Helios-Browser.st 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393
  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 := HLSourceCodeWidget 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 ]
  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 selector ])
  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. selectItem: aPackage
  550. self model selectedPackage: aPackage
  551. ! !
  552. !HLPackagesListWidget methodsFor: 'initialization'!
  553. initializeItems
  554. ^ items := self model packages
  555. sort: [ :a :b | a name < b name ]
  556. ! !
  557. !HLPackagesListWidget methodsFor: 'reactions'!
  558. onPackageSelected: aPackage
  559. self selectedItem: aPackage.
  560. self hasFocus ifFalse: [
  561. self
  562. activateItem: aPackage;
  563. focus ]
  564. !
  565. onPackagesFocusRequested
  566. self focus
  567. ! !
  568. !HLPackagesListWidget methodsFor: 'rendering'!
  569. renderButtonsOn: html
  570. html div
  571. class: 'buttons';
  572. with: [
  573. html button
  574. class: 'btn';
  575. with: 'Commit';
  576. onClick: [ self commitPackage ] ]
  577. !
  578. renderItemLabel: aPackage on: html
  579. html with: aPackage name
  580. ! !
  581. HLBrowserListWidget subclass: #HLProtocolsListWidget
  582. instanceVariableNames: ''
  583. package: 'Helios-Browser'!
  584. !HLProtocolsListWidget methodsFor: 'accessing'!
  585. allProtocol
  586. ^ self model allProtocol
  587. !
  588. label
  589. ^ 'Protocols'
  590. !
  591. selectedItem
  592. ^ super selectedItem" ifNil: [ self allProtocol ]"
  593. ! !
  594. !HLProtocolsListWidget methodsFor: 'actions'!
  595. observeModel
  596. self model announcer
  597. on: HLClassSelected
  598. do: [ :ann | self onClassSelected: ann item ];
  599. on: HLShowInstanceToggled
  600. do: [ :ann | self onClassSelected: self model selectedClass ];
  601. on: HLProtocolSelected
  602. do: [ :ann | self onProtocolSelected: ann item ];
  603. on: HLProtocolsFocusRequested
  604. do: [ :ann | self onProtocolsFocusRequested ]
  605. !
  606. observeSystem
  607. self model systemAnnouncer
  608. on: ProtocolAdded
  609. do: [ :ann | self onProtocolAdded: ann protocol to: ann theClass ];
  610. on: ProtocolRemoved
  611. do: [ :ann | self onProtocolRemoved: ann protocol from: ann theClass ]
  612. !
  613. selectItem: aString
  614. self model selectedProtocol: aString
  615. ! !
  616. !HLProtocolsListWidget methodsFor: 'private'!
  617. setItemsForClass: aClass
  618. self items: (aClass
  619. ifNil: [ Array with: self allProtocol ]
  620. ifNotNil: [
  621. (Array with: self allProtocol)
  622. addAll: aClass protocols;
  623. yourself ])
  624. !
  625. setItemsForSelectedClass
  626. self setItemsForClass: self model selectedClass
  627. ! !
  628. !HLProtocolsListWidget methodsFor: 'reactions'!
  629. onClassSelected: aClass
  630. self selectedItem: nil.
  631. self setItemsForSelectedClass.
  632. self refresh
  633. !
  634. onProtocolAdded: aString to: aClass
  635. aClass = self model selectedClass ifFalse: [ ^ self ].
  636. self setItemsForSelectedClass.
  637. self refresh
  638. !
  639. onProtocolRemoved: aString from: aClass
  640. aClass = self model selectedClass ifFalse: [ ^ self ].
  641. self model selectedProtocol = aString
  642. ifTrue: [
  643. self
  644. selectedItem: nil;
  645. selectItem: nil ].
  646. self setItemsForSelectedClass.
  647. self refresh
  648. !
  649. onProtocolSelected: aString
  650. self selectedItem: aString.
  651. aString ifNil: [ ^ self ].
  652. self hasFocus ifFalse: [
  653. self
  654. activateItem: aString;
  655. focus ]
  656. !
  657. onProtocolsFocusRequested
  658. self focus
  659. ! !
  660. !HLProtocolsListWidget methodsFor: 'rendering'!
  661. renderContentOn: html
  662. self model showInstance
  663. ifFalse: [ html div
  664. class: 'class_side';
  665. with: [ super renderContentOn: html ] ]
  666. ifTrue: [ super renderContentOn: html ]
  667. ! !
  668. Object subclass: #HLBrowserModel
  669. instanceVariableNames: 'announcer environment selectedPackage selectedClass selectedProtocol selectedSelector showInstance showComment'
  670. package: 'Helios-Browser'!
  671. !HLBrowserModel methodsFor: 'accessing'!
  672. announcer
  673. ^ announcer ifNil: [ announcer := Announcer new ]
  674. !
  675. availableClassNames
  676. ^ self environment availableClassNames
  677. !
  678. availablePackageNames
  679. ^ self environment availablePackageNames
  680. !
  681. availablePackages
  682. ^ self environment availablePackageNames
  683. !
  684. availableProtocols
  685. ^ self environment availableProtocolsFor: self selectedClass
  686. !
  687. environment
  688. ^ environment ifNil: [ HLManager current environment ]
  689. !
  690. environment: anEnvironment
  691. environment := anEnvironment
  692. !
  693. handleUnkownVariableError: anError
  694. self announcer announce: (HLUnknownVariableErrorRaised new
  695. error: anError;
  696. yourself)
  697. !
  698. manager
  699. ^ HLManager current
  700. !
  701. packages
  702. ^ self environment packages
  703. !
  704. selectedClass
  705. ^ selectedClass
  706. !
  707. selectedClass: aClass
  708. selectedClass = aClass ifTrue: [
  709. aClass ifNil: [ ^ self ].
  710. self selectedProtocol: nil ].
  711. aClass
  712. ifNil: [ selectedClass := nil ]
  713. ifNotNil: [
  714. self showInstance
  715. ifTrue: [ selectedClass := aClass theNonMetaClass ]
  716. ifFalse: [ selectedClass := aClass theMetaClass ] ].
  717. self selectedProtocol: nil.
  718. self announcer announce: (HLClassSelected on: self selectedClass)
  719. !
  720. selectedMethod
  721. ^ self selectedClass ifNotNil: [
  722. self selectedClass methodDictionary
  723. at: selectedSelector
  724. ifAbsent: [ nil ] ]
  725. !
  726. selectedMethod: aCompiledMethod
  727. selectedSelector = aCompiledMethod ifTrue: [ ^ self ].
  728. aCompiledMethod
  729. ifNil: [ selectedSelector := nil ]
  730. ifNotNil: [
  731. selectedSelector = aCompiledMethod selector ifTrue: [ ^ self ].
  732. selectedSelector := aCompiledMethod selector ].
  733. self announcer announce: (HLMethodSelected on: aCompiledMethod)
  734. !
  735. selectedPackage
  736. ^ selectedPackage
  737. !
  738. selectedPackage: aPackage
  739. selectedPackage = aPackage ifTrue: [ ^ self ].
  740. selectedPackage := aPackage.
  741. self selectedClass: nil.
  742. self announcer announce: (HLPackageSelected on: aPackage)
  743. !
  744. selectedProtocol
  745. ^ selectedProtocol
  746. !
  747. selectedProtocol: aString
  748. selectedProtocol = aString ifTrue: [ ^ self ].
  749. selectedProtocol := aString.
  750. self selectedMethod: nil.
  751. self announcer announce: (HLProtocolSelected on: aString)
  752. !
  753. showComment
  754. ^ showComment ifNil: [ false ]
  755. !
  756. showComment: aBoolean
  757. showComment := aBoolean.
  758. self announcer announce: HLShowCommentToggled new
  759. !
  760. showInstance
  761. ^ showInstance ifNil: [ true ]
  762. !
  763. showInstance: aBoolean
  764. showInstance := aBoolean.
  765. showComment := false.
  766. self selectedClass ifNotNil: [
  767. self selectedClass: (aBoolean
  768. ifTrue: [self selectedClass theNonMetaClass ]
  769. ifFalse: [ self selectedClass theMetaClass ]) ].
  770. self announcer announce: HLShowInstanceToggled new
  771. !
  772. systemAnnouncer
  773. ^ self environment systemAnnouncer
  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. renameClassTo: aClassName
  845. self environment
  846. renameClass: self selectedClass theNonMetaClass
  847. to: aClassName
  848. ! !
  849. !HLBrowserModel methodsFor: 'compiling'!
  850. compileClassComment: aString
  851. self environment
  852. compileClassComment: aString
  853. for: self selectedClass
  854. !
  855. compileClassDefinition: aString
  856. self environment compileClassDefinition: aString
  857. !
  858. compileMethod: aString
  859. | method |
  860. self withCompileErrorHandling: [
  861. method := self environment
  862. compileMethod: aString
  863. for: self selectedClass
  864. protocol: self compilationProtocol.
  865. self selectedMethod: method ]
  866. ! !
  867. !HLBrowserModel methodsFor: 'defaults'!
  868. allProtocol
  869. ^ '-- all --'
  870. !
  871. unclassifiedProtocol
  872. ^ 'as yet unclassified'
  873. ! !
  874. !HLBrowserModel methodsFor: 'error handling'!
  875. handleCompileError: anError
  876. self announcer announce: (HLCompileErrorRaised new
  877. error: anError;
  878. yourself)
  879. !
  880. handleParseError: anError
  881. | split line column messageToInsert |
  882. split := anError messageText tokenize: ' : '.
  883. messageToInsert := split second.
  884. "21 = 'Parse error on line ' size + 1"
  885. split := split first copyFrom: 21 to: split first size.
  886. split := split tokenize: ' column '.
  887. line := split first.
  888. column := split second.
  889. self announcer announce: (HLParseErrorRaised new
  890. line: line asNumber;
  891. column: column asNumber;
  892. message: messageToInsert;
  893. error: anError;
  894. yourself)
  895. !
  896. withCompileErrorHandling: aBlock
  897. [
  898. [
  899. aBlock
  900. on: ParseError
  901. do: [:ex | self handleParseError: ex ]
  902. ]
  903. on: UnknownVariableError
  904. do: [ :ex | self handleUnkownVariableError: ex ]
  905. ]
  906. on: CompilerError
  907. do: [ :ex | self handleCompileError: ex ]
  908. ! !
  909. !HLBrowserModel methodsFor: 'private'!
  910. compilationProtocol
  911. | currentProtocol |
  912. currentProtocol := self selectedProtocol.
  913. currentProtocol ifNil: [ currentProtocol := self unclassifiedProtocol ].
  914. self selectedMethod ifNotNil: [ currentProtocol := self selectedMethod protocol ].
  915. ^ currentProtocol = self allProtocol
  916. ifTrue: [ self unclassifiedProtocol ]
  917. ifFalse: [ currentProtocol ]
  918. !
  919. withHelperLabelled: aString do: aBlock
  920. "TODO: doesn't belong here"
  921. (window jQuery: '#helper') remove.
  922. [ :html |
  923. html div
  924. id: 'helper';
  925. with: aString ] appendToJQuery: 'body' asJQuery.
  926. [
  927. aBlock value.
  928. (window jQuery: '#helper') remove
  929. ]
  930. valueWithTimeout: 10
  931. ! !
  932. !HLBrowserModel methodsFor: 'testing'!
  933. shouldCompileClassDefinition: aString
  934. ^ self selectedClass isNil or: [
  935. aString first asUppercase = aString first ]
  936. ! !
  937. !HLBrowserModel class methodsFor: 'actions'!
  938. on: anEnvironment
  939. ^ self new
  940. environment: anEnvironment;
  941. yourself
  942. ! !
  943. Object subclass: #HLClassCache
  944. instanceVariableNames: 'class selectorsCache overrideCache overriddenCache'
  945. package: 'Helios-Browser'!
  946. !HLClassCache methodsFor: 'accessing'!
  947. overriddenCache
  948. ^ overriddenCache ifNil: [ overriddenCache := HashedCollection new ]
  949. !
  950. overrideCache
  951. ^ overrideCache ifNil: [ overrideCache := HashedCollection new ]
  952. !
  953. selectorsCache
  954. ^ selectorsCache
  955. !
  956. selectorsCache: aCache
  957. selectorsCache := aCache
  958. !
  959. theClass
  960. ^ class
  961. !
  962. theClass: aClass
  963. class := aClass
  964. ! !
  965. !HLClassCache methodsFor: 'actions'!
  966. invalidateChildrenSelector: aSelector
  967. self theClass subclasses do: [ :each |
  968. (self selectorsCache cacheFor: each)
  969. removeSelector: aSelector;
  970. invalidateChildrenSelector: aSelector ]
  971. !
  972. invalidateParentSelector: aSelector
  973. self theClass superclass ifNotNil: [
  974. (self selectorsCache cacheFor: self theClass superclass)
  975. removeSelector: aSelector;
  976. invalidateParentSelector: aSelector ]
  977. !
  978. invalidateSelector: aSelector
  979. self
  980. invalidateParentSelector: aSelector;
  981. invalidateChildrenSelector: aSelector;
  982. removeSelector: aSelector
  983. ! !
  984. !HLClassCache methodsFor: 'private'!
  985. removeSelector: aSelector
  986. self overriddenCache
  987. removeKey: aSelector
  988. ifAbsent: [ ].
  989. self overrideCache
  990. removeKey: aSelector
  991. ifAbsent: [ ]
  992. ! !
  993. !HLClassCache methodsFor: 'testing'!
  994. isOverridden: aMethod
  995. ^ self overriddenCache
  996. at: aMethod selector
  997. ifAbsentPut: [ aMethod isOverridden ]
  998. !
  999. isOverride: aMethod
  1000. ^ self overrideCache
  1001. at: aMethod selector
  1002. ifAbsentPut: [ aMethod isOverride ]
  1003. ! !
  1004. !HLClassCache class methodsFor: 'instance creation'!
  1005. on: aClass selectorsCache: aSelectorsCache
  1006. ^ self new
  1007. theClass: aClass;
  1008. selectorsCache: aSelectorsCache;
  1009. yourself
  1010. ! !
  1011. Object subclass: #HLSelectorsCache
  1012. instanceVariableNames: 'classesCache'
  1013. package: 'Helios-Browser'!
  1014. !HLSelectorsCache methodsFor: 'accessing'!
  1015. cacheFor: aClass
  1016. aClass ifNil: [ ^ nil ].
  1017. ^ self classesCache
  1018. at: aClass name
  1019. ifAbsentPut: [ self newCacheFor: aClass ]
  1020. !
  1021. classesCache
  1022. ^ classesCache ifNil: [ classesCache := HashedCollection new ]
  1023. ! !
  1024. !HLSelectorsCache methodsFor: 'actions'!
  1025. observeSystem
  1026. SystemAnnouncer current
  1027. on: MethodAdded
  1028. do: [ :ann | self onMethodAdded: ann method ];
  1029. on: MethodRemoved
  1030. do: [ :ann | self onMethodRemoved: ann method ]
  1031. ! !
  1032. !HLSelectorsCache methodsFor: 'factory'!
  1033. newCacheFor: aClass
  1034. ^ HLClassCache
  1035. on: aClass
  1036. selectorsCache: self
  1037. ! !
  1038. !HLSelectorsCache methodsFor: 'initialization'!
  1039. initialize
  1040. super initialize.
  1041. self observeSystem
  1042. ! !
  1043. !HLSelectorsCache methodsFor: 'private'!
  1044. invalidateCacheFor: aMethod
  1045. (self cacheFor: aMethod methodClass)
  1046. invalidateSelector: aMethod selector
  1047. ! !
  1048. !HLSelectorsCache methodsFor: 'reactions'!
  1049. onMethodAdded: aMethod
  1050. self invalidateCacheFor: aMethod
  1051. !
  1052. onMethodRemoved: aMethod
  1053. self invalidateCacheFor: aMethod
  1054. ! !
  1055. !HLSelectorsCache methodsFor: 'testing'!
  1056. isOverridden: aMethod
  1057. ^ (self cacheFor: aMethod methodClass)
  1058. isOverridden: aMethod
  1059. !
  1060. isOverride: aMethod
  1061. ^ (self cacheFor: aMethod methodClass)
  1062. isOverride: aMethod
  1063. ! !
  1064. HLSelectorsCache class instanceVariableNames: 'current'!
  1065. !HLSelectorsCache class methodsFor: 'accessing'!
  1066. current
  1067. ^ current ifNil: [ current := super new ]
  1068. !
  1069. flush
  1070. current := nil
  1071. ! !
  1072. !HLSelectorsCache class methodsFor: 'instance creation'!
  1073. new
  1074. self shouldNotImplement
  1075. ! !