|
1 "{ NameSpace: NewInspector }" |
|
2 |
|
3 Object subclass:#InspectorList |
|
4 instanceVariableNames:'inspectedObject instanceNames instanceTypes selection' |
|
5 classVariableNames:'' |
|
6 poolDictionaries:'' |
|
7 category:'Inspector' |
|
8 ! |
|
9 |
|
10 |
|
11 !InspectorList class methodsFor:'instance creation'! |
|
12 |
|
13 for:anObject |
|
14 "create a new list for an instance |
|
15 " |
|
16 ^ self basicNew for:anObject |
|
17 |
|
18 |
|
19 ! ! |
|
20 |
|
21 !InspectorList class methodsFor:'testing'! |
|
22 |
|
23 isDirectory:anInstance |
|
24 "returns true if the class is a directory |
|
25 " |
|
26 |cls| |
|
27 |
|
28 anInstance notNil ifTrue:[ |
|
29 cls := anInstance class. |
|
30 |
|
31 cls == Character ifTrue:[ ^ false ]. |
|
32 cls == Symbol ifTrue:[ ^ false ]. |
|
33 cls == String ifTrue:[ ^ false ]. |
|
34 |
|
35 cls allInstVarNames notEmpty ifTrue:[ |
|
36 ^ true |
|
37 ]. |
|
38 |
|
39 anInstance isVariable ifTrue:[ |
|
40 ^ true |
|
41 ]. |
|
42 ]. |
|
43 ^ false |
|
44 |
|
45 |
|
46 ! ! |
|
47 |
|
48 !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 |
|
58 includesSelf:aBoolean |
|
59 "includes 'self' dependant on the boolean |
|
60 " |
|
61 (self includesSelf) ~~ aBoolean ifTrue:[ |
|
62 aBoolean ifTrue:[ |
|
63 instanceNames addFirst:'self'. |
|
64 instanceTypes addFirst:#self. |
|
65 |
|
66 selection isNil ifTrue:[selection := 1] |
|
67 ifFalse:[selection := selection + 1] |
|
68 ] ifFalse:[ |
|
69 instanceNames removeFirst. |
|
70 instanceTypes removeFirst. |
|
71 |
|
72 selection isNil ifFalse:[ |
|
73 (selection := selection - 1) == 0 ifTrue:[ |
|
74 selection := nil |
|
75 ] |
|
76 ] |
|
77 ] |
|
78 ] |
|
79 |
|
80 |
|
81 ! |
|
82 |
|
83 size |
|
84 "returns current list size |
|
85 " |
|
86 ^ instanceNames size |
|
87 |
|
88 ! ! |
|
89 |
|
90 !InspectorList methodsFor:'accessing contents'! |
|
91 |
|
92 inspectedObject |
|
93 "returns current inspected object |
|
94 " |
|
95 ^ inspectedObject |
|
96 |
|
97 |
|
98 ! |
|
99 |
|
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 |
|
120 "returns list of instance names |
|
121 " |
|
122 ^ instanceNames |
|
123 |
|
124 |
|
125 ! |
|
126 |
|
127 instanceTypeAt:anIndex |
|
128 "returns type assigned to the list entry (#directory #normal #self) |
|
129 " |
|
130 (anIndex notNil and:[anIndex <= instanceTypes size]) ifTrue:[ |
|
131 ^ instanceTypes at:anIndex |
|
132 ]. |
|
133 ^ nil |
|
134 |
|
135 |
|
136 ! |
|
137 |
|
138 instanceTypes |
|
139 "returns list of types (#directory #normal #self) |
|
140 " |
|
141 ^ instanceTypes |
|
142 |
|
143 |
|
144 ! |
|
145 |
|
146 instanceVarAt:anIndex |
|
147 "returns the instnace variable assigned to the index |
|
148 " |
|
149 |idx nm| |
|
150 |
|
151 (anIndex notNil and:[anIndex <= instanceTypes size]) ifTrue:[ |
|
152 nm := instanceNames at:anIndex. |
|
153 |
|
154 (nm at:1) isDigit ifFalse:[ |
|
155 self includesSelf ifFalse:[ |
|
156 ^ inspectedObject instVarAt:anIndex |
|
157 ]. |
|
158 anIndex == 1 ifFalse:[^ inspectedObject instVarAt:(anIndex-1)] |
|
159 ifTrue:[^ inspectedObject] |
|
160 ]. |
|
161 ^ inspectedObject basicAt:(Number readFrom:nm onError:0) |
|
162 ]. |
|
163 ^ nil |
|
164 |
|
165 |
|
166 ! ! |
|
167 |
|
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'! |
|
236 |
|
237 for:anObject |
|
238 "setup a new instance |
|
239 " |
|
240 |varNamesSize| |
|
241 |
|
242 inspectedObject := anObject. |
|
243 selection := nil. |
|
244 |
|
245 (self class isDirectory:inspectedObject) ifTrue:[ |
|
246 instanceNames := inspectedObject class allInstVarNames. |
|
247 varNamesSize := instanceNames size. |
|
248 instanceTypes := OrderedCollection new:varNamesSize. |
|
249 |
|
250 1 to:varNamesSize do:[:i| |
|
251 (self class isDirectory:(inspectedObject instVarAt:i)) ifTrue:[ |
|
252 instanceTypes add:#directory |
|
253 ] ifFalse:[ |
|
254 instanceTypes add:#normal |
|
255 ] |
|
256 ] |
|
257 ] ifFalse:[ |
|
258 instanceNames := OrderedCollection new. |
|
259 instanceTypes := OrderedCollection new. |
|
260 ]. |
|
261 self update. |
|
262 ! ! |
|
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:[ |
|
308 instanceNames removeLast. " .. " |
|
309 instanceTypes removeLast. " #grow " |
|
310 ] |
|
311 ]. |
|
312 |
|
313 [lstVarId ~~ newLastId] whileTrue:[ |
|
314 lstVarId := lstVarId + 1. |
|
315 obj := inspectedObject basicAt:lstVarId. |
|
316 |
|
317 (self class isDirectory:obj) ifTrue:[instanceTypes add:#directory] |
|
318 ifFalse:[instanceTypes add:#normal]. |
|
319 |
|
320 instanceNames add:(lstVarId printString, ' ', obj class name printString). |
|
321 ]. |
|
322 |
|
323 lstVarId ~~ basicSize ifTrue:[ |
|
324 instanceNames add:'..'. |
|
325 instanceTypes add:#grow |
|
326 ]. |
|
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 ! ! |
|
373 |
|
374 !InspectorList methodsFor:'selections'! |
|
375 |
|
376 selectedInstanceName |
|
377 "returns name of current selection or nil |
|
378 " |
|
379 ^ self instanceNameAt:selection |
|
380 |
|
381 |
|
382 ! |
|
383 |
|
384 selectedInstanceType |
|
385 "returns type of current selection or nil |
|
386 " |
|
387 ^ self instanceTypeAt:selection |
|
388 |
|
389 |
|
390 ! |
|
391 |
|
392 selectedInstanceVar |
|
393 "returns current inspected instance variable or nil |
|
394 " |
|
395 ^ self instanceVarAt:selection |
|
396 |
|
397 |
|
398 ! |
|
399 |
|
400 selection |
|
401 "returns current selection number or nil |
|
402 " |
|
403 ^ selection |
|
404 |
|
405 |
|
406 ! |
|
407 |
|
408 selection:aNrOrNil |
|
409 "change current selection to a number or nil; may grow a variable list |
|
410 " |
|
411 |rsz| |
|
412 |
|
413 aNrOrNil isNil ifTrue:[ |
|
414 self includesSelf ifTrue:[selection := 1] |
|
415 ifFalse:[selection := nil] |
|
416 ] ifFalse:[ |
|
417 aNrOrNil >= instanceNames size ifTrue:[ |
|
418 (rsz := self lastVariableId) notNil ifTrue:[ |
|
419 rsz := rsz * 2. |
|
420 |
|
421 rsz < aNrOrNil ifTrue:[ |
|
422 rsz := aNrOrNil |
|
423 ]. |
|
424 self resizeVariableList:rsz |
|
425 ] |
|
426 ]. |
|
427 aNrOrNil > instanceNames size ifFalse:[selection := aNrOrNil] |
|
428 ifTrue:[selection := nil] |
|
429 ] |
|
430 |
|
431 ! ! |
|
432 |
|
433 !InspectorList class methodsFor:'documentation'! |
|
434 |
|
435 version |
|
436 ^ '$Header$' |
|
437 ! ! |