DoWhatIMeanSupport.st
changeset 4366 8041b628bba3
parent 4365 fda4ed5a9772
child 4367 dd00d1570f88
--- a/DoWhatIMeanSupport.st	Tue Sep 03 02:56:10 2013 +0200
+++ b/DoWhatIMeanSupport.st	Tue Sep 03 11:32:02 2013 +0200
@@ -1613,7 +1613,8 @@
     |selector srchClass implClass 
      bestSelectors selector2 bestSelectors2 allBest best info numArgs
      newParts nSelParts oldLen newLen selectorParts 
-     findBest parentNode selectorsSentInCode split editAction parentNodeClassIfKnown|
+     findBest parentNode selectorsSentInCode split editAction parentNodeClassIfKnown 
+     otherMessagesToReceiver possibleClasses|
 
     "/ Transcript show:'msg in '; show:methodOrNil; show:' / '; showCR:classOrNil.
 
@@ -1639,9 +1640,9 @@
     selector := node selector.
     parentNode := node parent.
 
-    "/ if there is already space before the cursor, do not attempty to complete the
-    "/ current message. Instead, look for a parent keyword message.
-    "/ is this a good idea? (could be that we want to see possible arguments for the kw message)
+    "/ if there is already space before the cursor, and the parent node is not a message,
+    "/ do not attempty to complete the current message.
+    "/ If it is a message, we will look for parent-message completion also below (best2 stuff)
     (codeView characterBeforeCursor ? $ ) isSeparator ifTrue:[
         (parentNode notNil and:[ parentNode isMessage ]) ifFalse:[
             ^ self.
@@ -1650,6 +1651,30 @@
 
     bestSelectors := findBest value:node receiver value:selector.
 
+    "/ if the receiver is a variable, we can look for other messages being sent to
+    "/ that variable
+    (tree notNil and:[ node receiver isVariable ])
+    ifTrue:[
+        otherMessagesToReceiver := tree allMessageNodes 
+                                    select:[:eachMessageNode | 
+                                        node receiver = eachMessageNode receiver
+                                        and:[ selector ~= eachMessageNode selector]]
+                                    thenCollect:[:eachNode | eachNode selector].
+        possibleClasses := Smalltalk allClassesForWhich:[:cls |
+                            otherMessagesToReceiver conform:[:eachSelectorSent | cls canUnderstand:eachSelectorSent]].
+        possibleClasses := possibleClasses select:[:cls | cls isLoaded].
+        (possibleClasses notEmpty and:[possibleClasses size < 10]) ifTrue:[
+            bestSelectors := Set new.
+            possibleClasses do:[:eachClass |
+                |bestSelectorsForClass|
+
+                bestSelectorsForClass := Parser findBest:30 selectorsFor:selector in:eachClass forCompletion:true.
+                bestSelectors addAll:bestSelectorsForClass. 
+            ].
+            bestSelectors := bestSelectors asOrderedCollection
+        ].
+    ].
+
     "/ if we are behind a keyword messages colon,
     "/ only look for matching prefix selectors;
     "/ also, a good completion is to insert an argument;
@@ -2188,7 +2213,7 @@
      allVariables allDistances variablesAlreadyAdded nodeVal
      char oldLen newLen 
      getDistanceComputeBlockWithWeight addWithFactorBlock names allTheBest bestAssoc
-     globalFactor localFactor selectorOfMessageToNode tree2 implementors argIdx namesUsed kwPart
+     globalFactor localFactor selectorOfMessageToNode implementors argIdx namesUsed kwPart
      editAction suggestions nameIsOK longerNames|
 
     "/ Transcript show:'var in '; show:methodOrNil; show:' / '; showCR:classOrNil.
@@ -2331,14 +2356,6 @@
         names := OrderedCollection withAll:node allVariablesOnScope.
 
         (names isEmpty or:[rememberedScopeNodes notNil]) ifTrue:[
-"/            "/ if there were no variables (due to a parse error)
-"/            "/ do another parse and see what we have
-"/            tree2 := self treeForCode:(codeView contentsAsString string) allowErrors:true.
-"/            "/ better if we already have a body (include locals then)
-"/            "/ otherwise, only the arguments are considered
-"/            tree2 notNil ifTrue:[
-"/                names := (tree body ? tree) allVariablesOnScope.
-"/            ].
             rememberedScopeNodes notNil ifTrue:[
                 rememberedScopeNodes do:[:each |
                     (each isMethod or:[each isBlock]) ifTrue:[
@@ -2355,8 +2372,8 @@
                     ]
                 ]
             ].
-            addWithFactorBlock value:names value:(4 * localFactor).
         ].
+        addWithFactorBlock value:names value:(4 * localFactor).
 
         classOrNil notNil ifTrue:[
             "/ instance variables
@@ -2468,6 +2485,13 @@
             "/ globals
             names := Smalltalk keys.
             names := names select:[:nm | nm isUppercaseFirst ].
+            "/ only consider all globals, if the first char of the completed name is uppercase;
+            "/ otherwise, only consider names with a caseInsensitve prefix match
+            nm first isUppercase ifTrue:[
+                
+            ] ifFalse:[
+                names := names select:[:globalName | globalName asLowercase startsWith: nm].
+            ].
             addWithFactorBlock value:names value:(1.5 * globalFactor).
         ].
 
@@ -3722,10 +3746,10 @@
 !DoWhatIMeanSupport class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/DoWhatIMeanSupport.st,v 1.137 2013-09-03 00:56:10 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/DoWhatIMeanSupport.st,v 1.138 2013-09-03 09:32:02 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libwidg2/DoWhatIMeanSupport.st,v 1.137 2013-09-03 00:56:10 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/DoWhatIMeanSupport.st,v 1.138 2013-09-03 09:32:02 cg Exp $'
 ! !