[squeak-dev] The Trunk: Tools-mt.1086.mcz
commits at source.squeak.org
commits at source.squeak.org
Wed Dec 15 14:54:35 UTC 2021
Marcel Taeumel uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-mt.1086.mcz
==================== Summary ====================
Name: Tools-mt.1086
Author: mt
Time: 15 December 2021, 3:54:32.768 pm
UUID: 77c9e2bc-974d-4b4b-ba71-1b4fd6dadff4
Ancestors: Tools-mt.1085
Adds custom inspector for (full) block closures.
Please read the commentary in #doItReceiver to not get over-excited about what you can and cannot do in the inspector's "source code" field and the code pane below.
=============== Diff against Tools-mt.1085 ===============
Item was added:
+ ----- Method: BlockClosure>>inspectorClass (in category '*Tools-Inspector') -----
+ inspectorClass
+
+ ^ BlockClosureInspector!
Item was added:
+ Inspector subclass: #BlockClosureInspector
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Tools-Inspector'!
Item was added:
+ ----- Method: BlockClosureInspector>>bindingOf: (in category 'evaluation') -----
+ bindingOf: aString
+ " See commentary in #doItReceiver. Yes, we cannot evalute the closured bindings by name in the code pane. But we can browse and change the bindings through their inspector fields.
+
+ self object method literalsDo: [:literal |
+ (literal isVariableBinding and: [literal key = aString])
+ ifTrue: [^ literal]].
+ "
+
+ ^ super bindingOf: aString!
Item was added:
+ ----- Method: BlockClosureInspector>>doItReceiver (in category 'evaluation') -----
+ doItReceiver
+ "Overwritten for documentation only. We cannot expose the closured 'self' here because users expect the closure to be the #doItReceiver so that 'self value' can be used to evaluate the block. We can, however, configure the styler to at least style #fieldSource correctly. See #updateStyler:requestor: and #hasBindingOf:.
+
+ Note that you can always debug-it the expression 'self value' to the evaluate parts of the closure."
+
+ ^ super doItReceiver!
Item was added:
+ ----- Method: BlockClosureInspector>>fieldSource (in category 'fields') -----
+ fieldSource
+
+ ^ (self newFieldForType: #code key: #source)
+ name: 'source code' translated; emphasizeName;
+ valueGetter: [:blockClosure | '"{1}"\{2}' withCRs format: {blockClosure outerContext. blockClosure decompile decompileString}]; printValueAsIs;
+ shouldStyleValue: true;
+ yourself!
Item was added:
+ ----- Method: BlockClosureInspector>>hasBindingOf: (in category 'user interface - styling') -----
+ hasBindingOf: aString
+
+ self object method literalsDo: [:literal |
+ (literal isVariableBinding and: [literal key = aString])
+ ifTrue: [^ true]].
+ ^ self object outerContext tempNames includes: aString!
Item was added:
+ ----- Method: BlockClosureInspector>>streamBaseFieldsOn: (in category 'fields - streaming') -----
+ streamBaseFieldsOn: aStream
+
+ super streamBaseFieldsOn: aStream.
+ aStream nextPut: self fieldSource.!
Item was added:
+ ----- Method: BlockClosureInspector>>streamBindingsOn: (in category 'fields - streaming') -----
+ streamBindingsOn: aStream
+
+ | compiledCode tempNames |
+ self flag: #decompile. "mt: Use #to: and #do: instead of #to:do: to avoid inlining to preserve bindings in enumeration block for later decompilation. See InspectorField."
+ (1 to: (compiledCode := self object method) numLiterals) do: [:index |
+ | literal |
+ literal := compiledCode literalAt: index.
+ literal isVariableBinding ifTrue: [
+ aStream nextPut: ((self newFieldForType: #tempVar key: index)
+ name: ('[{1}]' format: {literal key});
+ valueGetter: [:closure | (closure method literalAt: index) value];
+ valueSetter: [:closure :value | (closure method literalAt: index) value: value];
+ yourself)]].
+
+ tempNames := self object outerContext tempNames.
+ "No need to show closured bindings from outerContext. The important temps are already covered in the indexed fields below."
+ "(1 to: tempNames size - self object basicSize) do: [:index |
+ aStream nextPut: ((self newFieldForType: #tempVar key: index)
+ name: ('[{1}]' format: {tempNames at: index});
+ valueGetter: [:closure | closure outerContext tempAt: index];
+ valueSetter: [:closure :value | closure outerContext tempAt: index put: value];
+ yourself)]."
+
+ (1 to: self object basicSize) do: [:index |
+ aStream nextPut: ((self newFieldForType: #tempVar key: index)
+ name: ('[{1}]' format: {tempNames at: index + tempNames size - self object basicSize});
+ valueGetter: [:closure | closure basicAt: index];
+ valueSetter: [:closure :value | closure basicAt: index put: value];
+ yourself)].
+
+
+ "See commentary in #doItReceiver. No need to expose the closured 'self' here because there is already the #receiver instVar.
+
+ fieldReceiver
+ ^ (self newFieldForType: #tempVar key: #receiver)
+ name: '[self]';
+ valueGetter: [:obj | obj receiver];
+ valueSetter: [:obj :value | obj receiver: value];
+ yourself
+ "!
Item was added:
+ ----- Method: BlockClosureInspector>>streamInstanceVariablesOn: (in category 'fields - streaming') -----
+ streamInstanceVariablesOn: aStream
+ "Add (closured) bindings to the list."
+
+ super streamInstanceVariablesOn: aStream.
+ self streamBindingsOn: aStream.!
Item was added:
+ ----- Method: BlockClosureInspector>>updateStyler:requestor: (in category 'user interface - styling') -----
+ updateStyler: aStyler requestor: anObject
+ "Overwritten to let the receiver behave like a Workspace to be asked for #hasBindingOf:."
+
+ super updateStyler: aStyler requestor: anObject.
+ aStyler workspace: self.!
More information about the Squeak-dev
mailing list
|