11 !InspectorList class methodsFor:'instance creation'! |
11 !InspectorList class methodsFor:'instance creation'! |
12 |
12 |
13 for:anObject |
13 for:anObject |
14 "create a new list for an instance |
14 "create a new list for an instance |
15 " |
15 " |
16 ^ self basicNew for:anObject |
16 ^ self new inspect:anObject |
|
17 |
|
18 |
|
19 ! |
|
20 |
|
21 new |
|
22 "create a new instance and set the inspected object to nil |
|
23 " |
|
24 ^ self basicNew initialize. |
|
25 |
|
26 ! ! |
|
27 |
|
28 !InspectorList class methodsFor:'helpers'! |
|
29 |
|
30 asString:aCollection |
|
31 "converts any collection to a string seperated by spaces. If |
|
32 the collection is empty or nil, nil is returned otherwise a |
|
33 string. |
|
34 " |
|
35 |string| |
|
36 |
|
37 aCollection isCollection ifTrue:[ |
|
38 aCollection isString ifTrue:[ |
|
39 string := aCollection |
|
40 ] ifFalse:[ |
|
41 string := aCollection asStringWith:Character space |
|
42 from:1 to:(aCollection size) |
|
43 compressTabs:true |
|
44 final:nil |
|
45 ]. |
|
46 string := string withoutSeparators. |
|
47 |
|
48 string notEmpty ifTrue:[ |
|
49 ^ string |
|
50 ] |
|
51 ]. |
|
52 ^ nil |
17 |
53 |
18 |
54 |
19 ! ! |
55 ! ! |
20 |
56 |
21 !InspectorList class methodsFor:'testing'! |
57 !InspectorList class methodsFor:'testing'! |
22 |
58 |
23 isDirectory:anInstance |
59 isDirectory:anInstance |
24 "returns true if the class is a directory |
60 "returns true if the instance is a directory |
25 " |
61 " |
26 |cls| |
62 |cls| |
27 |
63 |
28 anInstance notNil ifTrue:[ |
64 anInstance notNil ifTrue:[ |
29 cls := anInstance class. |
65 cls := anInstance class. |
41 ]. |
77 ]. |
42 ]. |
78 ]. |
43 ^ false |
79 ^ false |
44 |
80 |
45 |
81 |
|
82 ! |
|
83 |
|
84 isTraceable:anInstance |
|
85 "returns true if the instance could be traced or traped |
|
86 " |
|
87 |cls| |
|
88 |
|
89 anInstance notNil ifTrue:[ |
|
90 cls := anInstance class. |
|
91 |
|
92 ^ ( cls ~~ True |
|
93 and:[cls ~~ False |
|
94 and:[cls ~~ SmallInteger]] |
|
95 ) |
|
96 ]. |
|
97 ^ false. |
|
98 |
46 ! ! |
99 ! ! |
47 |
100 |
48 !InspectorList methodsFor:'accessing'! |
101 !InspectorList methodsFor:'accessing'! |
49 |
|
50 includesSelf |
|
51 "returns true if 'self' is included in the list |
|
52 " |
|
53 ^ (self instanceTypeAt:1) == #self |
|
54 |
|
55 |
|
56 ! |
|
57 |
102 |
58 includesSelf:aBoolean |
103 includesSelf:aBoolean |
59 "includes 'self' dependant on the boolean |
104 "includes 'self' dependant on the boolean |
60 " |
105 " |
61 (self includesSelf) ~~ aBoolean ifTrue:[ |
106 (self includesSelf) ~~ aBoolean ifTrue:[ |
62 aBoolean ifTrue:[ |
107 aBoolean ifTrue:[ |
63 instanceNames addFirst:'self'. |
108 instanceNames addFirst:'self'. |
64 instanceTypes addFirst:#self. |
109 instanceTypes addFirst:#self. |
65 |
110 |
66 selection isNil ifTrue:[selection := 1] |
111 selection notNil ifTrue:[selection := selection + 1] |
67 ifFalse:[selection := selection + 1] |
112 ifFalse:[selection := 1] |
|
113 |
68 ] ifFalse:[ |
114 ] ifFalse:[ |
69 instanceNames removeFirst. |
115 instanceNames removeFirst. |
70 instanceTypes removeFirst. |
116 instanceTypes removeFirst. |
71 |
117 |
72 selection isNil ifFalse:[ |
118 selection isNil ifFalse:[ |
95 ^ inspectedObject |
169 ^ inspectedObject |
96 |
170 |
97 |
171 |
98 ! |
172 ! |
99 |
173 |
100 instanceNameAt:anIndex |
|
101 "returns the name assigned to the index |
|
102 " |
|
103 |idx nm| |
|
104 |
|
105 (anIndex notNil and:[anIndex <= instanceTypes size]) ifTrue:[ |
|
106 nm := instanceNames at:anIndex. |
|
107 |
|
108 (nm at:1) isDigit ifFalse:[ |
|
109 ^ nm |
|
110 ]. |
|
111 idx := Number readFrom:nm onError:0. |
|
112 ^ '[', idx printString, ']'. |
|
113 ]. |
|
114 ^ nil |
|
115 |
|
116 |
|
117 ! |
|
118 |
|
119 instanceNames |
174 instanceNames |
120 "returns list of instance names |
175 "returns list of instance names |
121 " |
176 " |
122 ^ instanceNames |
177 ^ instanceNames |
123 |
178 |
124 |
179 |
125 ! |
180 ! |
126 |
181 |
127 instanceTypeAt:anIndex |
182 instanceTypeAt:anIndex |
128 "returns type assigned to the list entry (#directory #normal #self) |
183 "returns type assigned to the list entry (#directory #normal #self #grow) |
129 " |
184 In case of an invalid index nil is returned. |
130 (anIndex notNil and:[anIndex <= instanceTypes size]) ifTrue:[ |
185 " |
131 ^ instanceTypes at:anIndex |
186 (anIndex isNil or:[anIndex > instanceTypes size]) ifFalse:[^ instanceTypes at:anIndex] |
132 ]. |
187 ifTrue:[^ nil]. |
133 ^ nil |
|
134 |
188 |
135 |
189 |
136 ! |
190 ! |
137 |
191 |
138 instanceTypes |
192 instanceTypes |
139 "returns list of types (#directory #normal #self) |
193 "returns list of types (#directory #normal #self #grow) |
140 " |
194 " |
141 ^ instanceTypes |
195 ^ instanceTypes |
142 |
196 |
143 |
197 |
144 ! |
198 ! |
145 |
199 |
146 instanceVarAt:anIndex |
200 instanceVarAt:anIndex |
147 "returns the instnace variable assigned to the index |
201 "returns the instnace variable assigned to the index or |
|
202 nil in case of an invalid index. |
148 " |
203 " |
149 |idx nm| |
204 |idx nm| |
150 |
205 |
151 (anIndex notNil and:[anIndex <= instanceTypes size]) ifTrue:[ |
206 (anIndex isNil or:[anIndex > instanceTypes size]) ifFalse:[ |
152 nm := instanceNames at:anIndex. |
207 nm := instanceNames at:anIndex. |
153 |
208 |
154 (nm at:1) isDigit ifFalse:[ |
209 (nm at:1) isDigit ifFalse:[ |
155 self includesSelf ifFalse:[ |
210 self includesSelf ifFalse:[ |
156 ^ inspectedObject instVarAt:anIndex |
211 ^ inspectedObject instVarAt:anIndex |
163 ^ nil |
218 ^ nil |
164 |
219 |
165 |
220 |
166 ! ! |
221 ! ! |
167 |
222 |
168 !InspectorList methodsFor:'actions'! |
|
169 |
|
170 accept:aText notifying:aView |
|
171 "on error #Error is returned otherwise the inspected object instance |
|
172 " |
|
173 |txt slNr value| |
|
174 |
|
175 (selection isNil or:[(txt := self textToString:aText) isNil]) ifTrue:[ |
|
176 ^ #Error |
|
177 ]. |
|
178 |
|
179 self includesSelf ifFalse:[slNr := selection] |
|
180 ifTrue:[slNr := selection -1]. |
|
181 |
|
182 value := inspectedObject class evaluatorClass |
|
183 evaluate:txt |
|
184 receiver:inspectedObject |
|
185 notifying:aView. |
|
186 |
|
187 slNr ~~ 0 ifTrue:[ |
|
188 (inspectedObject class isVariable) ifFalse:[ |
|
189 inspectedObject instVarAt:slNr put:value |
|
190 ] ifTrue:[ |
|
191 slNr <= (inspectedObject class instSize) ifTrue:[ |
|
192 inspectedObject instVarAt:slNr put:value |
|
193 ] ifFalse:[ |
|
194 slNr := slNr - inspectedObject class instSize. |
|
195 inspectedObject basicAt:slNr put:value |
|
196 ] |
|
197 ] |
|
198 ]. |
|
199 inspectedObject changed. |
|
200 self update. |
|
201 ^ inspectedObject |
|
202 |
|
203 |
|
204 ! |
|
205 |
|
206 doIt:aCode notifying:aView |
|
207 "on success the value returned from parser is returned otherwise #Error |
|
208 " |
|
209 |code result evaluator selInstVar state| |
|
210 |
|
211 (selection isNil or:[(code := self textToString:aCode) isNil]) ifFalse:[ |
|
212 selInstVar := self selectedInstanceVar. |
|
213 evaluator := selInstVar class evaluatorClass. |
|
214 state := true. |
|
215 |
|
216 evaluator notNil ifTrue:[ |
|
217 result := evaluator evaluate:code |
|
218 in:nil |
|
219 receiver:selInstVar |
|
220 notifying:aView |
|
221 logged:true |
|
222 ifFail:[state := false]. |
|
223 |
|
224 state ifTrue:[ |
|
225 self update. |
|
226 ^ result |
|
227 ] |
|
228 ] |
|
229 ]. |
|
230 ^ #Error. |
|
231 |
|
232 |
|
233 ! ! |
|
234 |
|
235 !InspectorList methodsFor:'initialization'! |
223 !InspectorList methodsFor:'initialization'! |
236 |
224 |
237 for:anObject |
225 initialize |
238 "setup a new instance |
226 "initialize instance attributes |
239 " |
227 " |
240 |varNamesSize| |
228 super initialize. |
241 |
229 |
242 inspectedObject := anObject. |
230 instanceNames := OrderedCollection new. |
243 selection := nil. |
231 instanceTypes := OrderedCollection new. |
244 |
232 |
245 (self class isDirectory:inspectedObject) ifTrue:[ |
233 ! ! |
246 instanceNames := inspectedObject class allInstVarNames. |
234 |
247 varNamesSize := instanceNames size. |
235 !InspectorList methodsFor:'private'! |
248 instanceTypes := OrderedCollection new:varNamesSize. |
236 |
249 |
237 resizeTo:aNumber |
250 1 to:varNamesSize do:[:i| |
238 "resize list to minimum aNumber |
251 (self class isDirectory:(inspectedObject instVarAt:i)) ifTrue:[ |
239 " |
252 instanceTypes add:#directory |
240 |lstVarId basicSize newLastId obj instSize| |
253 ] ifFalse:[ |
241 |
254 instanceTypes add:#normal |
242 (inspectedObject isVariable and:[self class isDirectory:inspectedObject]) ifFalse:[ |
255 ] |
243 ^ self |
256 ] |
244 ]. |
|
245 |
|
246 instanceTypes size == 0 ifTrue:[ |
|
247 lstVarId := 0 |
257 ] ifFalse:[ |
248 ] ifFalse:[ |
258 instanceNames := OrderedCollection new. |
249 instSize := inspectedObject class instSize. |
259 instanceTypes := OrderedCollection new. |
250 |
260 ]. |
251 instanceTypes first == #self ifTrue:[ |
261 self update. |
252 instSize := instSize + 1 |
262 ! ! |
253 ]. |
263 |
|
264 !InspectorList methodsFor:'private'! |
|
265 |
|
266 lastVariableId |
|
267 "returns last variable id or nil if not growable |
|
268 " |
|
269 |lstId bscSz| |
|
270 |
|
271 (inspectedObject isVariable and:[self class isDirectory:inspectedObject]) ifFalse:[ |
|
272 ^ nil |
|
273 ]. |
|
274 |
|
275 bscSz := inspectedObject class instSize. |
|
276 |
|
277 self includesSelf ifTrue:[ |
|
278 bscSz := bscSz + 1. |
|
279 ]. |
|
280 lstId := instanceTypes size - bscSz. |
|
281 |
|
282 (lstId ~~ 0 and:[instanceTypes last == #grow]) ifTrue:[^ lstId-1] |
|
283 ifFalse:[^ lstId]. |
|
284 ! |
|
285 |
|
286 resizeVariableList:toNumber |
|
287 "resize variable list |
|
288 " |
|
289 |lstVarId basicSize newLastId obj| |
|
290 |
|
291 (lstVarId := self lastVariableId) isNil ifTrue:[ |
|
292 ^ self |
|
293 ]. |
|
294 |
|
295 basicSize := inspectedObject basicSize. |
|
296 |
|
297 (toNumber <= lstVarId or:[basicSize == lstVarId]) ifTrue:[ |
|
298 ^ self |
|
299 ]. |
|
300 newLastId := (toNumber + 49) roundTo:100. |
|
301 |
|
302 newLastId > basicSize ifTrue:[ |
|
303 newLastId := basicSize |
|
304 ]. |
|
305 |
|
306 lstVarId ~~ 0 ifTrue:[ |
|
307 instanceTypes last == #grow ifTrue:[ |
254 instanceTypes last == #grow ifTrue:[ |
308 instanceNames removeLast. " .. " |
255 instanceNames removeLast. " .. " |
309 instanceTypes removeLast. " #grow " |
256 instanceTypes removeLast. " #grow " |
310 ] |
257 ]. |
|
258 lstVarId := instanceTypes size - instSize. |
|
259 ]. |
|
260 |
|
261 (basicSize := inspectedObject basicSize) == lstVarId ifTrue:[ |
|
262 ^ self |
|
263 ]. |
|
264 newLastId := (1 bitShift:((aNumber-1) highBit)) max:128. |
|
265 |
|
266 (newLastId + 64) > basicSize ifTrue:[ |
|
267 newLastId := basicSize |
311 ]. |
268 ]. |
312 |
269 |
313 [lstVarId ~~ newLastId] whileTrue:[ |
270 [lstVarId ~~ newLastId] whileTrue:[ |
314 lstVarId := lstVarId + 1. |
271 lstVarId := lstVarId + 1. |
315 obj := inspectedObject basicAt:lstVarId. |
272 obj := inspectedObject basicAt:lstVarId. |
322 |
279 |
323 lstVarId ~~ basicSize ifTrue:[ |
280 lstVarId ~~ basicSize ifTrue:[ |
324 instanceNames add:'..'. |
281 instanceNames add:'..'. |
325 instanceTypes add:#grow |
282 instanceTypes add:#grow |
326 ]. |
283 ]. |
327 |
|
328 |
|
329 ! |
|
330 |
|
331 textToString:aText |
|
332 "converts a text to a string |
|
333 " |
|
334 |s| |
|
335 |
|
336 aText isString ifTrue:[ |
|
337 s := aText string |
|
338 ] ifFalse:[ |
|
339 aText isCollection ifTrue:[ |
|
340 s := ''. |
|
341 aText do:[:el|el notNil ifTrue:[s := s, el string]]. |
|
342 ] |
|
343 ]. |
|
344 |
|
345 s notNil ifTrue:[ |
|
346 (s := s withoutSeparators) notEmpty ifTrue:[ |
|
347 ^ s |
|
348 ] |
|
349 ]. |
|
350 ^ nil. |
|
351 |
|
352 |
|
353 ! |
|
354 |
|
355 update |
|
356 "update contents |
|
357 " |
|
358 |delNr lstVarId| |
|
359 |
|
360 (lstVarId := self lastVariableId) isNil ifFalse:[ |
|
361 lstVarId == 0 ifTrue:[ |
|
362 lstVarId := 100 |
|
363 ] ifFalse:[ |
|
364 instanceTypes last == #grow ifTrue:[delNr := lstVarId+1] |
|
365 ifFalse:[delNr := lstVarId]. |
|
366 |
|
367 instanceTypes removeLast:delNr. |
|
368 instanceNames removeLast:delNr. |
|
369 ]. |
|
370 self resizeVariableList:lstVarId. |
|
371 ] |
|
372 ! ! |
284 ! ! |
373 |
285 |
374 !InspectorList methodsFor:'selections'! |
286 !InspectorList methodsFor:'selections'! |
375 |
287 |
376 selectedInstanceName |
|
377 "returns name of current selection or nil |
|
378 " |
|
379 ^ self instanceNameAt:selection |
|
380 |
|
381 |
|
382 ! |
|
383 |
|
384 selectedInstanceType |
288 selectedInstanceType |
385 "returns type of current selection or nil |
289 "returns type assigned to the selected list entry (#directory #normal #self #grow). |
|
290 In case of no selection nil is returned. |
386 " |
291 " |
387 ^ self instanceTypeAt:selection |
292 ^ self instanceTypeAt:selection |
388 |
293 |
389 |
294 |
390 ! |
295 ! |
403 ^ selection |
308 ^ selection |
404 |
309 |
405 |
310 |
406 ! |
311 ! |
407 |
312 |
408 selection:aNrOrNil |
313 setSelection:aNrOrNil |
409 "change current selection to a number or nil; may grow a variable list |
314 "change current selection to a number or nil; may resize the lists |
410 " |
315 " |
411 |rsz| |
316 selection := aNrOrNil. |
412 |
317 |
413 aNrOrNil isNil ifTrue:[ |
318 (selection isNil or:[instanceTypes size > selection]) ifFalse:[ |
414 self includesSelf ifTrue:[selection := 1] |
319 self resizeTo:selection. |
415 ifFalse:[selection := nil] |
320 |
416 ] ifFalse:[ |
321 selection > instanceTypes size ifTrue:[ |
417 aNrOrNil >= instanceNames size ifTrue:[ |
322 selection := nil |
418 (rsz := self lastVariableId) notNil ifTrue:[ |
323 ] |
419 rsz := rsz * 2. |
324 ] |
420 |
325 ! ! |
421 rsz < aNrOrNil ifTrue:[ |
326 |
422 rsz := aNrOrNil |
327 !InspectorList methodsFor:'testing'! |
423 ]. |
328 |
424 self resizeVariableList:rsz |
329 includesSelf |
|
330 "returns true if 'self' is included in the list |
|
331 " |
|
332 ^ (instanceTypes notEmpty and:[instanceTypes first == #self]) |
|
333 |
|
334 |
|
335 ! |
|
336 |
|
337 isEmpty |
|
338 "returns true if the list is empty |
|
339 " |
|
340 ^ instanceNames isEmpty |
|
341 |
|
342 ! |
|
343 |
|
344 notEmpty |
|
345 "returns true if the list is not empty |
|
346 " |
|
347 ^ instanceNames notEmpty |
|
348 |
|
349 ! ! |
|
350 |
|
351 !InspectorList methodsFor:'user interaction'! |
|
352 |
|
353 accept:aText notifying:aView |
|
354 "evaluating aText on the selected instance var; if an error occurs #Error |
|
355 is returned otherwise the inspected object instance. On success the list |
|
356 will be updated. |
|
357 " |
|
358 |text slNr value| |
|
359 |
|
360 selection notNil ifTrue:[ |
|
361 text := self class asString:aText. |
|
362 |
|
363 text notNil ifTrue:[ |
|
364 self includesSelf ifFalse:[slNr := selection] |
|
365 ifTrue:[slNr := selection-1]. |
|
366 |
|
367 value := inspectedObject class evaluatorClass |
|
368 evaluate:text |
|
369 receiver:inspectedObject |
|
370 notifying:aView. |
|
371 |
|
372 slNr ~~ 0 ifTrue:[ |
|
373 (inspectedObject class isVariable) ifFalse:[ |
|
374 inspectedObject instVarAt:slNr put:value |
|
375 ] ifTrue:[ |
|
376 slNr <= (inspectedObject class instSize) ifTrue:[ |
|
377 inspectedObject instVarAt:slNr put:value |
|
378 ] ifFalse:[ |
|
379 slNr := slNr - inspectedObject class instSize. |
|
380 inspectedObject basicAt:slNr put:value |
|
381 ] |
|
382 ] |
|
383 ]. |
|
384 inspectedObject changed. |
|
385 self update. |
|
386 ^ inspectedObject |
|
387 ] |
|
388 ]. |
|
389 ^ #Error |
|
390 ! |
|
391 |
|
392 doIt:aCode notifying:aView |
|
393 "evaluating aCode on the selected instance var; if an error occurs #Error |
|
394 is returned otherwise the result returned from the evaluator. On success |
|
395 the list will be updated. |
|
396 " |
|
397 |successFg result evaluator selInstVar code| |
|
398 |
|
399 selInstVar := self selectedInstanceVar. |
|
400 |
|
401 selInstVar notNil ifTrue:[ |
|
402 code := self class asString:aCode. |
|
403 |
|
404 code notNil ifTrue:[ |
|
405 evaluator := selInstVar class evaluatorClass. |
|
406 successFg := true. |
|
407 |
|
408 evaluator notNil ifTrue:[ |
|
409 result := evaluator evaluate:code |
|
410 in:nil |
|
411 receiver:selInstVar |
|
412 notifying:aView |
|
413 logged:true |
|
414 ifFail:[successFg := false]. |
|
415 |
|
416 successFg ifTrue:[ |
|
417 self update. |
|
418 ^ result |
|
419 ] |
425 ] |
420 ] |
426 ]. |
421 ] |
427 aNrOrNil > instanceNames size ifFalse:[selection := aNrOrNil] |
422 ]. |
428 ifTrue:[selection := nil] |
423 ^ #Error. |
429 ] |
424 |
430 |
425 |
|
426 ! |
|
427 |
|
428 inspect:anObject |
|
429 "inspect a new instance; update contents |
|
430 " |
|
431 |varNamesSize| |
|
432 |
|
433 selection := nil. |
|
434 |
|
435 anObject == inspectedObject ifFalse:[ |
|
436 inspectedObject := anObject. |
|
437 |
|
438 (self class isDirectory:inspectedObject) ifFalse:[ |
|
439 instanceNames := OrderedCollection new. |
|
440 instanceTypes := OrderedCollection new. |
|
441 ] ifTrue:[ |
|
442 instanceNames := inspectedObject class allInstVarNames. |
|
443 varNamesSize := instanceNames size. |
|
444 instanceTypes := OrderedCollection new:varNamesSize. |
|
445 |
|
446 1 to:varNamesSize do:[:i| |
|
447 (self class isDirectory:(inspectedObject instVarAt:i)) ifTrue:[ |
|
448 instanceTypes add:#directory |
|
449 ] ifFalse:[ |
|
450 instanceTypes add:#normal |
|
451 ] |
|
452 ]. |
|
453 ] |
|
454 ]. |
|
455 self update |
431 ! ! |
456 ! ! |
432 |
457 |
433 !InspectorList class methodsFor:'documentation'! |
458 !InspectorList class methodsFor:'documentation'! |
434 |
459 |
435 version |
460 version |