Helios-Browser.st 32 KB

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