Helios-Browser.st 30 KB

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