Helios-Browser.st 30 KB

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