IDE.st 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379
  1. Smalltalk current createPackage: 'IDE' properties: #{}!
  2. Widget subclass: #ClassesList
  3. instanceVariableNames: 'browser ul nodes'
  4. package: 'IDE'!
  5. !ClassesList methodsFor: 'accessing'!
  6. browser
  7. ^browser
  8. !
  9. browser: aBrowser
  10. browser := aBrowser
  11. !
  12. category
  13. ^self browser selectedPackage
  14. !
  15. getNodes
  16. | classes children others |
  17. classes := self browser classes.
  18. children := #().
  19. others := #().
  20. classes do: [:each |
  21. (classes includes: each superclass)
  22. ifFalse: [children add: each]
  23. ifTrue: [others add: each]].
  24. ^children collect: [:each |
  25. ClassesListNode on: each browser: self browser classes: others level: 0]
  26. !
  27. nodes
  28. nodes ifNil: [nodes := self getNodes].
  29. ^nodes
  30. !
  31. resetNodes
  32. nodes := nil
  33. ! !
  34. !ClassesList methodsFor: 'rendering'!
  35. renderOn: html
  36. ul := html ul
  37. class: 'jt_column browser classes';
  38. yourself.
  39. self updateNodes
  40. !
  41. updateNodes
  42. ul contents: [:html |
  43. self nodes do: [:each |
  44. each renderOn: html]]
  45. ! !
  46. !ClassesList class methodsFor: 'instance creation'!
  47. on: aBrowser
  48. ^self new
  49. browser: aBrowser;
  50. yourself
  51. ! !
  52. Widget subclass: #ClassesListNode
  53. instanceVariableNames: 'browser theClass level nodes'
  54. package: 'IDE'!
  55. !ClassesListNode methodsFor: ''!
  56. renderOn: html
  57. | li cssClass |
  58. cssClass := ''.
  59. li := html li
  60. onClick: [self browser selectClass: self theClass].
  61. li asJQuery html: self label.
  62. self browser selectedClass = self theClass ifTrue: [
  63. cssClass := cssClass, ' selected'].
  64. self theClass comment isEmpty ifFalse: [
  65. cssClass := cssClass, ' commented'].
  66. li class: cssClass.
  67. self nodes do: [:each |
  68. each renderOn: html]
  69. ! !
  70. !ClassesListNode methodsFor: 'accessing'!
  71. browser
  72. ^browser
  73. !
  74. browser: aBrowser
  75. browser := aBrowser
  76. !
  77. getNodesFrom: aCollection
  78. | children others |
  79. children := #().
  80. others := #().
  81. aCollection do: [:each |
  82. (each superclass = self theClass)
  83. ifTrue: [children add: each]
  84. ifFalse: [others add: each]].
  85. nodes:= children collect: [:each |
  86. ClassesListNode on: each browser: self browser classes: others level: self level + 1]
  87. !
  88. label
  89. | str |
  90. str := String new writeStream.
  91. self level timesRepeat: [
  92. str nextPutAll: '    '].
  93. str nextPutAll: self theClass name.
  94. ^str contents
  95. !
  96. level
  97. ^level
  98. !
  99. level: anInteger
  100. level := anInteger
  101. !
  102. nodes
  103. ^nodes
  104. !
  105. theClass
  106. ^theClass
  107. !
  108. theClass: aClass
  109. theClass := aClass
  110. ! !
  111. !ClassesListNode methodsFor: 'visiting'!
  112. traverseClassesWith: aCollection
  113. "sort classes alphabetically Issue #143"
  114. aCollection add: self theClass.
  115. (self nodes sorted: [:a :b | a theClass name <= b theClass name ]) do: [:aNode |
  116. aNode traverseClassesWith: aCollection ].
  117. ! !
  118. !ClassesListNode class methodsFor: 'instance creation'!
  119. on: aClass browser: aBrowser classes: aCollection level: anInteger
  120. ^self new
  121. theClass: aClass;
  122. browser: aBrowser;
  123. level: anInteger;
  124. getNodesFrom: aCollection;
  125. yourself
  126. ! !
  127. ErrorHandler subclass: #DebugErrorHandler
  128. instanceVariableNames: ''
  129. package: 'IDE'!
  130. !DebugErrorHandler methodsFor: 'error handling'!
  131. handleError: anError
  132. [Debugger new
  133. error: anError;
  134. open] on: Error do: [:error |
  135. ErrorHandler new handleError: error]
  136. ! !
  137. !DebugErrorHandler class methodsFor: 'initialization'!
  138. initialize
  139. self register
  140. ! !
  141. Widget subclass: #SourceArea
  142. instanceVariableNames: 'editor div receiver onDoIt'
  143. package: 'IDE'!
  144. !SourceArea methodsFor: 'accessing'!
  145. currentLine
  146. ^editor getLine: (editor getCursor line)
  147. !
  148. currentLineOrSelection
  149. ^editor somethingSelected
  150. ifFalse: [self currentLine]
  151. ifTrue: [self selection]
  152. !
  153. editor
  154. ^editor
  155. !
  156. onDoIt
  157. ^onDoIt
  158. !
  159. onDoIt: aBlock
  160. onDoIt := aBlock
  161. !
  162. receiver
  163. ^receiver ifNil: [DoIt new]
  164. !
  165. receiver: anObject
  166. receiver := anObject
  167. !
  168. selection
  169. ^editor getSelection
  170. !
  171. selectionEnd
  172. ^textarea element selectionEnd
  173. !
  174. selectionEnd: anInteger
  175. textarea element selectionEnd: anInteger
  176. !
  177. selectionStart
  178. ^textarea element selectionStart
  179. !
  180. selectionStart: anInteger
  181. textarea element selectionStart: anInteger
  182. !
  183. setEditorOn: aTextarea
  184. <self['@editor'] = CodeMirror.fromTextArea(aTextarea, {
  185. theme: 'jtalk',
  186. lineNumbers: true,
  187. enterMode: 'flat',
  188. matchBrackets: true,
  189. electricChars: false
  190. })>
  191. !
  192. val
  193. ^editor getValue
  194. !
  195. val: aString
  196. editor setValue: aString
  197. ! !
  198. !SourceArea methodsFor: 'actions'!
  199. clear
  200. self val: ''
  201. !
  202. doIt
  203. | result |
  204. result := self eval: self currentLineOrSelection.
  205. self onDoIt ifNotNil: [self onDoIt value].
  206. ^result
  207. !
  208. eval: aString
  209. | compiler |
  210. compiler := Compiler new.
  211. [compiler parseExpression: aString] on: Error do: [:ex |
  212. ^window alert: ex messageText].
  213. ^(compiler load: 'doIt ^[', aString, '] value' forClass: DoIt) fn applyTo: self receiver arguments: #()
  214. !
  215. fileIn
  216. Importer new import: self currentLineOrSelection readStream
  217. !
  218. handleKeyDown: anEvent
  219. <if(anEvent.ctrlKey) {
  220. if(anEvent.keyCode === 80) { //ctrl+p
  221. self._printIt();
  222. anEvent.preventDefault();
  223. return false;
  224. }
  225. if(anEvent.keyCode === 68) { //ctrl+d
  226. self._doIt();
  227. anEvent.preventDefault();
  228. return false;
  229. }
  230. if(anEvent.keyCode === 73) { //ctrl+i
  231. self._inspectIt();
  232. anEvent.preventDefault();
  233. return false;
  234. }
  235. }>
  236. !
  237. inspectIt
  238. self doIt inspect
  239. !
  240. print: aString
  241. | start stop |
  242. start := HashedCollection new.
  243. stop := HashedCollection new.
  244. start at: 'line' put: (editor getCursor: false) line.
  245. start at: 'ch' put: (editor getCursor: false) ch.
  246. stop at: 'line' put: (start at: 'line').
  247. stop at: 'ch' put: ((start at: 'ch') + aString size + 2).
  248. editor replaceSelection: (editor getSelection, ' ', aString, ' ').
  249. editor setCursor: (editor getCursor: true).
  250. editor setSelection: stop end: start
  251. !
  252. printIt
  253. self print: self doIt printString
  254. ! !
  255. !SourceArea methodsFor: 'events'!
  256. onKeyDown: aBlock
  257. div onKeyDown: aBlock
  258. !
  259. onKeyUp: aBlock
  260. div onKeyUp: aBlock
  261. ! !
  262. !SourceArea methodsFor: 'rendering'!
  263. renderOn: html
  264. | textarea |
  265. div := html div class: 'source'.
  266. div with: [textarea := html textarea].
  267. self setEditorOn: textarea element.
  268. div onKeyDown: [:e | self handleKeyDown: e]
  269. ! !
  270. Widget subclass: #TabManager
  271. instanceVariableNames: 'selectedTab tabs opened ul input'
  272. package: 'IDE'!
  273. !TabManager methodsFor: 'accessing'!
  274. labelFor: aWidget
  275. | label maxSize |
  276. maxSize := 15.
  277. label := aWidget label copyFrom: 0 to: (aWidget label size min: maxSize).
  278. aWidget label size > maxSize ifTrue: [
  279. label := label, '...'].
  280. ^label
  281. !
  282. tabs
  283. ^tabs ifNil: [tabs := Array new]
  284. ! !
  285. !TabManager methodsFor: 'actions'!
  286. close
  287. opened ifTrue: [
  288. '#jtalk' asJQuery hide.
  289. ul asJQuery hide.
  290. selectedTab hide.
  291. self removeBodyMargin.
  292. 'body' asJQuery removeClass: 'jtalkBody'.
  293. opened := false]
  294. !
  295. closeTab: aWidget
  296. self removeTab: aWidget.
  297. self selectTab: self tabs last.
  298. aWidget remove.
  299. self update
  300. !
  301. newBrowserTab
  302. Browser open
  303. !
  304. onResize: aBlock
  305. <jQuery('#jtalk').resizable({
  306. handles: 'n',
  307. resize: aBlock,
  308. minHeight: 230
  309. })>
  310. !
  311. onWindowResize: aBlock
  312. <jQuery(window).resize(aBlock)>
  313. !
  314. open
  315. opened ifFalse: [
  316. 'body' asJQuery addClass: 'jtalkBody'.
  317. '#jtalk' asJQuery show.
  318. ul asJQuery show.
  319. self updateBodyMargin.
  320. selectedTab show.
  321. opened := true]
  322. !
  323. removeBodyMargin
  324. self setBodyMargin: 0
  325. !
  326. search: aString
  327. | searchedClass |
  328. searchedClass := Smalltalk current at: aString.
  329. searchedClass isClass
  330. ifTrue: [Browser openOn: searchedClass]
  331. ifFalse: [ReferencesBrowser search: aString]
  332. !
  333. selectTab: aWidget
  334. self open.
  335. selectedTab := aWidget.
  336. self tabs do: [:each |
  337. each hide].
  338. aWidget show.
  339. self update
  340. !
  341. setBodyMargin: anInteger
  342. '.jtalkBody' asJQuery css: 'margin-bottom' put: anInteger asString, 'px'
  343. !
  344. updateBodyMargin
  345. self setBodyMargin: '#jtalk' asJQuery height
  346. !
  347. updatePosition
  348. <jQuery('#jtalk').css('top', '').css('bottom', '0px')>
  349. ! !
  350. !TabManager methodsFor: 'adding/Removing'!
  351. addTab: aWidget
  352. self tabs add: aWidget.
  353. aWidget appendToJQuery: '#jtalk' asJQuery.
  354. aWidget hide
  355. !
  356. removeTab: aWidget
  357. self tabs remove: aWidget.
  358. self update
  359. ! !
  360. !TabManager methodsFor: 'initialization'!
  361. initialize
  362. super initialize.
  363. opened := true.
  364. [:html | html div id: 'jtalk'] appendToJQuery: 'body' asJQuery.
  365. 'body' asJQuery
  366. addClass: 'jtalkBody'.
  367. self appendToJQuery: '#jtalk' asJQuery.
  368. self
  369. addTab: IDETranscript current;
  370. addTab: Workspace new;
  371. addTab: TestRunner new.
  372. self selectTab: self tabs last.
  373. self
  374. onResize: [self updateBodyMargin; updatePosition];
  375. onWindowResize: [self updatePosition]
  376. ! !
  377. !TabManager methodsFor: 'rendering'!
  378. renderOn: html
  379. html div id: 'logo'.
  380. self renderToolbarOn: html.
  381. ul := html ul
  382. id: 'jtalkTabs';
  383. yourself.
  384. self renderTabs
  385. !
  386. renderTabFor: aWidget on: html
  387. | li |
  388. li := html li.
  389. selectedTab = aWidget ifTrue: [
  390. li class: 'selected'].
  391. li with: [
  392. html span class: 'ltab'.
  393. html span
  394. class: 'mtab';
  395. with: [
  396. aWidget canBeClosed ifTrue: [
  397. html span
  398. class: 'close';
  399. with: 'x';
  400. onClick: [self closeTab: aWidget]].
  401. html span with: (self labelFor: aWidget)].
  402. html span class: 'rtab'];
  403. onClick: [self selectTab: aWidget]
  404. !
  405. renderTabs
  406. ul contents: [:html |
  407. self tabs do: [:each |
  408. self renderTabFor: each on: html].
  409. html li
  410. class: 'newtab';
  411. with: [
  412. html span class: 'ltab'.
  413. html span class: 'mtab'; with: ' + '.
  414. html span class: 'rtab'];
  415. onClick: [self newBrowserTab]]
  416. !
  417. renderToolbarOn: html
  418. html div
  419. id: 'jt_toolbar';
  420. with: [
  421. input := html input
  422. class: 'implementors';
  423. yourself.
  424. input onKeyPress: [:event |
  425. event keyCode = 13 ifTrue: [
  426. self search: input asJQuery val]].
  427. html div id: 'jt_close'; onClick: [self close]]
  428. ! !
  429. !TabManager methodsFor: 'updating'!
  430. update
  431. self renderTabs
  432. ! !
  433. TabManager class instanceVariableNames: 'current'!
  434. !TabManager class methodsFor: 'instance creation'!
  435. current
  436. ^current ifNil: [current := super new]
  437. !
  438. new
  439. self shouldNotImplement
  440. ! !
  441. Widget subclass: #TabWidget
  442. instanceVariableNames: 'div'
  443. package: 'IDE'!
  444. !TabWidget methodsFor: 'accessing'!
  445. label
  446. self subclassResponsibility
  447. ! !
  448. !TabWidget methodsFor: 'actions'!
  449. close
  450. TabManager current closeTab: self
  451. !
  452. hide
  453. div asJQuery hide
  454. !
  455. open
  456. TabManager current addTab: self.
  457. TabManager current selectTab: self
  458. !
  459. remove
  460. div asJQuery remove
  461. !
  462. show
  463. div asJQuery show
  464. ! !
  465. !TabWidget methodsFor: 'rendering'!
  466. renderBoxOn: html
  467. !
  468. renderButtonsOn: html
  469. !
  470. renderOn: html
  471. div := html div
  472. class: 'jtalkTool';
  473. yourself.
  474. self renderTab
  475. !
  476. renderTab
  477. div contents: [:html |
  478. html div
  479. class: 'jt_box';
  480. with: [self renderBoxOn: html].
  481. html div
  482. class: 'jt_buttons';
  483. with: [self renderButtonsOn: html]]
  484. !
  485. update
  486. self renderTab
  487. ! !
  488. !TabWidget methodsFor: 'testing'!
  489. canBeClosed
  490. ^false
  491. ! !
  492. !TabWidget class methodsFor: 'instance creation'!
  493. open
  494. ^self new open
  495. ! !
  496. TabWidget subclass: #Browser
  497. instanceVariableNames: 'selectedPackage selectedClass selectedProtocol selectedMethod packagesList classesList protocolsList methodsList sourceArea tabsList selectedTab saveButton classButtons methodButtons unsavedChanges'
  498. package: 'IDE'!
  499. !Browser methodsFor: 'accessing'!
  500. classCommentSource
  501. ^selectedClass comment
  502. !
  503. classDeclarationSource
  504. | stream |
  505. stream := '' writeStream.
  506. selectedClass ifNil: [^self classDeclarationTemplate].
  507. stream
  508. nextPutAll: selectedClass superclass asString;
  509. nextPutAll: ' subclass: #';
  510. nextPutAll: selectedClass name;
  511. nextPutAll: String lf, String tab;
  512. nextPutAll: 'instanceVariableNames: '''.
  513. selectedClass instanceVariableNames
  514. do: [:each | stream nextPutAll: each]
  515. separatedBy: [stream nextPutAll: ' '].
  516. stream
  517. nextPutAll: '''', String lf, String tab;
  518. nextPutAll: 'package: ''';
  519. nextPutAll: selectedClass category;
  520. nextPutAll: ''''.
  521. ^stream contents
  522. !
  523. classDeclarationTemplate
  524. ^'Object subclass: #NameOfSubclass
  525. instanceVariableNames: ''''
  526. package: ''', self selectedPackage, ''''
  527. !
  528. classes
  529. ^((Smalltalk current classes
  530. select: [:each | each category = selectedPackage])
  531. sort: [:a :b | a name < b name]) asSet
  532. !
  533. declarationSource
  534. ^selectedTab = #instance
  535. ifTrue: [self classDeclarationSource]
  536. ifFalse: [self metaclassDeclarationSource]
  537. !
  538. dummyMethodSource
  539. ^'messageSelectorAndArgumentNames
  540. "comment stating purpose of message"
  541. | temporary variable names |
  542. statements'
  543. !
  544. label
  545. ^selectedClass
  546. ifNil: ['Browser (nil)']
  547. ifNotNil: ['Browser: ', selectedClass name]
  548. !
  549. metaclassDeclarationSource
  550. | stream |
  551. stream := '' writeStream.
  552. selectedClass ifNotNil: [
  553. stream
  554. nextPutAll: selectedClass asString;
  555. nextPutAll: ' class ';
  556. nextPutAll: 'instanceVariableNames: '''.
  557. selectedClass class instanceVariableNames
  558. do: [:each | stream nextPutAll: each]
  559. separatedBy: [stream nextPutAll: ' '].
  560. stream nextPutAll: ''''].
  561. ^stream contents
  562. !
  563. methodSource
  564. ^selectedMethod
  565. ifNil: [self dummyMethodSource]
  566. ifNotNil: [selectedMethod source]
  567. !
  568. methods
  569. | klass |
  570. selectedTab = #comment ifTrue: [^#()].
  571. selectedClass ifNotNil: [
  572. klass := selectedTab = #instance
  573. ifTrue: [selectedClass]
  574. ifFalse: [selectedClass class]].
  575. ^(selectedProtocol
  576. ifNil: [
  577. klass
  578. ifNil: [#()]
  579. ifNotNil: [klass methodDictionary values]]
  580. ifNotNil: [
  581. klass methodDictionary values select: [:each |
  582. each category = selectedProtocol]]) sort: [:a :b | a selector < b selector]
  583. !
  584. packages
  585. | packages |
  586. packages := Array new.
  587. Smalltalk current classes do: [:each |
  588. (packages includes: each category) ifFalse: [
  589. packages add: each category]].
  590. ^packages sort
  591. !
  592. protocols
  593. | klass |
  594. selectedClass ifNotNil: [
  595. selectedTab = #comment ifTrue: [^#()].
  596. klass := selectedTab = #instance
  597. ifTrue: [selectedClass]
  598. ifFalse: [selectedClass class].
  599. klass methodDictionary isEmpty ifTrue: [
  600. ^Array with: 'not yet classified'].
  601. ^klass protocols].
  602. ^Array new
  603. !
  604. selectedClass
  605. ^selectedClass
  606. !
  607. selectedPackage
  608. ^selectedPackage
  609. !
  610. source
  611. selectedTab = #comment ifFalse: [
  612. ^(selectedProtocol notNil or: [selectedMethod notNil])
  613. ifFalse: [self declarationSource]
  614. ifTrue: [self methodSource]].
  615. ^selectedClass
  616. ifNil: ['']
  617. ifNotNil: [self classCommentSource]
  618. ! !
  619. !Browser methodsFor: 'actions'!
  620. addInstanceVariableNamed: aString toClass: aClass
  621. ClassBuilder new
  622. addSubclassOf: aClass superclass
  623. named: aClass name
  624. instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)
  625. package: aClass package name
  626. !
  627. addNewClass
  628. | className |
  629. className := window prompt: 'New class'.
  630. (className notNil and: [className notEmpty]) ifTrue: [
  631. Object subclass: className instanceVariableNames: '' package: self selectedPackage.
  632. self
  633. resetClassesList;
  634. updateClassesList.
  635. self selectClass: (Smalltalk current at: className)]
  636. !
  637. addNewProtocol
  638. | newProtocol |
  639. newProtocol := window prompt: 'New method protocol'.
  640. (newProtocol notNil and: [newProtocol notEmpty]) ifTrue: [
  641. selectedMethod category: newProtocol.
  642. self setMethodProtocol: newProtocol]
  643. !
  644. cancelChanges
  645. ^unsavedChanges
  646. ifTrue: [window confirm: 'Cancel changes?']
  647. ifFalse: [true]
  648. !
  649. commitPackage
  650. selectedPackage ifNotNil: [ |package|
  651. package := Package named: selectedPackage.
  652. { Exporter -> (package commitPathJs, '/', selectedPackage, '.js').
  653. StrippedExporter -> (package commitPathJs, '/', selectedPackage, '.deploy.js').
  654. ChunkExporter -> (package commitPathSt, '/', selectedPackage, '.st') }
  655. do: [:commitStrategy| |fileContents|
  656. fileContents := (commitStrategy key new exportPackage: selectedPackage).
  657. self ajaxPutAt: commitStrategy value data: fileContents]
  658. ]
  659. !
  660. compile
  661. self disableSaveButton.
  662. selectedTab = #comment
  663. ifTrue: [
  664. selectedClass ifNotNil: [
  665. self compileClassComment]]
  666. ifFalse: [
  667. (selectedProtocol notNil or: [selectedMethod notNil])
  668. ifFalse: [self compileDefinition]
  669. ifTrue: [self compileMethodDefinition]]
  670. !
  671. compileClassComment
  672. selectedClass comment: sourceArea val
  673. !
  674. compileDefinition
  675. | newClass |
  676. newClass := Compiler new loadExpression: sourceArea val.
  677. self
  678. resetClassesList;
  679. updateCategoriesList;
  680. updateClassesList.
  681. self selectClass: newClass
  682. !
  683. compileMethodDefinition
  684. selectedTab = #instance
  685. ifTrue: [self compileMethodDefinitionFor: selectedClass]
  686. ifFalse: [self compileMethodDefinitionFor: selectedClass class]
  687. !
  688. compileMethodDefinitionFor: aClass
  689. | compiler method source node |
  690. source := sourceArea val.
  691. selectedProtocol ifNil: [selectedProtocol := selectedMethod category].
  692. compiler := Compiler new.
  693. compiler source: source.
  694. node := compiler parse: source.
  695. node isParseFailure ifTrue: [
  696. ^window alert: 'PARSE ERROR: ', node reason, ', position: ', node position asString].
  697. compiler currentClass: aClass.
  698. method := compiler eval: (compiler compileNode: node).
  699. method category: selectedProtocol.
  700. compiler unknownVariables do: [:each |
  701. "Do not try to redeclare javascript's objects"
  702. (window at: each) ifNil: [
  703. (window confirm: 'Declare ''', each, ''' as instance variable?') ifTrue: [
  704. self addInstanceVariableNamed: each toClass: aClass.
  705. ^self compileMethodDefinitionFor: aClass]]].
  706. aClass addCompiledMethod: method.
  707. compiler setupClass: aClass.
  708. self updateMethodsList.
  709. self selectMethod: method
  710. !
  711. copyClass
  712. | className |
  713. className := window prompt: 'Copy class'.
  714. (className notNil and: [className notEmpty]) ifTrue: [
  715. ClassBuilder new copyClass: self selectedClass named: className.
  716. self
  717. resetClassesList;
  718. updateClassesList.
  719. self selectClass: (Smalltalk current at: className)]
  720. !
  721. disableSaveButton
  722. saveButton ifNotNil: [
  723. saveButton at: 'disabled' put: true].
  724. unsavedChanges := false
  725. !
  726. handleSourceAreaKeyDown: anEvent
  727. <if(anEvent.ctrlKey) {
  728. if(anEvent.keyCode === 83) { //ctrl+s
  729. self._compile();
  730. anEvent.preventDefault();
  731. return false;
  732. }
  733. }
  734. >
  735. !
  736. hideClassButtons
  737. classButtons asJQuery hide
  738. !
  739. hideMethodButtons
  740. methodButtons asJQuery hide
  741. !
  742. removeClass
  743. (window confirm: 'Do you really want to remove ', selectedClass name, '?')
  744. ifTrue: [
  745. Smalltalk current removeClass: selectedClass.
  746. self resetClassesList.
  747. self selectClass: nil]
  748. !
  749. removeMethod
  750. self cancelChanges ifTrue: [
  751. (window confirm: 'Do you really want to remove #', selectedMethod selector, '?')
  752. ifTrue: [
  753. selectedTab = #instance
  754. ifTrue: [selectedClass removeCompiledMethod: selectedMethod]
  755. ifFalse: [selectedClass class removeCompiledMethod: selectedMethod].
  756. self selectMethod: nil]]
  757. !
  758. removePackage
  759. (window confirm: 'Do you really want to remove the whole package ', selectedPackage, ' with all its classes?')
  760. ifTrue: [
  761. Smalltalk current removePackage: selectedPackage.
  762. self updateCategoriesList]
  763. !
  764. renameClass
  765. | newName |
  766. newName := window prompt: 'Rename class ', selectedClass name.
  767. (newName notNil and: [newName notEmpty]) ifTrue: [
  768. selectedClass rename: newName.
  769. self
  770. updateClassesList;
  771. updateSourceAndButtons]
  772. !
  773. renamePackage
  774. | newName |
  775. newName := window prompt: 'Rename package ', selectedPackage.
  776. newName ifNotNil: [
  777. newName notEmpty ifTrue: [
  778. Smalltalk current renamePackage: selectedPackage to: newName.
  779. self updateCategoriesList]]
  780. !
  781. search: aString
  782. self cancelChanges ifTrue: [| searchedClass |
  783. searchedClass := Smalltalk current at: aString.
  784. searchedClass isClass
  785. ifTrue: [self class openOn: searchedClass]
  786. ifFalse: [self searchReferencesOf: aString]]
  787. !
  788. searchClassReferences
  789. ReferencesBrowser search: selectedClass name
  790. !
  791. searchReferencesOf: aString
  792. ReferencesBrowser search: aString
  793. !
  794. selectCategory: aCategory
  795. self cancelChanges ifTrue: [
  796. selectedPackage := aCategory.
  797. selectedClass := selectedProtocol := selectedMethod := nil.
  798. self resetClassesList.
  799. self
  800. updateCategoriesList;
  801. updateClassesList;
  802. updateProtocolsList;
  803. updateMethodsList;
  804. updateSourceAndButtons]
  805. !
  806. selectClass: aClass
  807. self cancelChanges ifTrue: [
  808. selectedClass := aClass.
  809. selectedProtocol := selectedMethod := nil.
  810. self
  811. updateClassesList;
  812. updateProtocolsList;
  813. updateMethodsList;
  814. updateSourceAndButtons]
  815. !
  816. selectMethod: aMethod
  817. self cancelChanges ifTrue: [
  818. selectedMethod := aMethod.
  819. self
  820. updateProtocolsList;
  821. updateMethodsList;
  822. updateSourceAndButtons]
  823. !
  824. selectProtocol: aString
  825. self cancelChanges ifTrue: [
  826. selectedProtocol := aString.
  827. selectedMethod := nil.
  828. self
  829. updateProtocolsList;
  830. updateMethodsList;
  831. updateSourceAndButtons]
  832. !
  833. selectTab: aString
  834. self cancelChanges ifTrue: [
  835. selectedTab := aString.
  836. self selectProtocol: nil.
  837. self updateTabsList]
  838. !
  839. setMethodProtocol: aString
  840. self cancelChanges ifTrue: [
  841. (self protocols includes: aString)
  842. ifFalse: [self addNewProtocol]
  843. ifTrue: [
  844. selectedMethod category: aString.
  845. selectedProtocol := aString.
  846. selectedMethod := selectedMethod.
  847. self
  848. updateProtocolsList;
  849. updateMethodsList;
  850. updateSourceAndButtons]]
  851. !
  852. showClassButtons
  853. classButtons asJQuery show
  854. !
  855. showMethodButtons
  856. methodButtons asJQuery show
  857. ! !
  858. !Browser methodsFor: 'initialization'!
  859. initialize
  860. super initialize.
  861. selectedTab := #instance.
  862. selectedPackage := self packages first.
  863. unsavedChanges := false
  864. ! !
  865. !Browser methodsFor: 'network'!
  866. ajaxPutAt: anURL data: aString
  867. jQuery
  868. ajax: anURL options: #{ 'type' -> 'PUT'.
  869. 'data' -> aString.
  870. 'contentType' -> 'text/plain;charset=UTF-8'.
  871. 'error' -> [window alert: 'PUT request failed at: ', anURL] }
  872. ! !
  873. !Browser methodsFor: 'rendering'!
  874. renderBottomPanelOn: html
  875. html div
  876. class: 'jt_sourceCode';
  877. with: [
  878. sourceArea := SourceArea new.
  879. sourceArea renderOn: html.
  880. sourceArea onKeyDown: [:e |
  881. self handleSourceAreaKeyDown: e].
  882. sourceArea onKeyUp: [self updateStatus]]
  883. !
  884. renderBoxOn: html
  885. self
  886. renderTopPanelOn: html;
  887. renderTabsOn: html;
  888. renderBottomPanelOn: html
  889. !
  890. renderButtonsOn: html
  891. saveButton := html button.
  892. saveButton
  893. with: 'Save';
  894. onClick: [self compile].
  895. methodButtons := html span.
  896. classButtons := html span.
  897. html div
  898. class: 'right';
  899. with: [
  900. html button
  901. with: 'DoIt';
  902. onClick: [sourceArea doIt].
  903. html button
  904. with: 'PrintIt';
  905. onClick: [sourceArea printIt].
  906. html button with: 'InspectIt';
  907. onClick: [sourceArea inspectIt]].
  908. self updateSourceAndButtons
  909. !
  910. renderTabsOn: html
  911. tabsList := html ul class: 'jt_tabs jt_browser'.
  912. self updateTabsList.
  913. !
  914. renderTopPanelOn: html
  915. html div
  916. class: 'top';
  917. with: [
  918. packagesList := html ul class: 'jt_column browser packages'.
  919. html div class: 'jt_packagesButtons'; with: [
  920. html button
  921. title: 'Commit classes in this package to disk';
  922. onClick: [self commitPackage];
  923. with: 'Commit'.
  924. html button
  925. title: 'Rename package';
  926. onClick: [self renamePackage];
  927. with: 'Rename'.
  928. html button
  929. title: 'Remove this package from the system';
  930. onClick: [self removePackage];
  931. with: 'Remove'].
  932. classesList := ClassesList on: self.
  933. classesList renderOn: html.
  934. protocolsList := html ul class: 'jt_column browser protocols'.
  935. methodsList := html ul class: 'jt_column browser methods'.
  936. self
  937. updateCategoriesList;
  938. updateClassesList;
  939. updateProtocolsList;
  940. updateMethodsList.
  941. html div class: 'jt_clear']
  942. ! !
  943. !Browser methodsFor: 'testing'!
  944. canBeClosed
  945. ^true
  946. ! !
  947. !Browser methodsFor: 'updating'!
  948. resetClassesList
  949. classesList resetNodes
  950. !
  951. updateCategoriesList
  952. packagesList contents: [:html |
  953. self packages do: [:each || li label |
  954. each isEmpty
  955. ifTrue: [label := 'Unclassified']
  956. ifFalse: [label := each].
  957. li := html li.
  958. selectedPackage = each ifTrue: [
  959. li class: 'selected'].
  960. li
  961. with: label;
  962. onClick: [self selectCategory: each]]]
  963. !
  964. updateClassesList
  965. TabManager current update.
  966. classesList updateNodes
  967. !
  968. updateMethodsList
  969. methodsList contents: [:html |
  970. self methods do: [:each || li |
  971. li := html li.
  972. selectedMethod = each ifTrue: [
  973. li class: 'selected'].
  974. li
  975. with: each selector;
  976. onClick: [self selectMethod: each]]]
  977. !
  978. updateProtocolsList
  979. protocolsList contents: [:html |
  980. self protocols do: [:each || li |
  981. li := html li.
  982. selectedProtocol = each ifTrue: [
  983. li class: 'selected'].
  984. li
  985. with: each;
  986. onClick: [self selectProtocol: each]]]
  987. !
  988. updateSourceAndButtons
  989. self disableSaveButton.
  990. classButtons contents: [:html |
  991. html button
  992. title: 'Create a new class';
  993. onClick: [self addNewClass];
  994. with: 'New class'.
  995. html button
  996. with: 'Rename class';
  997. onClick: [self renameClass].
  998. html button
  999. with: 'Copy class';
  1000. onClick: [self copyClass].
  1001. html button
  1002. with: 'Remove class';
  1003. onClick: [self removeClass].
  1004. html button
  1005. with: 'References';
  1006. onClick: [self searchClassReferences]].
  1007. methodButtons contents: [:html | | protocolSelect referencesSelect |
  1008. html button
  1009. with: 'Remove method';
  1010. onClick: [self removeMethod].
  1011. protocolSelect := html select.
  1012. protocolSelect
  1013. onChange: [ self setMethodProtocol: protocolSelect asJQuery val];
  1014. with: [
  1015. html option
  1016. with: 'Method protocol';
  1017. at: 'disabled' put: 'disabled'.
  1018. html option
  1019. class: 'important';
  1020. with: 'New...'.
  1021. self protocols do: [:each |
  1022. option := html option with: each.
  1023. selectedProtocol = each ifTrue: [ option at: 'selected' put: 'selected' ] ]].
  1024. selectedMethod isNil ifFalse: [
  1025. referencesSelect := html select.
  1026. referencesSelect
  1027. onChange: [self searchReferencesOf: referencesSelect asJQuery val];
  1028. with: [ |option|
  1029. html option
  1030. with: 'References';
  1031. at: 'disabled' put: 'disabled'.
  1032. html option
  1033. class: 'important';
  1034. with: selectedMethod selector.
  1035. selectedMethod messageSends sorted do: [:each |
  1036. html option with: each]]]].
  1037. selectedMethod isNil
  1038. ifTrue: [
  1039. self hideMethodButtons.
  1040. (selectedClass isNil or: [selectedProtocol notNil])
  1041. ifTrue: [self hideClassButtons]
  1042. ifFalse: [self showClassButtons]]
  1043. ifFalse: [
  1044. self hideClassButtons.
  1045. self showMethodButtons].
  1046. sourceArea val: self source
  1047. !
  1048. updateStatus
  1049. sourceArea val = self source
  1050. ifTrue: [
  1051. saveButton ifNotNil: [
  1052. saveButton at: 'disabled' put: true].
  1053. unsavedChanges := false]
  1054. ifFalse: [
  1055. saveButton ifNotNil: [
  1056. saveButton removeAt: 'disabled'].
  1057. unsavedChanges := true]
  1058. !
  1059. updateTabsList
  1060. tabsList contents: [:html || li |
  1061. li := html li.
  1062. selectedTab = #instance ifTrue: [li class: 'selected'].
  1063. li
  1064. with: [
  1065. html span class: 'ltab'.
  1066. html span class: 'mtab'; with: 'Instance'.
  1067. html span class: 'rtab'];
  1068. onClick: [self selectTab: #instance].
  1069. li := html li.
  1070. selectedTab = #class ifTrue: [li class: 'selected'].
  1071. li
  1072. with: [
  1073. html span class: 'ltab'.
  1074. html span class: 'mtab'; with: 'Class'.
  1075. html span class: 'rtab'];
  1076. onClick: [self selectTab: #class].
  1077. li := html li.
  1078. selectedTab = #comment ifTrue: [li class: 'selected'].
  1079. li
  1080. with: [
  1081. html span class: 'ltab'.
  1082. html span class: 'mtab'; with: 'Comment'.
  1083. html span class: 'rtab'];
  1084. onClick: [self selectTab: #comment]]
  1085. ! !
  1086. !Browser class methodsFor: 'accessing'!
  1087. commitPathJs
  1088. ^'js'
  1089. !
  1090. commitPathSt
  1091. ^'st'
  1092. ! !
  1093. !Browser class methodsFor: 'convenience'!
  1094. open
  1095. self new open
  1096. !
  1097. openOn: aClass
  1098. ^self new
  1099. open;
  1100. selectCategory: aClass category;
  1101. selectClass: aClass
  1102. ! !
  1103. TabWidget subclass: #Debugger
  1104. instanceVariableNames: 'error selectedContext sourceArea ul ul2 inspector saveButton unsavedChanges selectedVariable selectedVariableName inspectButton'
  1105. package: 'IDE'!
  1106. !Debugger methodsFor: 'accessing'!
  1107. arguments
  1108. ^self method
  1109. ifNil: [selectedContext temps collect: [:each | nil]]
  1110. ifNotNil: [self method arguments]
  1111. !
  1112. error
  1113. ^error
  1114. !
  1115. error: anError
  1116. error := anError
  1117. !
  1118. label
  1119. ^'[Debugger]'
  1120. !
  1121. method
  1122. ^selectedContext receiver class methodAt: selectedContext selector
  1123. !
  1124. receiver
  1125. ^selectedContext receiver
  1126. !
  1127. source
  1128. ^self method
  1129. ifNil: ['Method doesn''t exist!!']
  1130. ifNotNil: [self method source]
  1131. ! !
  1132. !Debugger methodsFor: 'actions'!
  1133. inspectSelectedVariable
  1134. selectedVariable inspect
  1135. !
  1136. proceed
  1137. self close.
  1138. selectedContext receiver perform: selectedContext selector withArguments: selectedContext temps
  1139. !
  1140. save
  1141. | protocol |
  1142. protocol := (selectedContext receiver class methodDictionary at: selectedContext selector) category.
  1143. selectedContext receiver class compile: sourceArea val category: protocol.
  1144. self updateStatus
  1145. !
  1146. selectContext: aContext
  1147. selectedContext := aContext.
  1148. selectedVariable := nil.
  1149. selectedVariableName := nil.
  1150. self
  1151. updateContextsList;
  1152. updateSourceArea;
  1153. updateInspector;
  1154. updateVariablesList;
  1155. updateStatus
  1156. !
  1157. selectVariable: anObject named: aString
  1158. selectedVariable := anObject.
  1159. selectedVariableName := aString.
  1160. inspector contents: [:html | html with: anObject printString].
  1161. self updateVariablesList
  1162. ! !
  1163. !Debugger methodsFor: 'initialization'!
  1164. initialize
  1165. super initialize.
  1166. unsavedChanges = false
  1167. ! !
  1168. !Debugger methodsFor: 'rendering'!
  1169. renderBottomPanelOn: html
  1170. html div
  1171. class: 'jt_sourceCode debugger';
  1172. with: [
  1173. sourceArea := SourceArea new.
  1174. sourceArea renderOn: html].
  1175. ul2 := html ul class: 'jt_column debugger variables'.
  1176. inspector := html div class: 'jt_column debugger inspector'.
  1177. sourceArea
  1178. onKeyUp: [self updateStatus]
  1179. !
  1180. renderBoxOn: html
  1181. self
  1182. renderTopPanelOn: html;
  1183. renderBottomPanelOn: html
  1184. !
  1185. renderButtonsOn: html
  1186. saveButton := html button
  1187. with: 'Save';
  1188. onClick: [self save].
  1189. html button
  1190. with: 'DoIt';
  1191. onClick: [sourceArea doIt].
  1192. html button
  1193. with: 'PrintIt';
  1194. onClick: [sourceArea printIt].
  1195. html button
  1196. with: 'InspectIt';
  1197. onClick: [sourceArea inspectIt].
  1198. html button
  1199. with: 'Proceed';
  1200. onClick: [self proceed].
  1201. html button
  1202. with: 'Abandon';
  1203. onClick: [self close].
  1204. inspectButton := html button
  1205. class: 'jt_button debugger inspect';
  1206. with: 'Inspect';
  1207. onClick: [self inspectSelectedVariable].
  1208. self
  1209. updateSourceArea;
  1210. updateStatus;
  1211. updateVariablesList;
  1212. updateInspector
  1213. !
  1214. renderContext: aContext on: html
  1215. | li |
  1216. li := html li.
  1217. selectedContext = aContext ifTrue: [
  1218. li class: 'selected'].
  1219. li
  1220. with: aContext asString;
  1221. onClick: [self selectContext: aContext].
  1222. aContext home ifNotNil: [self renderContext: aContext home on: html]
  1223. !
  1224. renderTopPanelOn: html
  1225. selectedContext := self error context.
  1226. html div
  1227. class: 'top';
  1228. with: [
  1229. html div
  1230. class: 'label';
  1231. with: self error messageText.
  1232. ul := html ul
  1233. class: 'jt_column debugger contexts';
  1234. with: [self renderContext: self error context on: html]]
  1235. ! !
  1236. !Debugger methodsFor: 'testing'!
  1237. canBeClosed
  1238. ^true
  1239. ! !
  1240. !Debugger methodsFor: 'updating'!
  1241. updateContextsList
  1242. ul contents: [:html |
  1243. self renderContext: self error context on: html]
  1244. !
  1245. updateInspector
  1246. inspector contents: [:html |]
  1247. !
  1248. updateSourceArea
  1249. sourceArea val: self source
  1250. !
  1251. updateStatus
  1252. sourceArea val = self source
  1253. ifTrue: [
  1254. saveButton ifNotNil: [
  1255. saveButton at: 'disabled' put: true].
  1256. unsavedChanges := false]
  1257. ifFalse: [
  1258. saveButton ifNotNil: [
  1259. saveButton removeAt: 'disabled'].
  1260. unsavedChanges := true]
  1261. !
  1262. updateVariablesList
  1263. ul2 contents: [:html | | li |
  1264. li := html li
  1265. with: 'self';
  1266. onClick: [self selectVariable: self receiver named: 'self'].
  1267. selectedVariableName = 'self' ifTrue: [
  1268. li class: 'selected'].
  1269. self arguments withIndexDo: [:each :index | | param |
  1270. param := selectedContext temps at: index.
  1271. li := html li
  1272. with: each;
  1273. onClick: [self selectVariable: param named: each].
  1274. selectedVariableName = each ifTrue: [
  1275. li class: 'selected']].
  1276. self receiver class allInstanceVariableNames do: [:each | | ivar |
  1277. ivar := self receiver instVarAt: each.
  1278. li := html li
  1279. with: each;
  1280. onClick: [self selectVariable: ivar named: each].
  1281. selectedVariableName = each ifTrue: [
  1282. li class: 'selected']]].
  1283. selectedVariable ifNil: [inspectButton at: 'disabled' put: true] ifNotNil: [inspectButton removeAt: 'disabled']
  1284. ! !
  1285. TabWidget subclass: #IDETranscript
  1286. instanceVariableNames: 'textarea'
  1287. package: 'IDE'!
  1288. !IDETranscript methodsFor: 'accessing'!
  1289. label
  1290. ^'Transcript'
  1291. ! !
  1292. !IDETranscript methodsFor: 'actions'!
  1293. clear
  1294. textarea asJQuery val: ''
  1295. !
  1296. cr
  1297. textarea asJQuery val: textarea asJQuery val, String cr.
  1298. !
  1299. open
  1300. TabManager current
  1301. open;
  1302. selectTab: self
  1303. !
  1304. show: anObject
  1305. textarea ifNil: [self open].
  1306. textarea asJQuery val: textarea asJQuery val, anObject asString.
  1307. ! !
  1308. !IDETranscript methodsFor: 'rendering'!
  1309. renderBoxOn: html
  1310. textarea := html textarea.
  1311. textarea
  1312. class: 'jt_transcript';
  1313. at: 'spellcheck' put: 'false'
  1314. !
  1315. renderButtonsOn: html
  1316. html button
  1317. with: 'Clear transcript';
  1318. onClick: [self clear]
  1319. ! !
  1320. IDETranscript class instanceVariableNames: 'current'!
  1321. !IDETranscript class methodsFor: 'initialization'!
  1322. initialize
  1323. Transcript register: self current
  1324. ! !
  1325. !IDETranscript class methodsFor: 'instance creation'!
  1326. current
  1327. ^current ifNil: [current := super new]
  1328. !
  1329. new
  1330. self shouldNotImplement
  1331. !
  1332. open
  1333. TabManager current
  1334. open;
  1335. selectTab: self current
  1336. ! !
  1337. TabWidget subclass: #Inspector
  1338. instanceVariableNames: 'label variables object selectedVariable variablesList valueTextarea diveButton sourceArea'
  1339. package: 'IDE'!
  1340. !Inspector methodsFor: 'accessing'!
  1341. label
  1342. ^label ifNil: ['Inspector (nil)']
  1343. !
  1344. selectedVariable
  1345. ^selectedVariable
  1346. !
  1347. selectedVariable: aString
  1348. selectedVariable := aString
  1349. !
  1350. setLabel: aString
  1351. label := aString
  1352. !
  1353. setVariables: aCollection
  1354. variables := aCollection
  1355. !
  1356. sourceArea
  1357. ^sourceArea
  1358. !
  1359. variables
  1360. ^variables
  1361. ! !
  1362. !Inspector methodsFor: 'actions'!
  1363. dive
  1364. (self variables at: self selectedVariable) inspect
  1365. !
  1366. inspect: anObject
  1367. object := anObject.
  1368. variables := #().
  1369. object inspectOn: self
  1370. !
  1371. refresh
  1372. self
  1373. inspect: object;
  1374. updateVariablesList;
  1375. updateValueTextarea
  1376. ! !
  1377. !Inspector methodsFor: 'rendering'!
  1378. renderBottomPanelOn: html
  1379. html div
  1380. class: 'jt_sourceCode';
  1381. with: [
  1382. sourceArea := SourceArea new
  1383. receiver: object;
  1384. onDoIt: [self refresh];
  1385. yourself.
  1386. sourceArea renderOn: html]
  1387. !
  1388. renderBoxOn: html
  1389. self
  1390. renderTopPanelOn: html;
  1391. renderBottomPanelOn: html
  1392. !
  1393. renderButtonsOn: html
  1394. html button
  1395. with: 'DoIt';
  1396. onClick: [self sourceArea doIt].
  1397. html button
  1398. with: 'PrintIt';
  1399. onClick: [self sourceArea printIt].
  1400. html button
  1401. with: 'InspectIt';
  1402. onClick: [self sourceArea inspectIt].
  1403. self updateButtons
  1404. !
  1405. renderTopPanelOn: html
  1406. html div
  1407. class: 'top';
  1408. with: [
  1409. variablesList := html ul class: 'jt_column variables'.
  1410. valueTextarea := html textarea class: 'jt_column value'; at: 'readonly' put: 'readonly'.
  1411. html div class: 'jt_tabs inspector'; with: [
  1412. html button
  1413. class: 'jt_button inspector refresh';
  1414. with: 'Refresh';
  1415. onClick: [self refresh].
  1416. diveButton := html button
  1417. class: 'jt_button inspector dive';
  1418. with: 'Dive';
  1419. onClick: [self dive]].
  1420. html div class: 'jt_clear'].
  1421. self
  1422. updateVariablesList;
  1423. updateValueTextarea.
  1424. ! !
  1425. !Inspector methodsFor: 'testing'!
  1426. canBeClosed
  1427. ^true
  1428. ! !
  1429. !Inspector methodsFor: 'updating'!
  1430. selectVariable: aString
  1431. self selectedVariable: aString.
  1432. self
  1433. updateVariablesList;
  1434. updateValueTextarea;
  1435. updateButtons
  1436. !
  1437. updateButtons
  1438. (self selectedVariable notNil and: [(self variables at: self selectedVariable) notNil])
  1439. ifFalse: [diveButton at: 'disabled' put: true]
  1440. ifTrue: [diveButton removeAt: 'disabled']
  1441. !
  1442. updateValueTextarea
  1443. valueTextarea asJQuery val: (self selectedVariable isNil
  1444. ifTrue: ['']
  1445. ifFalse: [(self variables at: self selectedVariable) printString])
  1446. !
  1447. updateVariablesList
  1448. variablesList contents: [:html |
  1449. self variables keys do: [:each || li |
  1450. li := html li.
  1451. li
  1452. with: each;
  1453. onClick: [self selectVariable: each].
  1454. self selectedVariable = each ifTrue: [
  1455. li class: 'selected']]]
  1456. ! !
  1457. !Inspector class methodsFor: 'instance creation'!
  1458. on: anObject
  1459. ^self new
  1460. inspect: anObject;
  1461. yourself
  1462. ! !
  1463. TabWidget subclass: #ProgressBar
  1464. instanceVariableNames: 'percent progressDiv div'
  1465. package: 'IDE'!
  1466. !ProgressBar methodsFor: 'accessing'!
  1467. percent
  1468. ^percent ifNil: [0]
  1469. !
  1470. percent: aNumber
  1471. percent := aNumber
  1472. ! !
  1473. !ProgressBar methodsFor: 'rendering'!
  1474. renderOn: html
  1475. div := html div
  1476. class: 'progress_bar';
  1477. yourself.
  1478. self renderProgressBar
  1479. !
  1480. renderProgressBar
  1481. div contents: [:html |
  1482. html div
  1483. class: 'progress';
  1484. style: 'width:', self percent asString, '%']
  1485. ! !
  1486. !ProgressBar methodsFor: 'updating'!
  1487. updatePercent: aNumber
  1488. self percent: aNumber.
  1489. self renderProgressBar
  1490. ! !
  1491. TabWidget subclass: #ReferencesBrowser
  1492. instanceVariableNames: 'implementors senders implementorsList input timer selector sendersList referencedClasses referencedClassesList'
  1493. package: 'IDE'!
  1494. !ReferencesBrowser methodsFor: 'accessing'!
  1495. classesAndMetaclasses
  1496. ^Smalltalk current classes, (Smalltalk current classes collect: [:each | each class])
  1497. !
  1498. implementors
  1499. ^implementors ifNil: [implementors := Array new]
  1500. !
  1501. label
  1502. ^'[References]'
  1503. !
  1504. referencedClasses
  1505. ^referencedClasses ifNil: [referencedClasses := Array new]
  1506. !
  1507. selector
  1508. ^selector
  1509. !
  1510. senders
  1511. ^senders ifNil: [senders := Array new]
  1512. ! !
  1513. !ReferencesBrowser methodsFor: 'actions'!
  1514. openBrowserOn: aMethod
  1515. | browser |
  1516. browser := Browser openOn: (aMethod methodClass isMetaclass
  1517. ifTrue: [aMethod methodClass instanceClass] ifFalse: [aMethod methodClass]).
  1518. aMethod methodClass isMetaclass ifTrue: [browser selectTab: #class].
  1519. browser
  1520. selectProtocol: aMethod category;
  1521. selectMethod: aMethod
  1522. !
  1523. search: aString
  1524. self
  1525. searchReferencesFor: aString;
  1526. updateImplementorsList;
  1527. updateSendersList;
  1528. updateReferencedClassesList
  1529. !
  1530. searchReferencedClassesFor: aString
  1531. self classesAndMetaclasses do: [:each |
  1532. each methodDictionary values do: [:value |
  1533. (value referencedClasses includes: selector) ifTrue: [
  1534. self referencedClasses add: value]]]
  1535. !
  1536. searchReferencesFor: aString
  1537. selector := aString.
  1538. implementors := Array new.
  1539. senders := Array new.
  1540. referencedClasses := Array new.
  1541. (selector match: '^[A-Z]')
  1542. ifFalse: [self searchSelectorReferencesFor: selector]
  1543. ifTrue: [self searchReferencedClassesFor: selector]
  1544. !
  1545. searchSelectorReferencesFor: aString
  1546. self classesAndMetaclasses do: [:each |
  1547. each methodDictionary keysAndValuesDo: [:key :value |
  1548. key = selector ifTrue: [self implementors add: value].
  1549. (value messageSends includes: selector) ifTrue: [
  1550. self senders add: value]]]
  1551. ! !
  1552. !ReferencesBrowser methodsFor: 'initialization'!
  1553. initialize
  1554. super initialize.
  1555. selector := ''
  1556. ! !
  1557. !ReferencesBrowser methodsFor: 'private'!
  1558. setInputEvents
  1559. input
  1560. onKeyUp: [timer := [self search: input asJQuery val] valueWithTimeout: 100];
  1561. onKeyDown: [timer ifNotNil: [timer clearTimeout]]
  1562. ! !
  1563. !ReferencesBrowser methodsFor: 'rendering'!
  1564. renderBoxOn: html
  1565. self
  1566. renderInputOn: html;
  1567. renderImplementorsOn: html;
  1568. renderSendersOn: html;
  1569. renderReferencedClassesOn: html
  1570. !
  1571. renderImplementorsOn: html
  1572. implementorsList := html ul class: 'jt_column implementors'.
  1573. self updateImplementorsList
  1574. !
  1575. renderInputOn: html
  1576. input := html input
  1577. class: 'implementors';
  1578. yourself.
  1579. input asJQuery val: selector.
  1580. self setInputEvents
  1581. !
  1582. renderReferencedClassesOn: html
  1583. referencedClassesList := html ul class: 'jt_column referenced_classes'.
  1584. self updateReferencedClassesList
  1585. !
  1586. renderSendersOn: html
  1587. sendersList := html ul class: 'jt_column senders'.
  1588. self updateSendersList
  1589. ! !
  1590. !ReferencesBrowser methodsFor: 'testing'!
  1591. canBeClosed
  1592. ^true
  1593. ! !
  1594. !ReferencesBrowser methodsFor: 'updating'!
  1595. updateImplementorsList
  1596. implementorsList contents: [:html |
  1597. html li
  1598. class: 'column_label';
  1599. with: 'Implementors (', self implementors size asString, ')';
  1600. style: 'font-weight: bold'.
  1601. self implementors do: [:each || li |
  1602. li := html li.
  1603. li
  1604. with: (each methodClass asString, ' >> ', self selector);
  1605. onClick: [self openBrowserOn: each]]]
  1606. !
  1607. updateReferencedClassesList
  1608. referencedClassesList contents: [:html |
  1609. html li
  1610. class: 'column_label';
  1611. with: 'Class references (', self referencedClasses size asString, ')';
  1612. style: 'font-weight: bold'.
  1613. self referencedClasses do: [:each |
  1614. html li
  1615. with: (each methodClass asString, ' >> ', each selector);
  1616. onClick: [self openBrowserOn: each]]]
  1617. !
  1618. updateSendersList
  1619. sendersList contents: [:html |
  1620. html li
  1621. class: 'column_label';
  1622. with: 'Senders (', self senders size asString, ')';
  1623. style: 'font-weight: bold'.
  1624. self senders do: [:each |
  1625. html li
  1626. with: (each methodClass asString, ' >> ', each selector);
  1627. onClick: [self openBrowserOn: each]]]
  1628. ! !
  1629. !ReferencesBrowser class methodsFor: 'instance creation'!
  1630. search: aString
  1631. ^self new
  1632. searchReferencesFor: aString;
  1633. open
  1634. ! !
  1635. TabWidget subclass: #TestRunner
  1636. instanceVariableNames: 'selectedCategories packagesList selectedClasses classesList selectedMethods progressBar methodsList result statusDiv'
  1637. package: 'IDE'!
  1638. !TestRunner methodsFor: 'accessing'!
  1639. allClasses
  1640. ^TestCase allSubclasses
  1641. !
  1642. classes
  1643. ^(self allClasses
  1644. select: [:each | self selectedCategories includes: each category])
  1645. sort: [:a :b | a name > b name]
  1646. !
  1647. label
  1648. ^'SUnit'
  1649. !
  1650. packages
  1651. | packages |
  1652. packages := Array new.
  1653. self allClasses do: [:each |
  1654. (packages includes: each category) ifFalse: [
  1655. packages add: each category]].
  1656. ^packages sort
  1657. !
  1658. progressBar
  1659. ^progressBar ifNil: [progressBar := ProgressBar new]
  1660. !
  1661. result
  1662. ^result
  1663. !
  1664. selectedCategories
  1665. ^selectedCategories ifNil: [selectedCategories := Array new]
  1666. !
  1667. selectedClasses
  1668. ^selectedClasses ifNil: [selectedClasses := Array new]
  1669. !
  1670. statusInfo
  1671. ^self printTotal, self printPasses, self printErrors, self printFailures
  1672. !
  1673. testCases
  1674. | testCases |
  1675. testCases := #().
  1676. self selectedClasses do: [:each | testCases addAll: each buildSuite].
  1677. ^testCases
  1678. ! !
  1679. !TestRunner methodsFor: 'actions'!
  1680. performFailure: aTestCase
  1681. aTestCase perform: aTestCase selector
  1682. !
  1683. run: aCollection
  1684. result := TestResult new.
  1685. self
  1686. updateStatusDiv;
  1687. updateMethodsList.
  1688. self progressBar updatePercent: 0.
  1689. result total: aCollection size.
  1690. aCollection do: [:each |
  1691. [each runCaseFor: result.
  1692. self progressBar updatePercent: result runs / result total * 100.
  1693. self updateStatusDiv.
  1694. self updateMethodsList] valueWithTimeout: 100].
  1695. !
  1696. selectAllCategories
  1697. self packages do: [:each |
  1698. (selectedCategories includes: each) ifFalse: [
  1699. self selectedCategories add: each]].
  1700. self
  1701. updateCategoriesList;
  1702. updateClassesList
  1703. !
  1704. selectAllClasses
  1705. self classes do: [:each |
  1706. (selectedClasses includes: each) ifFalse: [
  1707. self selectedClasses add: each]].
  1708. self
  1709. updateCategoriesList;
  1710. updateClassesList
  1711. !
  1712. toggleCategory: aCategory
  1713. (self isSelectedCategory: aCategory)
  1714. ifFalse: [selectedCategories add: aCategory]
  1715. ifTrue: [selectedCategories remove: aCategory].
  1716. self
  1717. updateCategoriesList;
  1718. updateClassesList
  1719. !
  1720. toggleClass: aClass
  1721. (self isSelectedClass: aClass)
  1722. ifFalse: [selectedClasses add: aClass]
  1723. ifTrue: [selectedClasses remove: aClass].
  1724. self
  1725. updateClassesList
  1726. ! !
  1727. !TestRunner methodsFor: 'initialization'!
  1728. initialize
  1729. super initialize.
  1730. result := TestResult new
  1731. ! !
  1732. !TestRunner methodsFor: 'printing'!
  1733. printErrors
  1734. ^self result errors size asString , ' errors, '
  1735. !
  1736. printFailures
  1737. ^self result failures size asString, ' failures'
  1738. !
  1739. printPasses
  1740. ^(self result total - self result errors size - self result failures size) asString , ' passes, '
  1741. !
  1742. printTotal
  1743. ^self result total asString, ' runs, '
  1744. ! !
  1745. !TestRunner methodsFor: 'rendering'!
  1746. renderBoxOn: html
  1747. self
  1748. renderCategoriesOn: html;
  1749. renderClassesOn: html;
  1750. renderResultsOn: html
  1751. !
  1752. renderButtonsOn: html
  1753. html button
  1754. with: 'Run selected';
  1755. onClick: [self run: self testCases]
  1756. !
  1757. renderCategoriesOn: html
  1758. packagesList := html ul class: 'jt_column sunit packages'.
  1759. self updateCategoriesList
  1760. !
  1761. renderClassesOn: html
  1762. classesList := html ul class: 'jt_column sunit classes'.
  1763. self updateClassesList
  1764. !
  1765. renderErrorsOn: html
  1766. self result errors do: [:each |
  1767. html li
  1768. class: 'errors';
  1769. with: each class name, ' >> ', each selector;
  1770. onClick: [self performFailure: each]]
  1771. !
  1772. renderFailuresOn: html
  1773. self result failures do: [:each |
  1774. html li
  1775. class: 'failures';
  1776. with: each class name, ' >> ', each selector;
  1777. onClick: [self performFailure: each]]
  1778. !
  1779. renderResultsOn: html
  1780. statusDiv := html div.
  1781. html with: self progressBar.
  1782. methodsList := html ul class: 'jt_column sunit results'.
  1783. self updateMethodsList.
  1784. self updateStatusDiv
  1785. ! !
  1786. !TestRunner methodsFor: 'testing'!
  1787. isSelectedCategory: aCategory
  1788. ^(self selectedCategories includes: aCategory)
  1789. !
  1790. isSelectedClass: aClass
  1791. ^(self selectedClasses includes: aClass)
  1792. ! !
  1793. !TestRunner methodsFor: 'updating'!
  1794. updateCategoriesList
  1795. packagesList contents: [:html |
  1796. html li
  1797. class: 'all';
  1798. with: 'All';
  1799. onClick: [self selectAllCategories].
  1800. self packages do: [:each || li |
  1801. li := html li.
  1802. (self selectedCategories includes: each) ifTrue: [
  1803. li class: 'selected'].
  1804. li
  1805. with: each;
  1806. onClick: [self toggleCategory: each]]]
  1807. !
  1808. updateClassesList
  1809. classesList contents: [:html |
  1810. (self selectedCategories isEmpty) ifFalse: [
  1811. html li
  1812. class: 'all';
  1813. with: 'All';
  1814. onClick: [self selectAllClasses]].
  1815. self classes do: [:each || li |
  1816. li := html li.
  1817. (self selectedClasses includes: each) ifTrue: [
  1818. li class: 'selected'].
  1819. li
  1820. with: each name;
  1821. onClick: [self toggleClass: each]]]
  1822. !
  1823. updateMethodsList
  1824. methodsList contents: [:html |
  1825. self renderErrorsOn: html.
  1826. self renderFailuresOn: html]
  1827. !
  1828. updateStatusDiv
  1829. statusDiv class: 'sunit status ', result status.
  1830. statusDiv contents: [:html |
  1831. html span with: self statusInfo]
  1832. ! !
  1833. TabWidget subclass: #Workspace
  1834. instanceVariableNames: 'sourceArea'
  1835. package: 'IDE'!
  1836. !Workspace methodsFor: 'accessing'!
  1837. label
  1838. ^'Workspace'
  1839. ! !
  1840. !Workspace methodsFor: 'actions'!
  1841. clearWorkspace
  1842. sourceArea clear
  1843. !
  1844. doIt
  1845. sourceArea doIt
  1846. !
  1847. fileIn
  1848. sourceArea fileIn
  1849. !
  1850. inspectIt
  1851. sourceArea inspectIt
  1852. !
  1853. printIt
  1854. sourceArea printIt
  1855. ! !
  1856. !Workspace methodsFor: 'rendering'!
  1857. renderBoxOn: html
  1858. sourceArea := SourceArea new.
  1859. sourceArea renderOn: html
  1860. !
  1861. renderButtonsOn: html
  1862. html button
  1863. with: 'DoIt';
  1864. title: 'ctrl+d';
  1865. onClick: [self doIt].
  1866. html button
  1867. with: 'PrintIt';
  1868. title: 'ctrl+p';
  1869. onClick: [self printIt].
  1870. html button
  1871. with: 'InspectIt';
  1872. title: 'ctrl+i';
  1873. onClick: [self inspectIt].
  1874. html button
  1875. with: 'FileIn';
  1876. title: 'ctrl+f';
  1877. onClick: [self fileIn].
  1878. html button
  1879. with: 'Clear workspace';
  1880. onClick: [self clearWorkspace]
  1881. ! !
  1882. !Object methodsFor: '*IDE'!
  1883. inspect
  1884. Inspector new
  1885. inspect: self;
  1886. open
  1887. !
  1888. inspectOn: anInspector
  1889. | variables |
  1890. variables := Dictionary new.
  1891. variables at: '#self' put: self.
  1892. self class allInstanceVariableNames do: [:each |
  1893. variables at: each put: (self instVarAt: each)].
  1894. anInspector
  1895. setLabel: self printString;
  1896. setVariables: variables
  1897. ! !
  1898. !Collection methodsFor: '*IDE'!
  1899. inspectOn: anInspector
  1900. | variables |
  1901. variables := Dictionary new.
  1902. variables at: '#self' put: self.
  1903. self withIndexDo: [:each :i |
  1904. variables at: i put: each].
  1905. anInspector
  1906. setLabel: self printString;
  1907. setVariables: variables
  1908. ! !
  1909. !HashedCollection methodsFor: '*IDE'!
  1910. inspectOn: anInspector
  1911. | variables |
  1912. variables := Dictionary new.
  1913. variables at: '#self' put: self.
  1914. variables at: '#keys' put: self keys.
  1915. self keysAndValuesDo: [:key :value |
  1916. variables at: key put: value].
  1917. anInspector
  1918. setLabel: self printString;
  1919. setVariables: variables
  1920. ! !
  1921. !String methodsFor: '*IDE'!
  1922. inspectOn: anInspector
  1923. | label |
  1924. super inspectOn: anInspector.
  1925. self printString size > 30
  1926. ifTrue: [label := (self printString copyFrom: 1 to: 30), '...''']
  1927. ifFalse: [label := self printString].
  1928. anInspector setLabel: label
  1929. ! !
  1930. !Set methodsFor: '*IDE'!
  1931. inspectOn: anInspector
  1932. | variables |
  1933. variables := Dictionary new.
  1934. variables at: '#self' put: self.
  1935. elements withIndexDo: [:each :i |
  1936. variables at: i put: each].
  1937. anInspector
  1938. setLabel: self printString;
  1939. setVariables: variables
  1940. ! !
  1941. !Date methodsFor: '*IDE'!
  1942. inspectOn: anInspector
  1943. | variables |
  1944. variables := Dictionary new.
  1945. variables at: '#self' put: self.
  1946. variables at: '#year' put: self year.
  1947. variables at: '#month' put: self month.
  1948. variables at: '#day' put: self day.
  1949. variables at: '#hours' put: self hours.
  1950. variables at: '#minutes' put: self minutes.
  1951. variables at: '#seconds' put: self seconds.
  1952. variables at: '#milliseconds' put: self milliseconds.
  1953. anInspector
  1954. setLabel: self printString;
  1955. setVariables: variables
  1956. ! !
  1957. !Date methodsFor: '*IDE'!
  1958. inspectOn: anInspector
  1959. | variables |
  1960. variables := Dictionary new.
  1961. variables at: '#self' put: self.
  1962. variables at: '#year' put: self year.
  1963. variables at: '#month' put: self month.
  1964. variables at: '#day' put: self day.
  1965. variables at: '#hours' put: self hours.
  1966. variables at: '#minutes' put: self minutes.
  1967. variables at: '#seconds' put: self seconds.
  1968. variables at: '#milliseconds' put: self milliseconds.
  1969. anInspector
  1970. setLabel: self printString;
  1971. setVariables: variables
  1972. ! !
  1973. !MethodContext methodsFor: '*IDE'!
  1974. inspectOn: anInspector
  1975. | variables |
  1976. variables := Dictionary new.
  1977. variables at: '#self' put: self.
  1978. variables at: '#home' put: self home.
  1979. variables at: '#receiver' put: self receiver.
  1980. variables at: '#selector' put: self selector.
  1981. variables at: '#temps' put: self temps.
  1982. self class instanceVariableNames do: [:each |
  1983. variables at: each put: (self instVarAt: each)].
  1984. anInspector
  1985. setLabel: self printString;
  1986. setVariables: variables
  1987. ! !