diff -r ce09771c85a9 -r a25d288252f4 DoWhatIMeanSupport.st --- a/DoWhatIMeanSupport.st Tue May 17 00:01:55 2016 +0200 +++ b/DoWhatIMeanSupport.st Tue May 17 00:06:48 2016 +0200 @@ -1870,7 +1870,7 @@ |selector lcSelector bestSelectors parentSelector newParentSelector bestSelectors2 bestWithParenthesis allBest numArgs newParts nSelParts oldLen newLen selectorParts - findBest parentNode nodeReceiver "selectorsSentInCode" selectorsImplementedInClass + parentNode nodeReceiver "selectorsSentInCode" selectorsImplementedInClass editAction parentNodeClassIfKnown receiverNodeClassIfKnown offerParenthisationAroundNode parenthesisAroundIndex parentNodeToParenthesize @@ -1878,71 +1878,14 @@ classesFromAssignmentsToReceiver otherMessagesToReceiver canParenthesize classesOfReceiver| - "/ Transcript show:'node '; show:node; show:' ; '. - "/ Transcript show:'msg in '; show:methodOrNil; show:' / '; showCR:classOrNil. - + Verbose == true ifTrue:[ + Transcript show:'node '; show:node; show:' ; '. + Transcript show:'msg in '; show:methodOrNil; show:' / '; showCR:classOrNil. + ]. + offerParenthisationAroundNode := nil. offerValueInsertion := false. - "/ node at:1 - - findBest := - [:node :selector | - |srchClasses bestSelectors bestPrefixes - allMessagesSentToVariable classesImplementingAllMessages| - - srchClasses := node==nodeReceiver - ifTrue:[classesOfReceiver] - ifFalse:[self classesOfNode:node]. - - srchClasses isEmptyOrNil ifTrue:[ - node isVariable ifTrue:[ - allMessagesSentToVariable := Set new. - rememberedNodes do:[:eachNode | - eachNode allMessageNodesDo:[:eachMessage | - |msgReceiver msgSelector| - - (msgReceiver := eachMessage receiver) isVariable ifTrue:[ - msgReceiver name = node name ifTrue:[ - (msgSelector := eachMessage selector) ~= selector ifTrue:[ - allMessagesSentToVariable add:msgSelector - ] - ] - ] - ] - ]. - allMessagesSentToVariable notEmpty ifTrue:[ - "/ consider classes which implement all those messages. - classesImplementingAllMessages := Smalltalk allImplementorsOf:(allMessagesSentToVariable first). - allMessagesSentToVariable do:[:eachSelector | - classesImplementingAllMessages := classesImplementingAllMessages - select:[:cls | cls implements:eachSelector]. - ]. - srchClasses := classesImplementingAllMessages. - ]. - ]. - ]. - bestSelectors := Set new. - srchClasses isEmptyOrNil ifTrue:[ - bestSelectors addAll:( Parser findBest:50 selectorsFor:selector in:nil forCompletion:true ). - ] ifFalse:[ - srchClasses do:[:srchClass | - |bestForThisClass| - - bestForThisClass := Parser findBest:50 selectorsFor:selector in:srchClass forCompletion:true. - bestForThisClass := self - withoutSelectorsUnlikelyFor:srchClass - from:bestForThisClass - forPartial:selector. - bestSelectors addAll:bestForThisClass. - ]. - ]. - "/ remove the already typed-in selector itself, in case. - bestSelectors remove:selector ifAbsent:[]. - bestSelectors := bestSelectors asOrderedCollection. - bestSelectors - ]. - selector := node selector. lcSelector := selector asLowercase. parentNode := node parent. @@ -1950,9 +1893,11 @@ nodeReceiver notNil ifTrue:[ classesOfReceiver := self classesOfNode:nodeReceiver. ]. -Transcript show:node; show:' -> '; showCR:classesOfReceiver. -( node isVariable and:[node name = 'self']) ifTrue:[self halt]. - + Verbose == true ifTrue:[ + Transcript show:node; show:' -> '; showCR:classesOfReceiver. + ( node isVariable and:[node name = 'self']) ifTrue:[self halt]. + ]. + "/ if there is already space before the cursor, and the parent node is not a message, "/ do not attempt to complete the current message. "/ If it is a message, we will look for parent-message completion also below (best2 stuff) @@ -1965,7 +1910,11 @@ "/ only do this if the node-message has no parents around node parentheses isEmptyOrNil ifTrue:[ - bestSelectors := findBest value:nodeReceiver value:selector. + Verbose == true ifTrue:[ + Transcript show:'try for: '; showCR:nodeReceiver + ]. + bestSelectors := self findBest:nodeReceiver for:selector + inClasses:classesOfReceiver ] ifFalse:[ bestSelectors := OrderedCollection new. ]. @@ -2097,7 +2046,9 @@ "/ if its a unary message AND the parent is a keyword node, look for parent completion too. "/ i.e. look if there is a longer keyword possible newParentSelector := parentSelector,selector. - bestSelectors2 := findBest value:(parentNode receiver) value:newParentSelector. + bestSelectors2 := self + findBest:(parentNode receiver) for:newParentSelector + inClasses:(self classesOfNode:parentNode receiver). bestSelectors2 := bestSelectors2 select:[:sel | sel isKeyword and:[ sel startsWith:parentSelector]]. bestSelectors2 := bestSelectors2 asOrderedCollection sort:[:a :b | a size < b size]. bestSelectors := bestSelectors reject:[:sel | bestSelectors2 includes:sel]. @@ -2145,7 +2096,9 @@ "/ (i.e. into foo == shift <- more "/ or into foo bar <- baz codeView characterPositionOfCursor >= parentNode stop ifTrue:[ - kwSels := findBest value:parentNode value:selector. + kwSels := self + findBest:parentNode for:selector + inClasses:(self classesOfNode:parentNode). kwSels := kwSels select:[:sel | sel isKeyword]. kwSels := kwSels asOrderedCollection sort:[:a :b | a size < b size]. @@ -3774,6 +3727,70 @@ "Created: / 01-05-2016 / 18:44:09 / cg" ! +findBest:node for:selector inClasses:srchClassesArg + |srchClasses bestSelectors + allMessagesSentToVariable classesImplementingAllMessages| + + srchClasses := srchClassesArg. + Verbose == true ifTrue:[ + Transcript show:'node: '; showCR:node. + Transcript show:'srchClasses: '; showCR:srchClasses. + ]. + + srchClasses isEmptyOrNil ifTrue:[ + node isVariable ifTrue:[ + allMessagesSentToVariable := Set new. + rememberedNodes do:[:eachNode | + eachNode allMessageNodesDo:[:eachMessage | + |msgReceiver msgSelector| + + (msgReceiver := eachMessage receiver) isVariable ifTrue:[ + msgReceiver name = node name ifTrue:[ + (msgSelector := eachMessage selector) ~= selector ifTrue:[ + allMessagesSentToVariable add:msgSelector + ] + ] + ] + ] + ]. + allMessagesSentToVariable notEmpty ifTrue:[ + "/ consider classes which implement all those messages. + classesImplementingAllMessages := Smalltalk allImplementorsOf:(allMessagesSentToVariable first). + allMessagesSentToVariable do:[:eachSelector | + classesImplementingAllMessages := classesImplementingAllMessages + select:[:cls | cls implements:eachSelector]. + ]. + srchClasses := classesImplementingAllMessages. + ]. + ]. + ]. + bestSelectors := Set new. + srchClasses isEmptyOrNil ifTrue:[ + bestSelectors addAll:( Parser findBest:50 selectorsFor:selector in:nil forCompletion:true ). + Verbose == true ifTrue:[ + Transcript show:'bestSelectors (1): '; showCR:bestSelectors. + ]. + ] ifFalse:[ + srchClasses do:[:srchClass | + |bestForThisClass| + + bestForThisClass := Parser findBest:50 selectorsFor:selector in:srchClass forCompletion:true. + bestForThisClass := self + withoutSelectorsUnlikelyFor:srchClass + from:bestForThisClass + forPartial:selector. + Verbose == true ifTrue:[ + Transcript show:'bestSelectors (2): '; showCR:bestForThisClass. + ]. + bestSelectors addAll:bestForThisClass. + ]. + ]. + "/ remove the already typed-in selector itself, in case. + bestSelectors remove:selector ifAbsent:[]. + bestSelectors := bestSelectors asOrderedCollection. + ^ bestSelectors +! + findNodeForInterval:interval in:source |tree node| @@ -4601,7 +4618,7 @@ I have currently no better idea than hardcoding stuff I found irritating..." |selectors noNilChecks noIsXXXChecks noNoXXXChecks noBecome - noIndexedSetters noIndexedGetters noSizeQueries| + noIndexedSetters noIndexedGetters noSizeQueries docSelectors| aClass isNil ifTrue:[ ^ selectorsArg ]. @@ -4612,6 +4629,12 @@ self tracePoint:#cg message:aClass. + aClass isMeta ifTrue:[ + docSelectors := #(copyright documentation examples + version version_CVS version_SVN version_HG). + selectors := selectors reject:[:sel | docSelectors includes:sel]. + ]. + "/ actually meaning booleans here (aClass == True or:[aClass == False]) ifTrue:[ noNilChecks := noBecome := true.