Helios-Browser.st 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464
  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 := HLBrowserCodeWidget new
  66. browserModel: 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. HLNavigationListWidget subclass: #HLBrowserListWidget
  86. instanceVariableNames: 'model'
  87. package: 'Helios-Browser'!
  88. !HLBrowserListWidget methodsFor: 'accessing'!
  89. commandCategory
  90. ^ self label
  91. !
  92. label
  93. ^ 'List'
  94. !
  95. menuCommands
  96. "Answer a collection of commands to be put in the cog menu"
  97. ^ (HLBrowserCommand concreteClasses
  98. collect: [ :each | each for: self model ])
  99. select: [ :each |
  100. each category = self commandCategory and: [
  101. each isAction and: [ each isActive ] ] ]
  102. !
  103. model
  104. ^ model
  105. !
  106. model: aBrowserModel
  107. model := aBrowserModel.
  108. self
  109. observeSystem;
  110. observeModel
  111. !
  112. selectedItem: anItem
  113. "Selection changed, update the cog menu"
  114. super selectedItem: anItem.
  115. self updateMenu
  116. ! !
  117. !HLBrowserListWidget methodsFor: 'actions'!
  118. activateListItem: anItem
  119. self model withChangesDo: [ super activateListItem: anItem ]
  120. !
  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 or: [
  246. self items includes: aClass ]) ifFalse: [ ^ self ].
  247. self setItemsForSelectedPackage.
  248. self refresh
  249. !
  250. onClassMoved: aClass from: aPackage
  251. (aPackage = self model selectedPackage or: [
  252. aClass package = self model selectedPackage ])
  253. ifFalse: [ ^ self ].
  254. aPackage = self model selectedPackage ifTrue: [
  255. self
  256. selectedItem: nil;
  257. selectItem: nil ].
  258. self setItemsForSelectedPackage.
  259. self refresh
  260. !
  261. onClassRemoved: aClass
  262. aClass package = self model selectedPackage ifFalse: [ ^ self ].
  263. aClass = self model selectedClass ifTrue: [ self selectItem: nil ].
  264. self setItemsForSelectedPackage.
  265. self refresh
  266. !
  267. onClassRenamed: aClass
  268. aClass package = self model selectedPackage ifFalse: [ ^ self ].
  269. self setItemsForSelectedPackage.
  270. self refresh
  271. !
  272. onClassSelected: aClass
  273. | selectedClass |
  274. aClass ifNil: [ ^ self ].
  275. selectedClass := aClass theNonMetaClass.
  276. self selectedItem: selectedClass.
  277. self hasFocus ifFalse: [
  278. self
  279. activateItem: selectedClass;
  280. focus ]
  281. !
  282. onClassesFocusRequested
  283. self focus
  284. !
  285. onPackageSelected: aPackage
  286. self selectedItem: nil.
  287. self setItemsForSelectedPackage.
  288. self refresh
  289. !
  290. onShowInstanceToggled
  291. self refresh
  292. ! !
  293. !HLClassesListWidget methodsFor: 'rendering'!
  294. renderButtonsOn: html
  295. html div
  296. class: 'btn-group';
  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 ]) sorted
  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 ])
  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. observeSystem
  550. self model systemAnnouncer
  551. on: ClassAdded
  552. do: [ :ann | self onClassAdded: ann theClass ]
  553. !
  554. selectItem: aPackage
  555. self model selectedPackage: aPackage
  556. ! !
  557. !HLPackagesListWidget methodsFor: 'initialization'!
  558. initializeItems
  559. ^ items := self model packages
  560. sort: [ :a :b | a name < b name ]
  561. ! !
  562. !HLPackagesListWidget methodsFor: 'reactions'!
  563. onClassAdded: aClass
  564. "Amber doesn't have yet a global organizer for packages"
  565. (self items includes: aClass package) ifFalse: [
  566. self
  567. initializeItems;
  568. refresh ]
  569. !
  570. onPackageSelected: aPackage
  571. self selectedItem: aPackage.
  572. self hasFocus ifFalse: [
  573. self
  574. activateItem: aPackage;
  575. focus ]
  576. !
  577. onPackagesFocusRequested
  578. self focus
  579. ! !
  580. !HLPackagesListWidget methodsFor: 'rendering'!
  581. renderButtonsOn: html
  582. html div
  583. class: 'buttons';
  584. with: [
  585. html button
  586. class: 'btn';
  587. with: 'Commit';
  588. onClick: [ self commitPackage ] ]
  589. !
  590. renderItemLabel: aPackage on: html
  591. html with: aPackage name
  592. ! !
  593. HLBrowserListWidget subclass: #HLProtocolsListWidget
  594. instanceVariableNames: ''
  595. package: 'Helios-Browser'!
  596. !HLProtocolsListWidget methodsFor: 'accessing'!
  597. allProtocol
  598. ^ self model allProtocol
  599. !
  600. label
  601. ^ 'Protocols'
  602. !
  603. selectedItem
  604. ^ super selectedItem" ifNil: [ self allProtocol ]"
  605. ! !
  606. !HLProtocolsListWidget methodsFor: 'actions'!
  607. observeModel
  608. self model announcer
  609. on: HLClassSelected
  610. do: [ :ann | self onClassSelected: ann item ];
  611. on: HLShowInstanceToggled
  612. do: [ :ann | self onClassSelected: self model selectedClass ];
  613. on: HLProtocolSelected
  614. do: [ :ann | self onProtocolSelected: ann item ];
  615. on: HLProtocolsFocusRequested
  616. do: [ :ann | self onProtocolsFocusRequested ]
  617. !
  618. observeSystem
  619. self model systemAnnouncer
  620. on: ProtocolAdded
  621. do: [ :ann | self onProtocolAdded: ann protocol to: ann theClass ];
  622. on: ProtocolRemoved
  623. do: [ :ann | self onProtocolRemoved: ann protocol from: ann theClass ]
  624. !
  625. selectItem: aString
  626. self model selectedProtocol: aString
  627. ! !
  628. !HLProtocolsListWidget methodsFor: 'private'!
  629. setItemsForClass: aClass
  630. self items: (aClass
  631. ifNil: [ Array with: self allProtocol ]
  632. ifNotNil: [
  633. (Array with: self allProtocol)
  634. addAll: aClass protocols;
  635. yourself ])
  636. !
  637. setItemsForSelectedClass
  638. self setItemsForClass: self model selectedClass
  639. ! !
  640. !HLProtocolsListWidget methodsFor: 'reactions'!
  641. onClassSelected: aClass
  642. self selectedItem: nil.
  643. self setItemsForSelectedClass.
  644. self refresh
  645. !
  646. onProtocolAdded: aString to: aClass
  647. aClass = self model selectedClass ifFalse: [ ^ self ].
  648. self setItemsForSelectedClass.
  649. self refresh
  650. !
  651. onProtocolRemoved: aString from: aClass
  652. aClass = self model selectedClass ifFalse: [ ^ self ].
  653. self model selectedProtocol = aString
  654. ifTrue: [
  655. self
  656. selectedItem: nil;
  657. selectItem: nil ].
  658. self setItemsForSelectedClass.
  659. self refresh
  660. !
  661. onProtocolSelected: aString
  662. self selectedItem: aString.
  663. aString ifNil: [ ^ self ].
  664. self hasFocus ifFalse: [
  665. self
  666. activateItem: aString;
  667. focus ]
  668. !
  669. onProtocolsFocusRequested
  670. self focus
  671. ! !
  672. !HLProtocolsListWidget methodsFor: 'rendering'!
  673. renderContentOn: html
  674. self model showInstance
  675. ifFalse: [ html div
  676. class: 'class_side';
  677. with: [ super renderContentOn: html ] ]
  678. ifTrue: [ super renderContentOn: html ]
  679. ! !
  680. HLModel subclass: #HLBrowserModel
  681. instanceVariableNames: 'selectedPackage selectedClass selectedProtocol selectedSelector showInstance showComment'
  682. package: 'Helios-Browser'!
  683. !HLBrowserModel methodsFor: 'accessing'!
  684. allSelectors
  685. ^ self environment allSelectors
  686. !
  687. availableClassNames
  688. ^ self environment availableClassNames
  689. !
  690. availablePackageNames
  691. ^ self environment availablePackageNames
  692. !
  693. availablePackages
  694. ^ self environment availablePackageNames
  695. !
  696. availableProtocols
  697. ^ self environment availableProtocolsFor: self selectedClass
  698. !
  699. handleUnkownVariableError: anError
  700. self announcer announce: (HLUnknownVariableErrorRaised new
  701. error: anError;
  702. yourself)
  703. !
  704. packages
  705. ^ self environment packages
  706. !
  707. selectedClass
  708. ^ selectedClass
  709. !
  710. selectedClass: aClass
  711. aClass ifNil: [ ^ self ].
  712. self withChangesDo: [
  713. selectedClass = aClass ifTrue: [
  714. self selectedProtocol: nil ].
  715. aClass
  716. ifNil: [ selectedClass := nil ]
  717. ifNotNil: [
  718. self showInstance
  719. ifTrue: [ selectedClass := aClass theNonMetaClass ]
  720. ifFalse: [ selectedClass := aClass theMetaClass ] ].
  721. self selectedProtocol: nil.
  722. self announcer announce: (HLClassSelected on: self selectedClass) ]
  723. !
  724. selectedMethod
  725. ^ self selectedClass ifNotNil: [
  726. self selectedClass methodDictionary
  727. at: selectedSelector
  728. ifAbsent: [ nil ] ]
  729. !
  730. selectedMethod: aCompiledMethod
  731. selectedSelector = aCompiledMethod ifTrue: [ ^ self ].
  732. self withChangesDo: [
  733. aCompiledMethod
  734. ifNil: [ selectedSelector := nil ]
  735. ifNotNil: [
  736. selectedSelector := aCompiledMethod selector ].
  737. self announcer announce: (HLMethodSelected on: aCompiledMethod) ]
  738. !
  739. selectedPackage
  740. ^ selectedPackage
  741. !
  742. selectedPackage: aPackage
  743. selectedPackage = aPackage ifTrue: [ ^ self ].
  744. self withChangesDo: [
  745. selectedPackage := aPackage.
  746. self selectedClass: nil.
  747. self announcer announce: (HLPackageSelected on: aPackage) ]
  748. !
  749. selectedProtocol
  750. ^ selectedProtocol
  751. !
  752. selectedProtocol: aString
  753. selectedProtocol = aString ifTrue: [ ^ self ].
  754. self withChangesDo: [
  755. selectedProtocol := aString.
  756. self selectedMethod: nil.
  757. self announcer announce: (HLProtocolSelected on: aString) ]
  758. !
  759. showComment
  760. ^ showComment ifNil: [ false ]
  761. !
  762. showComment: aBoolean
  763. self withChangesDo: [
  764. showComment := aBoolean.
  765. self announcer announce: HLShowCommentToggled new ]
  766. !
  767. showInstance
  768. ^ showInstance ifNil: [ true ]
  769. !
  770. showInstance: aBoolean
  771. self withChangesDo: [
  772. showInstance := aBoolean.
  773. showComment := false.
  774. self selectedClass ifNotNil: [
  775. self selectedClass: (aBoolean
  776. ifTrue: [self selectedClass theNonMetaClass ]
  777. ifFalse: [ self selectedClass theMetaClass ]) ].
  778. self announcer announce: HLShowInstanceToggled new ]
  779. ! !
  780. !HLBrowserModel methodsFor: 'actions'!
  781. addInstVarNamed: aString
  782. self environment addInstVarNamed: aString to: self selectedClass.
  783. self announcer announce: (HLInstVarAdded new
  784. theClass: self selectedClass;
  785. variableName: aString;
  786. yourself)
  787. !
  788. focusOnClasses
  789. self announcer announce: HLClassesFocusRequested new
  790. !
  791. focusOnMethods
  792. self announcer announce: HLMethodsFocusRequested new
  793. !
  794. focusOnPackages
  795. self announcer announce: HLPackagesFocusRequested new
  796. !
  797. focusOnProtocols
  798. self announcer announce: HLProtocolsFocusRequested new
  799. !
  800. focusOnSourceCode
  801. self announcer announce: HLSourceCodeFocusRequested new
  802. !
  803. save: aString
  804. self announcer announce: HLSourceCodeSaved new.
  805. (self shouldCompileClassDefinition: aString)
  806. ifTrue: [ self compileClassDefinition: aString ]
  807. ifFalse: [ self compileMethod: aString ]
  808. !
  809. saveSourceCode
  810. self announcer announce: HLSaveSourceCode new
  811. ! !
  812. !HLBrowserModel methodsFor: 'commands actions'!
  813. commitPackage
  814. self
  815. withHelperLabelled: 'Committing package ', self selectedPackage name, '...'
  816. do: [ self environment commitPackage: self selectedPackage ]
  817. !
  818. copyClassTo: aClassName
  819. self withChangesDo: [
  820. self environment
  821. copyClass: self selectedClass theNonMetaClass
  822. to: aClassName ]
  823. !
  824. moveClassToPackage: aPackageName
  825. self withChangesDo: [
  826. self environment
  827. moveClass: self selectedClass theNonMetaClass
  828. toPackage: aPackageName ]
  829. !
  830. moveMethodToClass: aClassName
  831. self withChangesDo: [
  832. self environment
  833. moveMethod: self selectedMethod
  834. toClass: aClassName ]
  835. !
  836. moveMethodToProtocol: aProtocol
  837. self withChangesDo: [
  838. self environment
  839. moveMethod: self selectedMethod
  840. toProtocol: aProtocol ]
  841. !
  842. openClassNamed: aString
  843. | class |
  844. self withChangesDo: [
  845. class := self environment classNamed: aString.
  846. self selectedPackage: class package.
  847. self selectedClass: class ]
  848. !
  849. removeClass
  850. self withChangesDo: [
  851. (self manager confirm: 'Do you REALLY want to remove class ', self selectedClass name)
  852. ifTrue: [ self environment removeClass: self selectedClass ] ]
  853. !
  854. removeMethod
  855. self withChangesDo: [
  856. (self manager confirm: 'Do you REALLY want to remove method ', self selectedMethod methodClass name,' >> #', self selectedMethod selector)
  857. ifTrue: [ self environment removeMethod: self selectedMethod ] ]
  858. !
  859. removeProtocol
  860. self withChangesDo: [
  861. (self manager confirm: 'Do you REALLY want to remove protocol ', self selectedProtocol)
  862. ifTrue: [ self environment
  863. removeProtocol: self selectedProtocol
  864. from: self selectedClass ] ]
  865. !
  866. renameClassTo: aClassName
  867. self withChangesDo: [
  868. self environment
  869. renameClass: self selectedClass theNonMetaClass
  870. to: aClassName ]
  871. !
  872. renameProtocolTo: aString
  873. self withChangesDo: [
  874. self environment
  875. renameProtocol: self selectedProtocol
  876. to: aString
  877. in: self selectedClass ]
  878. ! !
  879. !HLBrowserModel methodsFor: 'compiling'!
  880. compileClassComment: aString
  881. self environment
  882. compileClassComment: aString
  883. for: self selectedClass
  884. !
  885. compileClassDefinition: aString
  886. self environment compileClassDefinition: aString
  887. !
  888. compileMethod: aString
  889. | method |
  890. self withCompileErrorHandling: [
  891. method := self environment
  892. compileMethod: aString
  893. for: self selectedClass
  894. protocol: self compilationProtocol.
  895. self selectedMethod: method ]
  896. ! !
  897. !HLBrowserModel methodsFor: 'defaults'!
  898. allProtocol
  899. ^ '-- all --'
  900. !
  901. unclassifiedProtocol
  902. ^ 'as yet unclassified'
  903. ! !
  904. !HLBrowserModel methodsFor: 'error handling'!
  905. handleCompileError: anError
  906. self announcer announce: (HLCompileErrorRaised new
  907. error: anError;
  908. yourself)
  909. !
  910. handleParseError: anError
  911. | split line column messageToInsert |
  912. split := anError messageText tokenize: ' : '.
  913. messageToInsert := split second.
  914. "21 = 'Parse error on line ' size + 1"
  915. split := split first copyFrom: 21 to: split first size.
  916. split := split tokenize: ' column '.
  917. line := split first.
  918. column := split second.
  919. self announcer announce: (HLParseErrorRaised new
  920. line: line asNumber;
  921. column: column asNumber;
  922. message: messageToInsert;
  923. error: anError;
  924. yourself)
  925. !
  926. withChangesDo: aBlock
  927. [
  928. self announcer announce: HLAboutToChange new.
  929. aBlock value
  930. ]
  931. on: HLChangeForbidden
  932. do: [ :ex | ]
  933. !
  934. withCompileErrorHandling: aBlock
  935. [
  936. [
  937. aBlock
  938. on: ParseError
  939. do: [:ex | self handleParseError: ex ]
  940. ]
  941. on: UnknownVariableError
  942. do: [ :ex | self handleUnkownVariableError: ex ]
  943. ]
  944. on: CompilerError
  945. do: [ :ex | self handleCompileError: ex ]
  946. ! !
  947. !HLBrowserModel methodsFor: 'private'!
  948. compilationProtocol
  949. | currentProtocol |
  950. currentProtocol := self selectedProtocol.
  951. currentProtocol ifNil: [ currentProtocol := self unclassifiedProtocol ].
  952. self selectedMethod ifNotNil: [ currentProtocol := self selectedMethod protocol ].
  953. ^ currentProtocol = self allProtocol
  954. ifTrue: [ self unclassifiedProtocol ]
  955. ifFalse: [ currentProtocol ]
  956. !
  957. withHelperLabelled: aString do: aBlock
  958. "TODO: doesn't belong here"
  959. (window jQuery: '#helper') remove.
  960. [ :html |
  961. html div
  962. id: 'helper';
  963. with: aString ] appendToJQuery: 'body' asJQuery.
  964. [
  965. aBlock value.
  966. (window jQuery: '#helper') remove
  967. ]
  968. valueWithTimeout: 10
  969. ! !
  970. !HLBrowserModel methodsFor: 'testing'!
  971. shouldCompileClassDefinition: aString
  972. ^ self selectedClass isNil or: [
  973. aString first asUppercase = aString first ]
  974. ! !
  975. !HLBrowserModel class methodsFor: 'actions'!
  976. on: anEnvironment
  977. ^ self new
  978. environment: anEnvironment;
  979. yourself
  980. ! !
  981. Object subclass: #HLClassCache
  982. instanceVariableNames: 'class selectorsCache overrideCache overriddenCache'
  983. package: 'Helios-Browser'!
  984. !HLClassCache methodsFor: 'accessing'!
  985. overriddenCache
  986. ^ overriddenCache ifNil: [ overriddenCache := HashedCollection new ]
  987. !
  988. overrideCache
  989. ^ overrideCache ifNil: [ overrideCache := HashedCollection new ]
  990. !
  991. selectorsCache
  992. ^ selectorsCache
  993. !
  994. selectorsCache: aCache
  995. selectorsCache := aCache
  996. !
  997. theClass
  998. ^ class
  999. !
  1000. theClass: aClass
  1001. class := aClass
  1002. ! !
  1003. !HLClassCache methodsFor: 'actions'!
  1004. invalidateChildrenSelector: aSelector
  1005. self theClass subclasses do: [ :each |
  1006. (self selectorsCache cacheFor: each)
  1007. removeSelector: aSelector;
  1008. invalidateChildrenSelector: aSelector ]
  1009. !
  1010. invalidateParentSelector: aSelector
  1011. self theClass superclass ifNotNil: [
  1012. (self selectorsCache cacheFor: self theClass superclass)
  1013. removeSelector: aSelector;
  1014. invalidateParentSelector: aSelector ]
  1015. !
  1016. invalidateSelector: aSelector
  1017. self
  1018. invalidateParentSelector: aSelector;
  1019. invalidateChildrenSelector: aSelector;
  1020. removeSelector: aSelector
  1021. ! !
  1022. !HLClassCache methodsFor: 'private'!
  1023. removeSelector: aSelector
  1024. self overriddenCache
  1025. removeKey: aSelector
  1026. ifAbsent: [ ].
  1027. self overrideCache
  1028. removeKey: aSelector
  1029. ifAbsent: [ ]
  1030. ! !
  1031. !HLClassCache methodsFor: 'testing'!
  1032. isOverridden: aMethod
  1033. ^ self overriddenCache
  1034. at: aMethod selector
  1035. ifAbsentPut: [ aMethod isOverridden ]
  1036. !
  1037. isOverride: aMethod
  1038. ^ self overrideCache
  1039. at: aMethod selector
  1040. ifAbsentPut: [ aMethod isOverride ]
  1041. ! !
  1042. !HLClassCache class methodsFor: 'instance creation'!
  1043. on: aClass selectorsCache: aSelectorsCache
  1044. ^ self new
  1045. theClass: aClass;
  1046. selectorsCache: aSelectorsCache;
  1047. yourself
  1048. ! !
  1049. HLFocusableWidget subclass: #HLDocumentationWidget
  1050. instanceVariableNames: 'documentation'
  1051. package: 'Helios-Browser'!
  1052. !HLDocumentationWidget methodsFor: 'accessing'!
  1053. documentation
  1054. ^ documentation ifNil: [ self defaultDocumentation ]
  1055. !
  1056. documentation: aString
  1057. documentation := aString
  1058. ! !
  1059. !HLDocumentationWidget methodsFor: 'defaults'!
  1060. defaultDocumentation
  1061. ^ '#No documentation available.
  1062. ##That''s bad. Seriously.'
  1063. ! !
  1064. !HLDocumentationWidget methodsFor: 'rendering'!
  1065. renderContentOn: html
  1066. html div
  1067. class: 'markdown';
  1068. with: (Showdown makeHtml: self documentation)
  1069. ! !
  1070. Object subclass: #HLSelectorsCache
  1071. instanceVariableNames: 'classesCache'
  1072. package: 'Helios-Browser'!
  1073. !HLSelectorsCache methodsFor: 'accessing'!
  1074. cacheFor: aClass
  1075. aClass ifNil: [ ^ nil ].
  1076. ^ self classesCache
  1077. at: aClass name
  1078. ifAbsentPut: [ self newCacheFor: aClass ]
  1079. !
  1080. classesCache
  1081. ^ classesCache ifNil: [ classesCache := HashedCollection new ]
  1082. ! !
  1083. !HLSelectorsCache methodsFor: 'actions'!
  1084. observeSystem
  1085. SystemAnnouncer current
  1086. on: MethodAdded
  1087. do: [ :ann | self onMethodAdded: ann method ];
  1088. on: MethodRemoved
  1089. do: [ :ann | self onMethodRemoved: ann method ]
  1090. ! !
  1091. !HLSelectorsCache methodsFor: 'factory'!
  1092. newCacheFor: aClass
  1093. ^ HLClassCache
  1094. on: aClass
  1095. selectorsCache: self
  1096. ! !
  1097. !HLSelectorsCache methodsFor: 'initialization'!
  1098. initialize
  1099. super initialize.
  1100. self observeSystem
  1101. ! !
  1102. !HLSelectorsCache methodsFor: 'private'!
  1103. invalidateCacheFor: aMethod
  1104. (self cacheFor: aMethod methodClass)
  1105. invalidateSelector: aMethod selector
  1106. ! !
  1107. !HLSelectorsCache methodsFor: 'reactions'!
  1108. onMethodAdded: aMethod
  1109. self invalidateCacheFor: aMethod
  1110. !
  1111. onMethodRemoved: aMethod
  1112. self invalidateCacheFor: aMethod
  1113. ! !
  1114. !HLSelectorsCache methodsFor: 'testing'!
  1115. isOverridden: aMethod
  1116. ^ (self cacheFor: aMethod methodClass)
  1117. isOverridden: aMethod
  1118. !
  1119. isOverride: aMethod
  1120. ^ (self cacheFor: aMethod methodClass)
  1121. isOverride: aMethod
  1122. ! !
  1123. HLSelectorsCache class instanceVariableNames: 'current'!
  1124. !HLSelectorsCache class methodsFor: 'accessing'!
  1125. current
  1126. ^ current ifNil: [ current := super new ]
  1127. !
  1128. flush
  1129. current := nil
  1130. ! !
  1131. !HLSelectorsCache class methodsFor: 'instance creation'!
  1132. new
  1133. self shouldNotImplement
  1134. ! !