Helios-Browser.st 30 KB

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