--- a/DoWhatIMeanSupport.st Thu May 05 17:11:41 2016 +0200
+++ b/DoWhatIMeanSupport.st Fri May 06 04:54:44 2016 +0200
@@ -1841,14 +1841,13 @@
codeCompletionForMessage:node into:actionBlock
"find good completions for a message selector in a message-send node"
- |selector lcSelector srchClass implClass
- bestSelectors parentSelector newParentSelector bestSelectors2 bestWithParenthesis allBest best info numArgs
+ |selector lcSelector bestSelectors parentSelector newParentSelector bestSelectors2 bestWithParenthesis allBest numArgs
newParts nSelParts oldLen newLen selectorParts
findBest parentNode nodeReceiver "selectorsSentInCode" selectorsImplementedInClass
editAction parentNodeClassIfKnown
receiverNodeClassIfKnown
- offerParenthisationAroundNode parenthesisAroundIndex
- parentNodeToParenthesize
+ offerParenthisationAroundNode parenthesisAroundIndex parentNodeToParenthesize
+ offerValueInsertion valueToInsert valueToInsertIndex valueInfo
classesFromAssignmentsToReceiver otherMessagesToReceiver
canParenthesize|
@@ -1856,6 +1855,7 @@
"/ Transcript show:'msg in '; show:methodOrNil; show:' / '; showCR:classOrNil.
offerParenthisationAroundNode := nil.
+ offerValueInsertion := false.
"/ node at:1
@@ -2239,7 +2239,30 @@
]
].
- (allBest isEmptyOrNil and:[bestWithParenthesis isEmptyOrNil]) ifTrue:[
+ "/ another convenient hack;
+ "/ if we have just typed in foo ==
+ "/ and the value of foo is a known literal,
+ "/ offer inserting this literal. This is great in a debugger...
+ ( #(#'==' #'=' #'~=' #'~~') includes:selector ) ifTrue:[
+ |val|
+
+ (val := self valueOfNode:nodeReceiver) notNil ifTrue:[
+ offerValueInsertion := true.
+ valueToInsert := val storeString.
+ nodeReceiver isVariable ifTrue:[
+ valueInfo := ' (current value of %1)' bindWith:nodeReceiver name.
+ ] ifFalse:[
+ valueInfo := ' (current value of expression)'.
+ ].
+ valueInfo := valueInfo withColor:(Color grey).
+ ].
+ ].
+
+ (allBest isEmptyOrNil
+ and:[bestWithParenthesis isEmptyOrNil
+ and:[offerParenthisationAroundNode isNil
+ and:[offerValueInsertion not]]]
+ ) ifTrue:[
^ self
].
@@ -2353,6 +2376,10 @@
allBest := allBest copyWith:( '(',selector,')' ).
parenthesisAroundIndex := allBest size.
].
+ offerValueInsertion ifTrue:[
+ allBest := allBest copyWith:( '... ',(valueToInsert contractTo:30),valueInfo).
+ valueToInsertIndex := allBest size.
+ ].
editAction :=
[:index |
@@ -2387,7 +2414,22 @@
codeView insertString:')' atCharacterPosition:offerParenthisationAroundNode stop+2.
codeView cursorToCharacterPosition:(offerParenthisationAroundNode stop+2); cursorRight.
].
- ]
+ ] ifFalse:[
+ (offerValueInsertion and:[index = valueToInsertIndex]) ifTrue:[
+ "/ for input like:
+ "/ foo ==
+ "/ insert a value
+ "/ i.e.: foo == #someSymbol
+ action :=
+ [
+ codeView characterBeforeCursor isSeparator ifFalse:[
+ codeView insertStringAtCursor:' '.
+ ].
+ codeView insertStringAtCursor:valueToInsert.
+ "/ codeView cursorRight.
+ ].
+ ]
+ ].
].
action isNil ifTrue:[
@@ -3728,8 +3770,10 @@
(node isMethod or:[node isBlock or:[node isSequence]]) ifTrue:[
currentScopeNodes add:node.
] ifFalse:[
- self debuggingCodeFor:#cg is:[
+ true ifTrue: "self debuggingCodeFor:#cg is:"[
+ node isMessage ifTrue:[
Transcript show:node; show:' '; show:node start; show:'->'; showCR:node stop.
+ ].
].
(node intersectsInterval:interval) ifTrue:[
@@ -4817,7 +4861,7 @@
it is a good idea to know what the reveiver's value is.
Sigh - returns nil both if unknown AND if a real nil is there."
- |nodeSelector nodeReceiver isNonDestructive receiverValue method|
+ |nodeSelector nodeReceiver isNonDestructive receiverValue method impl|
aNode isLiteral ifTrue:[
^ aNode value
@@ -4829,7 +4873,7 @@
aNode isMessage ifTrue:[
nodeSelector := aNode selector.
nodeReceiver := aNode receiver.
-
+
"/ some hardwired knowlegde here
classOrNil notNil ifTrue:[
(nodeReceiver isSelf and:[nodeSelector = #'class']) ifTrue:[
@@ -4837,22 +4881,36 @@
].
].
- isNonDestructive := false.
-
- ( #( class theMetaclass theNonMetaclass ) includes:nodeSelector) ifTrue:[
- isNonDestructive := true.
- ] ifFalse:[
- "/ follow non-destructive accessors
- receiverValue := self valueOfNode:nodeReceiver.
- receiverValue notNil ifTrue:[
+ receiverValue := self valueOfNode:nodeReceiver.
+ receiverValue notNil ifTrue:[
+ isNonDestructive := false.
+
+ "/ some are wellknown
+ nodeSelector == #size ifTrue:[
+ "/ mhm - be conservative; someone might have redefined #size
+ impl := receiverValue class whichClassIncludesSelector:nodeSelector.
+ "/ more hardwired stuff.
+ ((impl == Object) or:[(impl == String) or:[impl isSubclassOf:Collection]]) ifTrue:[
+ isNonDestructive := true.
+ ].
+ ].
+
+ ( #( basicSize
+ class theMetaclass theNonMetaclass ) includes:nodeSelector) ifTrue:[
+ isNonDestructive := true.
+ ] ifFalse:[
+ "/ follow non-destructive accessors
method := receiverValue class lookupMethodFor:nodeSelector.
method notNil ifTrue:[
(ParseTreeSearcher methodIsJustReturningSomething:method) ifTrue:[
"/ we can savely call that method to get the current value
- ^ receiverValue perform: nodeSelector.
- ]
+ isNonDestructive := true.
+ ].
].
].
+ isNonDestructive ifTrue:[
+ ^ receiverValue perform: nodeSelector.
+ ].
].
].