Helios-Browser.st 32 KB

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