Helios-Browser.st 30 KB

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