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