diff -r 8277d17c3e50 -r 976ed2a22e27 DoWhatIMeanSupport.st --- 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. + ]. ]. ].