Helios-Browser.st 28 KB

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