Helios-Browser.st 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557
  1. Smalltalk current createPackage: 'Helios-Browser'!
  2. HLWidget subclass: #HLBrowser
  3. instanceVariableNames: 'model packagesListWidget classesListWidget protocolsListWidget methodsListWidget sourceWidget bottomDiv'
  4. package: 'Helios-Browser'!
  5. !HLBrowser methodsFor: 'accessing'!
  6. environment
  7. ^ self model environment
  8. !
  9. model
  10. ^ model ifNil: [ model := HLBrowserModel new ]
  11. !
  12. model: aModel
  13. model := aModel
  14. ! !
  15. !HLBrowser methodsFor: 'actions'!
  16. focus
  17. ^ self packagesListWidget focus
  18. ! !
  19. !HLBrowser methodsFor: 'keybindings'!
  20. registerBindingsOn: aBindingGroup
  21. HLBrowserCommand
  22. registerConcreteClassesOn: aBindingGroup
  23. for: self model
  24. ! !
  25. !HLBrowser methodsFor: 'rendering'!
  26. renderContentOn: html
  27. html with: (HLContainer with: (HLHorizontalSplitter
  28. with: (HLVerticalSplitter
  29. with: (HLVerticalSplitter
  30. with: self packagesListWidget
  31. with: self classesListWidget)
  32. with: (HLVerticalSplitter
  33. with: self protocolsListWidget
  34. with: self methodsListWidget))
  35. with: self sourceWidget)).
  36. self packagesListWidget focus
  37. ! !
  38. !HLBrowser methodsFor: 'testing'!
  39. canHaveFocus
  40. ^ true
  41. ! !
  42. !HLBrowser methodsFor: 'widgets'!
  43. classesListWidget
  44. ^ classesListWidget ifNil: [
  45. classesListWidget := HLClassesListWidget on: self model.
  46. classesListWidget next: self protocolsListWidget ]
  47. !
  48. methodsListWidget
  49. ^ methodsListWidget ifNil: [
  50. methodsListWidget := HLMethodsListWidget on: self model.
  51. methodsListWidget next: self sourceWidget ]
  52. !
  53. packagesListWidget
  54. ^ packagesListWidget ifNil: [
  55. packagesListWidget := HLPackagesListWidget on: self model.
  56. packagesListWidget next: self classesListWidget ]
  57. !
  58. protocolsListWidget
  59. ^ protocolsListWidget ifNil: [
  60. protocolsListWidget := HLProtocolsListWidget on: self model.
  61. protocolsListWidget next: self methodsListWidget ]
  62. !
  63. sourceWidget
  64. ^ sourceWidget ifNil: [
  65. sourceWidget := HLBrowserBottomWidget new
  66. model: self model;
  67. yourself ]
  68. ! !
  69. HLBrowser class instanceVariableNames: 'nextId'!
  70. !HLBrowser class methodsFor: 'accessing'!
  71. nextId
  72. nextId ifNil: [ nextId := 0 ].
  73. ^ 'browser_', (nextId + 1) asString
  74. !
  75. tabLabel
  76. ^ 'Browser'
  77. !
  78. tabPriority
  79. ^ 0
  80. ! !
  81. !HLBrowser class methodsFor: 'testing'!
  82. canBeOpenAsTab
  83. ^ true
  84. ! !
  85. HLWidget subclass: #HLBrowserBottomWidget
  86. instanceVariableNames: 'model codeWidget documentationWidget selectedWidget'
  87. package: 'Helios-Browser'!
  88. !HLBrowserBottomWidget methodsFor: 'accessing'!
  89. codeWidget
  90. ^ codeWidget ifNil: [ codeWidget := HLBrowserCodeWidget new
  91. browserModel: self model;
  92. yourself ]
  93. !
  94. documentationWidget
  95. ^ documentationWidget ifNil: [ documentationWidget := HLDocumentationWidget new
  96. model: self model;
  97. yourself ]
  98. !
  99. model
  100. ^ model
  101. !
  102. model: aModel
  103. model := aModel.
  104. self observeModel
  105. !
  106. previous
  107. "For navigation"
  108. !
  109. previous: aWidget
  110. "For navigation"
  111. !
  112. selectedWidget
  113. ^ selectedWidget ifNil: [ selectedWidget := self codeWidget ]
  114. ! !
  115. !HLBrowserBottomWidget methodsFor: 'actions'!
  116. focus
  117. self selectedWidget focus
  118. !
  119. observeModel
  120. self model announcer
  121. on: HLShowInstanceToggled
  122. do: [ self onShowInstanceToggled ];
  123. on: HLShowCommentToggled
  124. do: [ self onShowCommentToggled ]
  125. !
  126. selectWidget: aWidget
  127. selectedWidget := aWidget.
  128. self refresh
  129. ! !
  130. !HLBrowserBottomWidget methodsFor: 'reactions'!
  131. onShowCommentToggled
  132. self selectWidget: self documentationWidget
  133. !
  134. onShowInstanceToggled
  135. self selectWidget: self codeWidget
  136. ! !
  137. !HLBrowserBottomWidget methodsFor: 'rendering'!
  138. renderContentOn: html
  139. html with: self selectedWidget
  140. ! !
  141. !HLBrowserBottomWidget methodsFor: 'testing'!
  142. canHaveFocus
  143. ^ true
  144. ! !
  145. HLNavigationListWidget subclass: #HLBrowserListWidget
  146. instanceVariableNames: 'model'
  147. package: 'Helios-Browser'!
  148. !HLBrowserListWidget methodsFor: 'accessing'!
  149. commandCategory
  150. ^ self label
  151. !
  152. label
  153. ^ 'List'
  154. !
  155. menuCommands
  156. "Answer a collection of commands to be put in the cog menu"
  157. ^ (HLBrowserCommand concreteClasses
  158. collect: [ :each | each for: self model ])
  159. select: [ :each |
  160. each category = self commandCategory and: [
  161. each isAction and: [ each isActive ] ] ]
  162. !
  163. model
  164. ^ model
  165. !
  166. model: aBrowserModel
  167. model := aBrowserModel.
  168. self
  169. observeSystem;
  170. observeModel
  171. !
  172. selectedItem: anItem
  173. "Selection changed, update the cog menu"
  174. super selectedItem: anItem.
  175. self updateMenu
  176. ! !
  177. !HLBrowserListWidget methodsFor: 'actions'!
  178. activateListItem: anItem
  179. self model withChangesDo: [ super activateListItem: anItem ]
  180. !
  181. observeModel
  182. !
  183. observeSystem
  184. ! !
  185. !HLBrowserListWidget methodsFor: 'rendering'!
  186. renderContentOn: html
  187. self renderHeadOn: html.
  188. super renderContentOn: html
  189. !
  190. renderHeadOn: html
  191. html div
  192. class: 'list-label';
  193. with: [
  194. html with: self label.
  195. self renderMenuOn: html ]
  196. !
  197. renderMenuOn: html
  198. | commands |
  199. commands := self menuCommands.
  200. commands isEmpty ifTrue: [ ^ self ].
  201. html div
  202. class: 'btn-group cog';
  203. with: [
  204. html a
  205. class: 'btn dropdown-toggle';
  206. at: 'data-toggle' put: 'dropdown';
  207. with: [ (html tag: 'i') class: 'icon-cog' ].
  208. html ul
  209. class: 'dropdown-menu pull-right';
  210. with: [
  211. self menuCommands do: [ :each |
  212. html li with: [ html a
  213. with: each menuLabel;
  214. onClick: [ self execute: each ] ] ] ] ]
  215. ! !
  216. !HLBrowserListWidget methodsFor: 'updating'!
  217. updateMenu
  218. (self wrapper asJQuery find: '.cog') remove.
  219. [ :html | self renderMenuOn: html ]
  220. appendToJQuery: (self wrapper asJQuery find: '.list-label')
  221. ! !
  222. !HLBrowserListWidget class methodsFor: 'instance creation'!
  223. on: aModel
  224. ^ self new
  225. model: aModel;
  226. yourself
  227. ! !
  228. HLBrowserListWidget subclass: #HLClassesListWidget
  229. instanceVariableNames: ''
  230. package: 'Helios-Browser'!
  231. !HLClassesListWidget methodsFor: 'accessing'!
  232. getChildrenOf: aClass
  233. ^ self items select: [ :each | each superclass = aClass ]
  234. !
  235. getRootClassesOf: aCollection
  236. ^ aCollection select: [ :each |
  237. (aCollection includes: each superclass) not ]
  238. !
  239. iconForItem: aClass
  240. ^ aClass theNonMetaClass comment isEmpty
  241. ifFalse: [ 'icon-none' ]
  242. ifTrue: [ 'icon-question-sign' ]
  243. !
  244. label
  245. ^ 'Classes'
  246. !
  247. showClass
  248. ^ self model showInstance not and: [
  249. self model showComment not ]
  250. !
  251. showComment
  252. ^ self model showComment
  253. !
  254. showInstance
  255. ^ self model showInstance and: [
  256. self model showComment not ]
  257. ! !
  258. !HLClassesListWidget methodsFor: 'actions'!
  259. focusMethodsListWidget
  260. self model announcer announce: HLMethodsListFocus new
  261. !
  262. focusProtocolsListWidget
  263. self model announcer announce: HLProtocolsListFocus new
  264. !
  265. observeModel
  266. self model announcer
  267. on: HLPackageSelected do: [ :ann | self onPackageSelected: ann item ];
  268. on: HLShowInstanceToggled do: [ :ann | self onShowInstanceToggled ];
  269. on: HLShowCommentToggled do: [ :ann | self onShowCommentToggled ];
  270. on: HLClassSelected do: [ :ann | self onClassSelected: ann item ];
  271. on: HLClassesFocusRequested do: [ :ann | self onClassesFocusRequested ]
  272. !
  273. observeSystem
  274. self model systemAnnouncer
  275. on: ClassAdded
  276. do: [ :ann | self onClassAdded: ann theClass ];
  277. on: ClassRemoved
  278. do: [ :ann | self onClassRemoved: ann theClass ];
  279. on: ClassMoved
  280. do: [ :ann | self onClassMoved: ann theClass from: ann oldPackage ];
  281. on: ClassRenamed
  282. do: [ :ann | self onClassRenamed: ann theClass ]
  283. !
  284. selectItem: aClass
  285. self model selectedClass: aClass
  286. !
  287. showComment: aBoolean
  288. self model showComment: aBoolean
  289. !
  290. showInstance: aBoolean
  291. self model showInstance: aBoolean
  292. ! !
  293. !HLClassesListWidget methodsFor: 'private'!
  294. setItemsForPackage: aPackage
  295. self items: (aPackage
  296. ifNil: [ #() ]
  297. ifNotNil: [ ((aPackage classes
  298. collect: [ :each | each theNonMetaClass ]) asSet asArray)
  299. sort: [:a :b | a name < b name ] ]).
  300. !
  301. setItemsForSelectedPackage
  302. self setItemsForPackage: self model selectedPackage
  303. ! !
  304. !HLClassesListWidget methodsFor: 'reactions'!
  305. onClassAdded: aClass
  306. (aClass package = self model selectedPackage or: [
  307. self items includes: aClass ]) ifFalse: [ ^ self ].
  308. self setItemsForSelectedPackage.
  309. self refresh
  310. !
  311. onClassMoved: aClass from: aPackage
  312. (aPackage = self model selectedPackage or: [
  313. aClass package = self model selectedPackage ])
  314. ifFalse: [ ^ self ].
  315. aPackage = self model selectedPackage ifTrue: [
  316. self
  317. selectedItem: nil;
  318. selectItem: nil ].
  319. self setItemsForSelectedPackage.
  320. self refresh
  321. !
  322. onClassRemoved: aClass
  323. aClass package = self model selectedPackage ifFalse: [ ^ self ].
  324. aClass = self model selectedClass ifTrue: [ self selectItem: nil ].
  325. self setItemsForSelectedPackage.
  326. self refresh
  327. !
  328. onClassRenamed: aClass
  329. aClass package = self model selectedPackage ifFalse: [ ^ self ].
  330. self setItemsForSelectedPackage.
  331. self refresh
  332. !
  333. onClassSelected: aClass
  334. | selectedClass |
  335. aClass ifNil: [ ^ self ].
  336. selectedClass := aClass theNonMetaClass.
  337. self selectedItem: selectedClass.
  338. self hasFocus ifFalse: [
  339. self
  340. activateItem: selectedClass;
  341. focus ]
  342. !
  343. onClassesFocusRequested
  344. self focus
  345. !
  346. onPackageSelected: aPackage
  347. self selectedItem: nil.
  348. self setItemsForSelectedPackage.
  349. self refresh
  350. !
  351. onShowCommentToggled
  352. self refresh
  353. !
  354. onShowInstanceToggled
  355. self refresh
  356. ! !
  357. !HLClassesListWidget methodsFor: 'rendering'!
  358. renderButtonsOn: html
  359. html div
  360. class: 'btn-group';
  361. with: [
  362. html button
  363. class: (String streamContents: [ :str |
  364. str nextPutAll: 'btn'.
  365. self showInstance ifTrue: [
  366. str nextPutAll: ' active' ] ]);
  367. with: 'Instance';
  368. onClick: [ self showInstance: true ].
  369. html button
  370. class: (String streamContents: [ :str |
  371. str nextPutAll: 'btn'.
  372. self showClass ifTrue: [
  373. str nextPutAll: ' active' ] ]);
  374. with: 'Class';
  375. onClick: [ self showInstance: false ].
  376. html button
  377. class: (String streamContents: [ :str |
  378. str nextPutAll: 'btn'.
  379. self showComment ifTrue: [
  380. str nextPutAll: ' active' ] ]);
  381. with: 'Doc';
  382. onClick: [ self showComment: true ] ]
  383. !
  384. renderItem: aClass level: anInteger on: html
  385. | li |
  386. li := html li.
  387. self registerMappingFrom: aClass to: li.
  388. li
  389. at: 'list-data' put: (self items indexOf: aClass);
  390. class: (self cssClassForItem: aClass);
  391. with: [
  392. html a
  393. with: [
  394. (html tag: 'i') class: (self iconForItem: aClass).
  395. self renderItemLabel: aClass level: anInteger on: html ];
  396. onClick: [
  397. self activateListItem: li asJQuery ] ].
  398. (self getChildrenOf: aClass) do: [ :each |
  399. self renderItem: each level: anInteger + 1 on: html ]
  400. !
  401. renderItem: aClass on: html
  402. super renderItem: aClass on: html.
  403. (self getChildrenOf: aClass) do: [ :each |
  404. self renderItem: each level: 1 on: html ]
  405. !
  406. renderItemLabel: aClass level: anInteger on: html
  407. html span asJQuery html: (String streamContents: [ :str |
  408. anInteger timesRepeat: [
  409. str nextPutAll: '&nbsp;&nbsp;&nbsp;&nbsp;'].
  410. str nextPutAll: aClass name ])
  411. !
  412. renderItemLabel: aClass on: html
  413. self renderItemLabel: aClass level: 0 on: html
  414. !
  415. renderListOn: html
  416. (self getRootClassesOf: self items)
  417. do: [ :each | self renderItem: each on: html ]
  418. ! !
  419. HLBrowserListWidget subclass: #HLMethodsListWidget
  420. instanceVariableNames: 'selectorsCache'
  421. package: 'Helios-Browser'!
  422. !HLMethodsListWidget methodsFor: 'accessing'!
  423. allProtocol
  424. ^ self model allProtocol
  425. !
  426. iconForItem: aSelector
  427. | override overriden method |
  428. method := self methodForSelector: aSelector.
  429. override := self isOverride: method.
  430. overriden := self isOverridden: method.
  431. ^ override
  432. ifTrue: [ overriden
  433. ifTrue: [ 'icon-resize-vertical' ]
  434. ifFalse: [ 'icon-arrow-up' ] ]
  435. ifFalse: [
  436. overriden
  437. ifTrue: [ 'icon-arrow-down' ]
  438. ifFalse: [ 'icon-none' ] ]
  439. !
  440. label
  441. ^ 'Methods'
  442. !
  443. methodForSelector: aSelector
  444. ^ self model selectedClass
  445. methodDictionary at: aSelector
  446. !
  447. methodsInProtocol: aString
  448. self model selectedClass ifNil: [ ^ #() ].
  449. ^ aString = self allProtocol
  450. ifTrue: [ self model selectedClass methods ]
  451. ifFalse: [ self model selectedClass methodsInProtocol: aString ]
  452. !
  453. overrideSelectors
  454. ^ self selectorsCache
  455. at: 'override'
  456. ifAbsentPut: [
  457. self model selectedClass allSuperclasses
  458. inject: Set new into: [ :acc :each | acc addAll: each selectors; yourself ] ]
  459. !
  460. overridenSelectors
  461. ^ self selectorsCache
  462. at: 'overriden'
  463. ifAbsentPut: [
  464. self model selectedClass allSubclasses
  465. inject: Set new into: [ :acc :each | acc addAll: each selectors; yourself ] ]
  466. !
  467. selectorsCache
  468. ^ self class selectorsCache
  469. !
  470. selectorsInProtocol: aString
  471. ^ ((self methodsInProtocol: aString)
  472. collect: [ :each | each selector ]) sorted
  473. ! !
  474. !HLMethodsListWidget methodsFor: 'actions'!
  475. observeModel
  476. self model announcer
  477. on: HLProtocolSelected
  478. do: [ :ann | self onProtocolSelected: ann item ];
  479. on: HLShowInstanceToggled
  480. do: [ :ann | self onProtocolSelected: nil ];
  481. on: HLMethodSelected
  482. do: [ :ann | self onMethodSelected: ann item ];
  483. on: HLMethodsFocusRequested
  484. do: [ :ann | self onMethodsFocusRequested ]
  485. !
  486. observeSystem
  487. self model systemAnnouncer
  488. on: ProtocolAdded
  489. do: [ :ann | self onProtocolAdded: ann theClass ];
  490. on: ProtocolRemoved
  491. do: [ :ann | self onProtocolRemoved: ann theClass ];
  492. on: MethodAdded
  493. do: [ :ann | self onMethodAdded: ann method ];
  494. on: MethodRemoved
  495. do: [ :ann | self onMethodRemoved: ann method ];
  496. on: MethodMoved
  497. do: [ :ann | self onMethodMoved: ann method ]
  498. !
  499. selectItem: aSelector
  500. aSelector ifNil: [ ^ self model selectedMethod: nil ].
  501. self model selectedMethod: (self methodForSelector: aSelector)
  502. ! !
  503. !HLMethodsListWidget methodsFor: 'private'!
  504. setItemsForProtocol: aString
  505. ^ self items: (aString
  506. ifNil: [ #() ]
  507. ifNotNil: [ self selectorsInProtocol: aString ])
  508. !
  509. setItemsForSelectedProtocol
  510. self setItemsForProtocol: self model selectedProtocol
  511. ! !
  512. !HLMethodsListWidget methodsFor: 'reactions'!
  513. onMethodAdded: aMethod
  514. self model selectedClass = aMethod methodClass ifFalse: [ ^ self ].
  515. self setItemsForSelectedProtocol.
  516. self refresh
  517. !
  518. onMethodMoved: aMethod
  519. self model selectedMethod = aMethod ifFalse: [ ^ self ].
  520. self model selectedProtocol = self model allProtocol ifFalse: [
  521. self
  522. selectedItem: nil;
  523. selectItem: nil;
  524. setItemsForSelectedProtocol;
  525. refresh ]
  526. !
  527. onMethodRemoved: aMethod
  528. self items detect: [ :each | each = aMethod selector ] ifNone: [ ^ self ].
  529. self selectedItem ifNotNil: [
  530. (aMethod methodClass = self model selectedClass and: [ aMethod selector = self selectedItem ])
  531. ifTrue: [
  532. self selectedItem: nil;
  533. selectItem: nil ] ].
  534. self setItemsForSelectedProtocol.
  535. self refresh
  536. !
  537. onMethodSelected: aMethod
  538. | selector |
  539. selector := aMethod isCompiledMethod
  540. ifTrue: [ aMethod selector ]
  541. ifFalse: [ nil ].
  542. self
  543. selectedItem: selector;
  544. activateItem: selector
  545. !
  546. onMethodsFocusRequested
  547. self focus
  548. !
  549. onProtocolAdded: aClass
  550. self model selectedClass = aClass ifFalse: [ ^ self ].
  551. self setItemsForSelectedProtocol.
  552. self refresh.
  553. self focus
  554. !
  555. onProtocolRemoved: aClass
  556. self model selectedClass = aClass ifFalse: [ ^ self ].
  557. self setItemsForSelectedProtocol.
  558. self refresh.
  559. self focus
  560. !
  561. onProtocolSelected: aString
  562. self selectedItem: nil.
  563. self setItemsForSelectedProtocol.
  564. self refresh
  565. ! !
  566. !HLMethodsListWidget methodsFor: 'rendering'!
  567. renderContentOn: html
  568. self model showInstance
  569. ifFalse: [ html div
  570. class: 'class_side';
  571. with: [ super renderContentOn: html ] ]
  572. ifTrue: [ super renderContentOn: html ]
  573. !
  574. renderItemLabel: aSelector on: html
  575. html with: aSelector
  576. ! !
  577. !HLMethodsListWidget methodsFor: 'testing'!
  578. isOverridden: aMethod
  579. ^ self selectorsCache isOverridden: aMethod
  580. !
  581. isOverride: aMethod
  582. ^ self selectorsCache isOverride: aMethod
  583. ! !
  584. HLMethodsListWidget class instanceVariableNames: 'selectorsCache'!
  585. !HLMethodsListWidget class methodsFor: 'accessing'!
  586. selectorsCache
  587. ^ HLSelectorsCache current
  588. ! !
  589. HLBrowserListWidget subclass: #HLPackagesListWidget
  590. instanceVariableNames: ''
  591. package: 'Helios-Browser'!
  592. !HLPackagesListWidget methodsFor: 'accessing'!
  593. items
  594. ^ items ifNil: [self initializeItems]
  595. !
  596. label
  597. ^ 'Packages'
  598. ! !
  599. !HLPackagesListWidget methodsFor: 'actions'!
  600. commitPackage
  601. self model commitPackage
  602. !
  603. focusClassesListWidget
  604. self model announcer announce: HLClassesListFocus new
  605. !
  606. observeModel
  607. self model announcer
  608. on: HLPackageSelected
  609. do: [ :ann | self onPackageSelected: ann item ];
  610. on: HLPackagesFocusRequested
  611. do: [ :ann | self onPackagesFocusRequested ]
  612. !
  613. observeSystem
  614. self model systemAnnouncer
  615. on: ClassAdded
  616. do: [ :ann | self onClassAdded: ann theClass ]
  617. !
  618. selectItem: aPackage
  619. self model selectedPackage: aPackage
  620. ! !
  621. !HLPackagesListWidget methodsFor: 'initialization'!
  622. initializeItems
  623. ^ items := self model packages
  624. sort: [ :a :b | a name < b name ]
  625. ! !
  626. !HLPackagesListWidget methodsFor: 'reactions'!
  627. onClassAdded: aClass
  628. "Amber doesn't have yet a global organizer for packages"
  629. (self items includes: aClass package) ifFalse: [
  630. self
  631. initializeItems;
  632. refresh ]
  633. !
  634. onPackageSelected: aPackage
  635. self selectedItem: aPackage.
  636. self hasFocus ifFalse: [
  637. self
  638. activateItem: aPackage;
  639. focus ]
  640. !
  641. onPackagesFocusRequested
  642. self focus
  643. ! !
  644. !HLPackagesListWidget methodsFor: 'rendering'!
  645. renderButtonsOn: html
  646. html div
  647. class: 'buttons';
  648. with: [
  649. html button
  650. class: 'btn';
  651. with: 'Commit';
  652. onClick: [ self commitPackage ] ]
  653. !
  654. renderItemLabel: aPackage on: html
  655. html with: aPackage name
  656. ! !
  657. HLBrowserListWidget subclass: #HLProtocolsListWidget
  658. instanceVariableNames: ''
  659. package: 'Helios-Browser'!
  660. !HLProtocolsListWidget methodsFor: 'accessing'!
  661. allProtocol
  662. ^ self model allProtocol
  663. !
  664. label
  665. ^ 'Protocols'
  666. !
  667. selectedItem
  668. ^ super selectedItem" ifNil: [ self allProtocol ]"
  669. ! !
  670. !HLProtocolsListWidget methodsFor: 'actions'!
  671. observeModel
  672. self model announcer
  673. on: HLClassSelected
  674. do: [ :ann | self onClassSelected: ann item ];
  675. on: HLShowInstanceToggled
  676. do: [ :ann | self onClassSelected: self model selectedClass ];
  677. on: HLProtocolSelected
  678. do: [ :ann | self onProtocolSelected: ann item ];
  679. on: HLProtocolsFocusRequested
  680. do: [ :ann | self onProtocolsFocusRequested ]
  681. !
  682. observeSystem
  683. self model systemAnnouncer
  684. on: ProtocolAdded
  685. do: [ :ann | self onProtocolAdded: ann protocol to: ann theClass ];
  686. on: ProtocolRemoved
  687. do: [ :ann | self onProtocolRemoved: ann protocol from: ann theClass ]
  688. !
  689. selectItem: aString
  690. self model selectedProtocol: aString
  691. ! !
  692. !HLProtocolsListWidget methodsFor: 'private'!
  693. setItemsForClass: aClass
  694. self items: (aClass
  695. ifNil: [ Array with: self allProtocol ]
  696. ifNotNil: [
  697. (Array with: self allProtocol)
  698. addAll: aClass protocols;
  699. yourself ])
  700. !
  701. setItemsForSelectedClass
  702. self setItemsForClass: self model selectedClass
  703. ! !
  704. !HLProtocolsListWidget methodsFor: 'reactions'!
  705. onClassSelected: aClass
  706. self selectedItem: nil.
  707. self setItemsForSelectedClass.
  708. self refresh
  709. !
  710. onProtocolAdded: aString to: aClass
  711. aClass = self model selectedClass ifFalse: [ ^ self ].
  712. self setItemsForSelectedClass.
  713. self refresh
  714. !
  715. onProtocolRemoved: aString from: aClass
  716. aClass = self model selectedClass ifFalse: [ ^ self ].
  717. self model selectedProtocol = aString
  718. ifTrue: [
  719. self
  720. selectedItem: nil;
  721. selectItem: nil ].
  722. self setItemsForSelectedClass.
  723. self refresh
  724. !
  725. onProtocolSelected: aString
  726. self selectedItem: aString.
  727. aString ifNil: [ ^ self ].
  728. self hasFocus ifFalse: [
  729. self
  730. activateItem: aString;
  731. focus ]
  732. !
  733. onProtocolsFocusRequested
  734. self focus
  735. ! !
  736. !HLProtocolsListWidget methodsFor: 'rendering'!
  737. renderContentOn: html
  738. self model showInstance
  739. ifFalse: [ html div
  740. class: 'class_side';
  741. with: [ super renderContentOn: html ] ]
  742. ifTrue: [ super renderContentOn: html ]
  743. ! !
  744. HLModel subclass: #HLBrowserModel
  745. instanceVariableNames: 'selectedPackage selectedClass selectedProtocol selectedSelector showInstance showComment'
  746. package: 'Helios-Browser'!
  747. !HLBrowserModel methodsFor: 'accessing'!
  748. allSelectors
  749. ^ self environment allSelectors
  750. !
  751. availableClassNames
  752. ^ self environment availableClassNames
  753. !
  754. availablePackageNames
  755. ^ self environment availablePackageNames
  756. !
  757. availablePackages
  758. ^ self environment availablePackageNames
  759. !
  760. availableProtocols
  761. ^ self environment availableProtocolsFor: self selectedClass
  762. !
  763. handleUnkownVariableError: anError
  764. self announcer announce: (HLUnknownVariableErrorRaised new
  765. error: anError;
  766. yourself)
  767. !
  768. packages
  769. ^ self environment packages
  770. !
  771. selectedClass
  772. ^ selectedClass
  773. !
  774. selectedClass: aClass
  775. (self selectedClass = aClass and: [ aClass isNil ])
  776. ifTrue: [ ^ self ].
  777. self withChangesDo: [
  778. selectedClass = aClass ifTrue: [
  779. self selectedProtocol: nil ].
  780. aClass
  781. ifNil: [ selectedClass := nil ]
  782. ifNotNil: [
  783. self showInstance
  784. ifTrue: [ selectedClass := aClass theNonMetaClass ]
  785. ifFalse: [ selectedClass := aClass theMetaClass ] ].
  786. self selectedProtocol: nil.
  787. self announcer announce: (HLClassSelected on: self selectedClass) ]
  788. !
  789. selectedMethod
  790. ^ self selectedClass ifNotNil: [
  791. self selectedClass methodDictionary
  792. at: selectedSelector
  793. ifAbsent: [ nil ] ]
  794. !
  795. selectedMethod: aCompiledMethod
  796. selectedSelector = aCompiledMethod ifTrue: [ ^ self ].
  797. self withChangesDo: [
  798. aCompiledMethod
  799. ifNil: [ selectedSelector := nil ]
  800. ifNotNil: [
  801. selectedSelector := aCompiledMethod selector ].
  802. self announcer announce: (HLMethodSelected on: aCompiledMethod) ]
  803. !
  804. selectedPackage
  805. ^ selectedPackage
  806. !
  807. selectedPackage: aPackage
  808. selectedPackage = aPackage ifTrue: [ ^ self ].
  809. self withChangesDo: [
  810. selectedPackage := aPackage.
  811. self selectedClass: nil.
  812. self announcer announce: (HLPackageSelected on: aPackage) ]
  813. !
  814. selectedProtocol
  815. ^ selectedProtocol
  816. !
  817. selectedProtocol: aString
  818. selectedProtocol = aString ifTrue: [ ^ self ].
  819. self withChangesDo: [
  820. selectedProtocol := aString.
  821. self selectedMethod: nil.
  822. self announcer announce: (HLProtocolSelected on: aString) ]
  823. !
  824. showComment
  825. ^ showComment ifNil: [ false ]
  826. !
  827. showComment: aBoolean
  828. self withChangesDo: [
  829. showComment := aBoolean.
  830. self announcer announce: HLShowCommentToggled new ]
  831. !
  832. showInstance
  833. ^ showInstance ifNil: [ true ]
  834. !
  835. showInstance: aBoolean
  836. self withChangesDo: [
  837. showInstance := aBoolean.
  838. showComment := false.
  839. self selectedClass ifNotNil: [
  840. self selectedClass: (aBoolean
  841. ifTrue: [self selectedClass theNonMetaClass ]
  842. ifFalse: [ self selectedClass theMetaClass ]) ].
  843. self announcer announce: HLShowInstanceToggled new ]
  844. ! !
  845. !HLBrowserModel methodsFor: 'actions'!
  846. addInstVarNamed: aString
  847. self environment addInstVarNamed: aString to: self selectedClass.
  848. self announcer announce: (HLInstVarAdded new
  849. theClass: self selectedClass;
  850. variableName: aString;
  851. yourself)
  852. !
  853. focusOnClasses
  854. self announcer announce: HLClassesFocusRequested new
  855. !
  856. focusOnMethods
  857. self announcer announce: HLMethodsFocusRequested new
  858. !
  859. focusOnPackages
  860. self announcer announce: HLPackagesFocusRequested new
  861. !
  862. focusOnProtocols
  863. self announcer announce: HLProtocolsFocusRequested new
  864. !
  865. focusOnSourceCode
  866. self announcer announce: HLSourceCodeFocusRequested new
  867. !
  868. save: aString
  869. self announcer announce: HLSourceCodeSaved new.
  870. (self shouldCompileClassDefinition: aString)
  871. ifTrue: [ self compileClassDefinition: aString ]
  872. ifFalse: [ self compileMethod: aString ]
  873. !
  874. saveSourceCode
  875. self announcer announce: HLSaveSourceCode new
  876. ! !
  877. !HLBrowserModel methodsFor: 'commands actions'!
  878. commitPackage
  879. self
  880. withHelperLabelled: 'Committing package ', self selectedPackage name, '...'
  881. do: [ self environment commitPackage: self selectedPackage ]
  882. !
  883. copyClassTo: aClassName
  884. self withChangesDo: [
  885. self environment
  886. copyClass: self selectedClass theNonMetaClass
  887. to: aClassName ]
  888. !
  889. moveClassToPackage: aPackageName
  890. self withChangesDo: [
  891. self environment
  892. moveClass: self selectedClass theNonMetaClass
  893. toPackage: aPackageName ]
  894. !
  895. moveMethodToClass: aClassName
  896. self withChangesDo: [
  897. self environment
  898. moveMethod: self selectedMethod
  899. toClass: aClassName ]
  900. !
  901. moveMethodToProtocol: aProtocol
  902. self withChangesDo: [
  903. self environment
  904. moveMethod: self selectedMethod
  905. toProtocol: aProtocol ]
  906. !
  907. openClassNamed: aString
  908. | class |
  909. self withChangesDo: [
  910. class := self environment classNamed: aString.
  911. self selectedPackage: class package.
  912. self selectedClass: class ]
  913. !
  914. removeClass
  915. self withChangesDo: [
  916. self manager
  917. confirm: 'Do you REALLY want to remove class ', self selectedClass name
  918. ifTrue: [ self environment removeClass: self selectedClass ] ]
  919. !
  920. removeMethod
  921. self withChangesDo: [
  922. self manager
  923. confirm: 'Do you REALLY want to remove method ', self selectedMethod methodClass name,' >> #', self selectedMethod selector
  924. ifTrue: [ self environment removeMethod: self selectedMethod ] ]
  925. !
  926. removeProtocol
  927. self withChangesDo: [
  928. self manager
  929. confirm: 'Do you REALLY want to remove protocol ', self selectedProtocol
  930. ifTrue: [ self environment
  931. removeProtocol: self selectedProtocol
  932. from: self selectedClass ] ]
  933. !
  934. renameClassTo: aClassName
  935. self withChangesDo: [
  936. self environment
  937. renameClass: self selectedClass theNonMetaClass
  938. to: aClassName ]
  939. !
  940. renameProtocolTo: aString
  941. self withChangesDo: [
  942. self environment
  943. renameProtocol: self selectedProtocol
  944. to: aString
  945. in: self selectedClass ]
  946. ! !
  947. !HLBrowserModel methodsFor: 'compiling'!
  948. compileClassComment: aString
  949. self environment
  950. compileClassComment: aString
  951. for: self selectedClass
  952. !
  953. compileClassDefinition: aString
  954. self environment compileClassDefinition: aString
  955. !
  956. compileMethod: aString
  957. | method |
  958. self withCompileErrorHandling: [
  959. method := self environment
  960. compileMethod: aString
  961. for: self selectedClass
  962. protocol: self compilationProtocol.
  963. self selectedMethod: method ]
  964. ! !
  965. !HLBrowserModel methodsFor: 'defaults'!
  966. allProtocol
  967. ^ '-- all --'
  968. !
  969. unclassifiedProtocol
  970. ^ 'as yet unclassified'
  971. ! !
  972. !HLBrowserModel methodsFor: 'error handling'!
  973. handleCompileError: anError
  974. self announcer announce: (HLCompileErrorRaised new
  975. error: anError;
  976. yourself)
  977. !
  978. handleParseError: anError
  979. | split line column messageToInsert |
  980. split := anError messageText tokenize: ' : '.
  981. messageToInsert := split second.
  982. "21 = 'Parse error on line ' size + 1"
  983. split := split first copyFrom: 21 to: split first size.
  984. split := split tokenize: ' column '.
  985. line := split first.
  986. column := split second.
  987. self announcer announce: (HLParseErrorRaised new
  988. line: line asNumber;
  989. column: column asNumber;
  990. message: messageToInsert;
  991. error: anError;
  992. yourself)
  993. !
  994. withChangesDo: aBlock
  995. [
  996. self announcer announce: HLAboutToChange new.
  997. aBlock value
  998. ]
  999. on: HLChangeForbidden
  1000. do: [ :ex | ]
  1001. !
  1002. withCompileErrorHandling: aBlock
  1003. [
  1004. [
  1005. aBlock
  1006. on: ParseError
  1007. do: [:ex | self handleParseError: ex ]
  1008. ]
  1009. on: UnknownVariableError
  1010. do: [ :ex | self handleUnkownVariableError: ex ]
  1011. ]
  1012. on: CompilerError
  1013. do: [ :ex | self handleCompileError: ex ]
  1014. ! !
  1015. !HLBrowserModel methodsFor: 'private'!
  1016. compilationProtocol
  1017. | currentProtocol |
  1018. currentProtocol := self selectedProtocol.
  1019. currentProtocol ifNil: [ currentProtocol := self unclassifiedProtocol ].
  1020. self selectedMethod ifNotNil: [ currentProtocol := self selectedMethod protocol ].
  1021. ^ currentProtocol = self allProtocol
  1022. ifTrue: [ self unclassifiedProtocol ]
  1023. ifFalse: [ currentProtocol ]
  1024. !
  1025. withHelperLabelled: aString do: aBlock
  1026. "TODO: doesn't belong here"
  1027. (window jQuery: '#helper') remove.
  1028. [ :html |
  1029. html div
  1030. id: 'helper';
  1031. with: aString ] appendToJQuery: 'body' asJQuery.
  1032. [
  1033. aBlock value.
  1034. (window jQuery: '#helper') remove
  1035. ]
  1036. valueWithTimeout: 10
  1037. ! !
  1038. !HLBrowserModel methodsFor: 'testing'!
  1039. shouldCompileClassDefinition: aString
  1040. ^ self selectedClass isNil or: [
  1041. aString first asUppercase = aString first ]
  1042. ! !
  1043. !HLBrowserModel class methodsFor: 'actions'!
  1044. on: anEnvironment
  1045. ^ self new
  1046. environment: anEnvironment;
  1047. yourself
  1048. ! !
  1049. Object subclass: #HLClassCache
  1050. instanceVariableNames: 'class selectorsCache overrideCache overriddenCache'
  1051. package: 'Helios-Browser'!
  1052. !HLClassCache methodsFor: 'accessing'!
  1053. overriddenCache
  1054. ^ overriddenCache ifNil: [ overriddenCache := HashedCollection new ]
  1055. !
  1056. overrideCache
  1057. ^ overrideCache ifNil: [ overrideCache := HashedCollection new ]
  1058. !
  1059. selectorsCache
  1060. ^ selectorsCache
  1061. !
  1062. selectorsCache: aCache
  1063. selectorsCache := aCache
  1064. !
  1065. theClass
  1066. ^ class
  1067. !
  1068. theClass: aClass
  1069. class := aClass
  1070. ! !
  1071. !HLClassCache methodsFor: 'actions'!
  1072. invalidateChildrenSelector: aSelector
  1073. self theClass subclasses do: [ :each |
  1074. (self selectorsCache cacheFor: each)
  1075. removeSelector: aSelector;
  1076. invalidateChildrenSelector: aSelector ]
  1077. !
  1078. invalidateParentSelector: aSelector
  1079. self theClass superclass ifNotNil: [
  1080. (self selectorsCache cacheFor: self theClass superclass)
  1081. removeSelector: aSelector;
  1082. invalidateParentSelector: aSelector ]
  1083. !
  1084. invalidateSelector: aSelector
  1085. self
  1086. invalidateParentSelector: aSelector;
  1087. invalidateChildrenSelector: aSelector;
  1088. removeSelector: aSelector
  1089. ! !
  1090. !HLClassCache methodsFor: 'private'!
  1091. removeSelector: aSelector
  1092. self overriddenCache
  1093. removeKey: aSelector
  1094. ifAbsent: [ ].
  1095. self overrideCache
  1096. removeKey: aSelector
  1097. ifAbsent: [ ]
  1098. ! !
  1099. !HLClassCache methodsFor: 'testing'!
  1100. isOverridden: aMethod
  1101. ^ self overriddenCache
  1102. at: aMethod selector
  1103. ifAbsentPut: [ aMethod isOverridden ]
  1104. !
  1105. isOverride: aMethod
  1106. ^ self overrideCache
  1107. at: aMethod selector
  1108. ifAbsentPut: [ aMethod isOverride ]
  1109. ! !
  1110. !HLClassCache class methodsFor: 'instance creation'!
  1111. on: aClass selectorsCache: aSelectorsCache
  1112. ^ self new
  1113. theClass: aClass;
  1114. selectorsCache: aSelectorsCache;
  1115. yourself
  1116. ! !
  1117. HLFocusableWidget subclass: #HLDocumentationWidget
  1118. instanceVariableNames: 'model'
  1119. package: 'Helios-Browser'!
  1120. !HLDocumentationWidget methodsFor: 'accessing'!
  1121. documentation
  1122. ^ self model selectedClass theNonMetaClass comment ifNil: [ self defaultDocumentation ]
  1123. !
  1124. model
  1125. ^ model
  1126. !
  1127. model: aModel
  1128. model := aModel
  1129. ! !
  1130. !HLDocumentationWidget methodsFor: 'defaults'!
  1131. defaultDocumentation
  1132. ^ '#No documentation available.
  1133. ##That''s bad. Seriously.'
  1134. ! !
  1135. !HLDocumentationWidget methodsFor: 'rendering'!
  1136. renderContentOn: html
  1137. (html div
  1138. class: 'markdown';
  1139. asJQuery) html: ((Showdown at: 'converter') new makeHtml: self documentation)
  1140. ! !
  1141. Object subclass: #HLSelectorsCache
  1142. instanceVariableNames: 'classesCache'
  1143. package: 'Helios-Browser'!
  1144. !HLSelectorsCache methodsFor: 'accessing'!
  1145. cacheFor: aClass
  1146. aClass ifNil: [ ^ nil ].
  1147. ^ self classesCache
  1148. at: aClass name
  1149. ifAbsentPut: [ self newCacheFor: aClass ]
  1150. !
  1151. classesCache
  1152. ^ classesCache ifNil: [ classesCache := HashedCollection new ]
  1153. ! !
  1154. !HLSelectorsCache methodsFor: 'actions'!
  1155. observeSystem
  1156. SystemAnnouncer current
  1157. on: MethodAdded
  1158. do: [ :ann | self onMethodAdded: ann method ];
  1159. on: MethodRemoved
  1160. do: [ :ann | self onMethodRemoved: ann method ]
  1161. ! !
  1162. !HLSelectorsCache methodsFor: 'factory'!
  1163. newCacheFor: aClass
  1164. ^ HLClassCache
  1165. on: aClass
  1166. selectorsCache: self
  1167. ! !
  1168. !HLSelectorsCache methodsFor: 'initialization'!
  1169. initialize
  1170. super initialize.
  1171. self observeSystem
  1172. ! !
  1173. !HLSelectorsCache methodsFor: 'private'!
  1174. invalidateCacheFor: aMethod
  1175. (self cacheFor: aMethod methodClass)
  1176. invalidateSelector: aMethod selector
  1177. ! !
  1178. !HLSelectorsCache methodsFor: 'reactions'!
  1179. onMethodAdded: aMethod
  1180. self invalidateCacheFor: aMethod
  1181. !
  1182. onMethodRemoved: aMethod
  1183. self invalidateCacheFor: aMethod
  1184. ! !
  1185. !HLSelectorsCache methodsFor: 'testing'!
  1186. isOverridden: aMethod
  1187. ^ (self cacheFor: aMethod methodClass)
  1188. isOverridden: aMethod
  1189. !
  1190. isOverride: aMethod
  1191. ^ (self cacheFor: aMethod methodClass)
  1192. isOverride: aMethod
  1193. ! !
  1194. HLSelectorsCache class instanceVariableNames: 'current'!
  1195. !HLSelectorsCache class methodsFor: 'accessing'!
  1196. current
  1197. ^ current ifNil: [ current := super new ]
  1198. !
  1199. flush
  1200. current := nil
  1201. ! !
  1202. !HLSelectorsCache class methodsFor: 'instance creation'!
  1203. new
  1204. self shouldNotImplement
  1205. ! !