cg@809: " cg@809: COPYRIGHT (c) 1997 by eXept Software AG cg@809: All Rights Reserved cg@809: cg@809: This software is furnished under a license and may be used cg@809: only in accordance with the terms of that license and with the cg@809: inclusion of the above copyright notice. This software may not cg@809: be provided or otherwise made available to, or used by, any cg@809: other person. No title to or ownership of the software is cg@809: hereby transferred. cg@809: " cg@809: cg@809: ca@33: "{ NameSpace: NewInspector }" ca@33: cg@1213: Object subclass:#NewInspectorList ca@33: instanceVariableNames:'inspectedObject instanceNames instanceTypes selection' ca@33: classVariableNames:'' ca@33: poolDictionaries:'' cg@1213: category:'Interface-NewInspector' ca@33: ! ca@33: cg@1213: !NewInspectorList class methodsFor:'documentation'! cg@809: cg@809: copyright cg@809: " cg@809: COPYRIGHT (c) 1997 by eXept Software AG cg@809: All Rights Reserved cg@809: cg@809: This software is furnished under a license and may be used cg@809: only in accordance with the terms of that license and with the cg@809: inclusion of the above copyright notice. This software may not cg@809: be provided or otherwise made available to, or used by, any cg@809: other person. No title to or ownership of the software is cg@809: hereby transferred. cg@809: " cg@809: cg@809: ! ! ca@33: cg@1213: !NewInspectorList class methodsFor:'instance creation'! ca@33: ca@33: for:anObject ca@33: "create a new list for an instance ca@33: " ca@38: ^ self new inspect:anObject ca@38: ca@38: ca@38: ! ca@38: ca@38: new ca@38: "create a new instance and set the inspected object to nil ca@38: " ca@38: ^ self basicNew initialize. ca@38: ca@38: ! ! ca@38: cg@1213: !NewInspectorList class methodsFor:'helpers'! ca@38: ca@38: asString:aCollection ca@38: "converts any collection to a string seperated by spaces. If ca@38: the collection is empty or nil, nil is returned otherwise a ca@38: string. ca@38: " ca@38: |string| ca@38: ca@38: aCollection isCollection ifTrue:[ ca@38: aCollection isString ifTrue:[ ca@38: string := aCollection ca@38: ] ifFalse:[ ca@38: string := aCollection asStringWith:Character space ca@38: from:1 to:(aCollection size) ca@38: compressTabs:true ca@38: final:nil ca@38: ]. ca@38: string := string withoutSeparators. ca@38: ca@38: string notEmpty ifTrue:[ ca@38: ^ string ca@38: ] ca@38: ]. ca@38: ^ nil ca@33: ca@33: ca@33: ! ! ca@33: cg@1213: !NewInspectorList class methodsFor:'testing'! ca@33: ca@33: isDirectory:anInstance ca@38: "returns true if the instance is a directory ca@33: " ca@33: |cls| ca@33: ca@33: anInstance notNil ifTrue:[ ca@33: cls := anInstance class. ca@33: ca@33: cls == Character ifTrue:[ ^ false ]. ca@33: cls == Symbol ifTrue:[ ^ false ]. ca@33: cls == String ifTrue:[ ^ false ]. cg@1022: cls == Float ifTrue:[ ^ false ]. cg@1022: cls == ShortFloat ifTrue:[ ^ false ]. ca@33: ca@33: cls allInstVarNames notEmpty ifTrue:[ ca@33: ^ true ca@33: ]. ca@33: ca@33: anInstance isVariable ifTrue:[ ca@33: ^ true ca@33: ]. ca@33: ]. ca@33: ^ false ca@33: cg@1022: "Modified: / 4.2.1999 / 20:00:11 / cg" ca@38: ! ca@38: ca@38: isTraceable:anInstance ca@38: "returns true if the instance could be traced or traped ca@38: " ca@38: |cls| ca@38: ca@38: anInstance notNil ifTrue:[ ca@38: cls := anInstance class. ca@38: ca@38: ^ ( cls ~~ True ca@38: and:[cls ~~ False ca@38: and:[cls ~~ SmallInteger]] ca@38: ) ca@38: ]. ca@38: ^ false. ca@38: ca@33: ! ! ca@33: cg@1213: !NewInspectorList methodsFor:'accessing'! ca@33: ca@33: includesSelf:aBoolean ca@33: "includes 'self' dependant on the boolean ca@33: " ca@33: (self includesSelf) ~~ aBoolean ifTrue:[ ca@33: aBoolean ifTrue:[ ca@33: instanceNames addFirst:'self'. ca@33: instanceTypes addFirst:#self. ca@33: ca@38: selection notNil ifTrue:[selection := selection + 1] ca@38: ifFalse:[selection := 1] ca@38: ca@33: ] ifFalse:[ ca@33: instanceNames removeFirst. ca@33: instanceTypes removeFirst. ca@33: ca@33: selection isNil ifFalse:[ ca@33: (selection := selection - 1) == 0 ifTrue:[ ca@33: selection := nil ca@33: ] ca@33: ] ca@33: ] ca@33: ] ca@33: ca@33: ca@33: ! ca@33: ca@38: list ca@38: "returns self ca@38: " ca@38: ^ self ca@38: ! ca@38: ca@33: size ca@38: "returns size of list ca@33: " ca@33: ^ instanceNames size ca@33: ca@38: ! ca@38: ca@38: update ca@38: "update list contents ca@38: " ca@38: |start stop size| ca@38: ca@38: inspectedObject isVariable ifTrue:[ ca@38: start := instanceNames findFirst:[:el|(el at:1) isDigit]. ca@38: stop := instanceTypes size. ca@38: ca@38: start == 0 ifTrue:[ ca@38: size := stop + 10. "must be > 1: force a resize the first time" ca@38: ] ifFalse:[ ca@38: instanceTypes last ~~ #grow ifTrue:[size := stop] ca@38: ifFalse:[size := stop-1]. ca@38: ca@38: instanceTypes removeFromIndex:start toIndex:stop. ca@38: instanceNames removeFromIndex:start toIndex:stop. ca@38: ]. ca@38: self resizeTo:size. ca@38: ] cg@1022: cg@1022: "Modified: / 4.2.1999 / 20:00:38 / cg" ca@33: ! ! ca@33: cg@1213: !NewInspectorList methodsFor:'accessing contents'! ca@33: ca@33: inspectedObject ca@33: "returns current inspected object ca@33: " ca@33: ^ inspectedObject ca@33: ca@33: ca@33: ! ca@33: ca@33: instanceNames ca@33: "returns list of instance names ca@33: " ca@33: ^ instanceNames ca@33: ca@33: ca@33: ! ca@33: ca@33: instanceTypeAt:anIndex ca@38: "returns type assigned to the list entry (#directory #normal #self #grow) ca@38: In case of an invalid index nil is returned. ca@33: " ca@38: (anIndex isNil or:[anIndex > instanceTypes size]) ifFalse:[^ instanceTypes at:anIndex] ca@38: ifTrue:[^ nil]. ca@33: ca@33: ca@33: ! ca@33: ca@33: instanceTypes ca@38: "returns list of types (#directory #normal #self #grow) ca@33: " ca@33: ^ instanceTypes ca@33: ca@33: ca@33: ! ca@33: ca@33: instanceVarAt:anIndex ca@38: "returns the instnace variable assigned to the index or ca@38: nil in case of an invalid index. ca@33: " cg@327: |nm| ca@33: ca@38: (anIndex isNil or:[anIndex > instanceTypes size]) ifFalse:[ ca@33: nm := instanceNames at:anIndex. ca@33: ca@33: (nm at:1) isDigit ifFalse:[ ca@33: self includesSelf ifFalse:[ ca@33: ^ inspectedObject instVarAt:anIndex ca@33: ]. ca@33: anIndex == 1 ifFalse:[^ inspectedObject instVarAt:(anIndex-1)] ca@33: ifTrue:[^ inspectedObject] ca@33: ]. ca@33: ^ inspectedObject basicAt:(Number readFrom:nm onError:0) ca@33: ]. ca@33: ^ nil ca@33: ca@33: ca@33: ! ! ca@33: cg@1213: !NewInspectorList methodsFor:'initialization'! ca@33: ca@38: initialize ca@38: "initialize instance attributes ca@33: " ca@38: super initialize. ca@33: ca@38: instanceNames := OrderedCollection new. ca@38: instanceTypes := OrderedCollection new. ca@38: ca@33: ! ! ca@33: cg@1213: !NewInspectorList methodsFor:'private'! ca@33: ca@38: resizeTo:aNumber ca@38: "resize list to minimum aNumber ca@33: " ca@38: |lstVarId basicSize newLastId obj instSize| ca@33: ca@33: (inspectedObject isVariable and:[self class isDirectory:inspectedObject]) ifFalse:[ ca@33: ^ self ca@33: ]. ca@33: ca@38: instanceTypes size == 0 ifTrue:[ ca@38: lstVarId := 0 ca@38: ] ifFalse:[ ca@38: instSize := inspectedObject class instSize. ca@33: ca@38: instanceTypes first == #self ifTrue:[ ca@38: instSize := instSize + 1 ca@38: ]. ca@33: instanceTypes last == #grow ifTrue:[ ca@33: instanceNames removeLast. " .. " ca@33: instanceTypes removeLast. " #grow " ca@38: ]. ca@38: lstVarId := instanceTypes size - instSize. ca@38: ]. ca@38: ca@38: (basicSize := inspectedObject basicSize) == lstVarId ifTrue:[ ca@38: ^ self ca@38: ]. ca@38: newLastId := (1 bitShift:((aNumber-1) highBit)) max:128. ca@38: ca@38: (newLastId + 64) > basicSize ifTrue:[ ca@38: newLastId := basicSize ca@33: ]. ca@33: ca@33: [lstVarId ~~ newLastId] whileTrue:[ ca@33: lstVarId := lstVarId + 1. ca@33: obj := inspectedObject basicAt:lstVarId. ca@33: ca@33: (self class isDirectory:obj) ifTrue:[instanceTypes add:#directory] ca@33: ifFalse:[instanceTypes add:#normal]. ca@33: ca@33: instanceNames add:(lstVarId printString, ' ', obj class name printString). ca@33: ]. ca@33: ca@33: lstVarId ~~ basicSize ifTrue:[ ca@33: instanceNames add:'..'. ca@33: instanceTypes add:#grow ca@33: ]. ca@33: ! ! ca@33: cg@1213: !NewInspectorList methodsFor:'selections'! ca@33: ca@33: selectedInstanceType ca@38: "returns type assigned to the selected list entry (#directory #normal #self #grow). ca@38: In case of no selection nil is returned. ca@33: " ca@33: ^ self instanceTypeAt:selection ca@33: ca@33: ca@33: ! ca@33: ca@33: selectedInstanceVar ca@33: "returns current inspected instance variable or nil ca@33: " ca@33: ^ self instanceVarAt:selection ca@33: ca@33: ca@33: ! ca@33: ca@33: selection ca@33: "returns current selection number or nil ca@33: " ca@33: ^ selection ca@33: ca@33: ca@33: ! ca@33: ca@38: setSelection:aNrOrNil ca@38: "change current selection to a number or nil; may resize the lists ca@38: " ca@38: selection := aNrOrNil. ca@38: ca@38: (selection isNil or:[instanceTypes size > selection]) ifFalse:[ ca@38: self resizeTo:selection. ca@38: ca@38: selection > instanceTypes size ifTrue:[ ca@38: selection := nil ca@38: ] ca@38: ] ca@38: ! ! ca@38: cg@1213: !NewInspectorList methodsFor:'testing'! ca@38: ca@38: includesSelf ca@38: "returns true if 'self' is included in the list ca@38: " ca@38: ^ (instanceTypes notEmpty and:[instanceTypes first == #self]) ca@38: ca@38: ca@38: ! ca@38: ca@38: isEmpty ca@38: "returns true if the list is empty ca@33: " ca@38: ^ instanceNames isEmpty ca@38: ca@38: ! ca@38: ca@38: notEmpty ca@38: "returns true if the list is not empty ca@38: " ca@38: ^ instanceNames notEmpty ca@38: ca@38: ! ! ca@38: cg@1213: !NewInspectorList methodsFor:'user interaction'! ca@38: ca@38: accept:aText notifying:aView ca@38: "evaluating aText on the selected instance var; if an error occurs #Error ca@38: is returned otherwise the inspected object instance. On success the list ca@38: will be updated. ca@38: " ca@38: |text slNr value| ca@38: ca@38: selection notNil ifTrue:[ ca@38: text := self class asString:aText. ca@38: ca@38: text notNil ifTrue:[ ca@38: self includesSelf ifFalse:[slNr := selection] ca@38: ifTrue:[slNr := selection-1]. ca@38: ca@38: value := inspectedObject class evaluatorClass ca@38: evaluate:text ca@38: receiver:inspectedObject ca@38: notifying:aView. ca@33: ca@38: slNr ~~ 0 ifTrue:[ ca@38: (inspectedObject class isVariable) ifFalse:[ ca@38: inspectedObject instVarAt:slNr put:value ca@38: ] ifTrue:[ ca@38: slNr <= (inspectedObject class instSize) ifTrue:[ ca@38: inspectedObject instVarAt:slNr put:value ca@38: ] ifFalse:[ ca@38: slNr := slNr - inspectedObject class instSize. ca@38: inspectedObject basicAt:slNr put:value ca@38: ] ca@38: ] ca@38: ]. ca@38: inspectedObject changed. ca@38: self update. ca@38: ^ inspectedObject ca@38: ] ca@38: ]. ca@38: ^ #Error ca@38: ! ca@38: ca@38: doIt:aCode notifying:aView ca@38: "evaluating aCode on the selected instance var; if an error occurs #Error ca@38: is returned otherwise the result returned from the evaluator. On success ca@38: the list will be updated. ca@38: " ca@38: |successFg result evaluator selInstVar code| ca@38: ca@38: selInstVar := self selectedInstanceVar. ca@38: ca@38: selInstVar notNil ifTrue:[ ca@38: code := self class asString:aCode. ca@38: ca@38: code notNil ifTrue:[ ca@38: evaluator := selInstVar class evaluatorClass. ca@38: successFg := true. ca@33: ca@38: evaluator notNil ifTrue:[ ca@38: result := evaluator evaluate:code ca@38: in:nil ca@38: receiver:selInstVar ca@38: notifying:aView ca@38: logged:true ca@38: ifFail:[successFg := false]. ca@38: ca@38: successFg ifTrue:[ ca@38: self update. ca@38: ^ result ca@38: ] ca@33: ] ca@38: ] ca@38: ]. ca@38: ^ #Error. ca@38: ca@38: ca@38: ! ca@38: ca@38: inspect:anObject ca@38: "inspect a new instance; update contents ca@38: " ca@38: |varNamesSize| ca@38: ca@38: selection := nil. ca@38: ca@38: anObject == inspectedObject ifFalse:[ ca@38: inspectedObject := anObject. ca@33: ca@38: (self class isDirectory:inspectedObject) ifFalse:[ ca@38: instanceNames := OrderedCollection new. ca@38: instanceTypes := OrderedCollection new. ca@38: ] ifTrue:[ ca@38: instanceNames := inspectedObject class allInstVarNames. ca@38: varNamesSize := instanceNames size. ca@38: instanceTypes := OrderedCollection new:varNamesSize. ca@38: ca@38: 1 to:varNamesSize do:[:i| ca@38: (self class isDirectory:(inspectedObject instVarAt:i)) ifTrue:[ ca@38: instanceTypes add:#directory ca@38: ] ifFalse:[ ca@38: instanceTypes add:#normal ca@38: ] ca@38: ]. ca@38: ] ca@38: ]. ca@38: self update ca@33: ! ! ca@33: cg@1213: !NewInspectorList class methodsFor:'documentation'! ca@33: ca@33: version ca@33: ^ '$Header$' ca@33: ! !