Fix in (Smalltalk)CompletionEngine - do not add method twice to completion result.
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 09 May 2014 14:54:07 +0100
changeset 201 9a0df215823a
parent 198 a199868d1eab
child 227 ff9860ceaa07
Fix in (Smalltalk)CompletionEngine - do not add method twice to completion result. When adding methods to resultset, always add only one method PO for "defining" class. Defining class is the top-most class in given types hierarchy that defines the method. For example, if completion type is an Array, then insert PO for Collection>>first instead of SequenceableCollection>>first (that overrides a "definition" in Collection)
Make.proto
SmallSense__CompletionEngine.st
SmallSense__SmalltalkCompletionEngine.st
bc.mak
smallsense.rc
--- a/Make.proto	Fri Apr 11 18:13:54 2014 +0200
+++ b/Make.proto	Fri May 09 14:54:07 2014 +0100
@@ -177,7 +177,7 @@
 $(OUTDIR)SmallSense__PO.$(O) SmallSense__PO.$(H): SmallSense__PO.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/HierarchicalItem.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__ParseTreeIndex.$(O) SmallSense__ParseTreeIndex.$(H): SmallSense__ParseTreeIndex.st $(INCLUDE_TOP)/stx/libbasic/Collection.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/OrderedCollection.$(H) $(INCLUDE_TOP)/stx/libbasic/SequenceableCollection.$(H) $(INCLUDE_TOP)/stx/libbasic/SortedCollection.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__ParseTreeIndexEntry.$(O) SmallSense__ParseTreeIndexEntry.$(H): SmallSense__ParseTreeIndexEntry.st $(INCLUDE_TOP)/stx/libbasic/Magnitude.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
-$(OUTDIR)SmallSense__ParseNodeInspector.$(O) SmallSense__ParseNodeInspector.$(H): SmallSense__ParseNodeInspector.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libwidg2/HierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ParseTreeInspector.$(O) SmallSense__ParseTreeInspector.$(H): SmallSense__ParseTreeInspector.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libwidg2/HierarchicalItem.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__SelectorNode.$(O) SmallSense__SelectorNode.$(H): SmallSense__SelectorNode.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libcomp/ParseNode.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__SettingsAppl.$(O) SmallSense__SettingsAppl.$(H): SmallSense__SettingsAppl.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/AbstractSettingsApplication.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__SmalltalkChecker.$(O) SmallSense__SmalltalkChecker.$(H): SmallSense__SmalltalkChecker.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/lint/SmalllintChecker.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
--- a/SmallSense__CompletionEngine.st	Fri Apr 11 18:13:54 2014 +0200
+++ b/SmallSense__CompletionEngine.st	Fri May 09 14:54:07 2014 +0100
@@ -124,17 +124,17 @@
     Smalltalk allClassesDo:[:class|
         class selectorsAndMethodsDo:[:selector :mthd |             
             (mthd isSynthetic not and:[(filter value: mthd) and:[ matcher value: matchPrefix value: selector]]) ifTrue:[
-                | class skip |
+                | class overridden |
 
                 class := mthd mclass superclass.
-                skip := false.
-                [ skip not and:[class notNil] ] whileTrue:[
+                overridden := false.
+                [ overridden not and:[class notNil] ] whileTrue:[
                     (class methodDictionary includesKey: selector) ifTrue:[
-                        skip := true.
+                        overridden := true.
                     ].
                     class := class superclass.
                 ].
-                skip ifFalse:[
+                overridden ifFalse:[
                     | classes |
 
                     classes := selectors at: selector ifAbsentPut:[ Set new ].
--- a/SmallSense__SmalltalkCompletionEngine.st	Fri Apr 11 18:13:54 2014 +0200
+++ b/SmallSense__SmalltalkCompletionEngine.st	Fri May 09 14:54:07 2014 +0100
@@ -174,8 +174,37 @@
 !
 
 addMethodsForType: type 
-    | classes seen |
+    ^ self addMethodsForType: type stripOff: nil
+
+    "Created: / 26-11-2011 / 17:03:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-05-2014 / 12:51:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsForType: type prefix: prefix stripOff: stripprefix
 
+    type isUnknownType ifFalse:[
+        self addMethodsForType:type stripOff: stripprefix.
+        
+        "/ If the type is union of more than 6 types, then
+        "/ assume that the inferencer is likely wrong.
+        "/ then, if the prefix is at least 3 chars,
+        "/ also add methods with that prefix.
+        
+        ((type classes size > 6) and:[ prefix size > 2 ]) ifTrue:[
+            self addMethodsStartingWith:prefix stripOff: stripprefix
+        ].
+    ] ifTrue:[
+        self addMethodsStartingWith:prefix stripOff: stripprefix  
+    ].
+
+    "Created: / 08-04-2014 / 21:04:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-04-2014 / 09:31:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsForType: type stripOff: stripprefix     
+    | classes seen selector2classesMap |
+
+    selector2classesMap := Dictionary new.
     classes := type classes.
     "/ Hack for Boolean: ifTrue:iFalse: etc are not defined
     "/ in Boolean ?!!?
@@ -207,123 +236,50 @@
 
     seen := Set new.
     classes do: [:each | 
-        | class |
+        | class selector2classMap |
 
         class := each.
-        [ class notNil and:[(seen includes: class) not]] whileTrue: [
+        selector2classMap := Dictionary new.
+
+        "/ Now, special care for Java classes, sigh...
+        (class isMetaclass and:[class theNonMetaclass isJavaClass]) ifTrue:[
             seen add: class.
-            "/ Now, special care for Java classes, sigh...
-            (class isMetaclass and:[class theNonMetaclass isJavaClass]) ifTrue:[
-                class theNonMetaclass selectorsAndMethodsDo: [:selector :met | 
-                    met isStatic ifTrue:[
-                        result add: (MethodPO 
-                                    name: selector
-                                    class: met mclass).
-                    ].
+            class theNonMetaclass selectorsAndMethodsDo: [:selector :met | 
+                met isStatic ifTrue:[
+                    result add: (MethodPO 
+                                name: selector
+                                class: met mclass).
                 ].
-            ] ifFalse:[
+            ].
+        ] ifFalse:[ 
+            [ class notNil and:[(seen includes: class) not]] whileTrue: [
                 class selectorsAndMethodsDo: [:selector :met | 
                     met isSynthetic ifFalse:[
-                        result add: (MethodPO 
-                                    name: selector
-                                    class: met mclass).
+                        (stripprefix isNil or:[ selector size > stripprefix size and:[selector startsWith: stripprefix]]) ifTrue:[
+                            selector2classMap at: selector put: class.
+                        ].
                     ]
                 ].
-            ].
-            class := class superclass.
+                class := class superclass.
+            ]
+        ].
+        selector2classMap keysAndValuesDo:[:selector :class |
+            | classes |    
+
+            classes := selector2classesMap at: selector ifAbsentPut: [ Set new ].
+            classes add: class.
         ]
     ].
 
-    "Created: / 26-11-2011 / 17:03:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 22-01-2014 / 19:48:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-addMethodsForType: type prefix: prefix stripOff: stripprefix
-
-    type isUnknownType ifFalse:[
-        self addMethodsForType:type stripOff: stripprefix.
-        
-        "/ If the type is union of more than 6 types, then
-        "/ assume that the inferencer is likely wrong.
-        "/ then, if the prefix is at least 3 chars,
-        "/ also add methods with that prefix.
-        
-        ((type classes size > 6) and:[ prefix size > 2 ]) ifTrue:[
-            self addMethodsStartingWith:prefix stripOff: stripprefix
-        ].
-    ] ifTrue:[
-        self addMethodsStartingWith:prefix stripOff: stripprefix  
-    ].
-
-    "Created: / 08-04-2014 / 21:04:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 09-04-2014 / 09:31:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-addMethodsForType: type stripOff: stripprefix     
-    | classes seen |
-
-    classes := type classes.
-    "/ Hack for Boolean: ifTrue:iFalse: etc are not defined
-    "/ in Boolean ?!!?
-    (classes size == 1 and:[classes anElement == Boolean ]) ifTrue:[
-        classes := Array with: True with: False.
-    ].
-    classes size == 1 ifTrue:[
-        classes anElement == JavaPackage class ifTrue:[  
-            "/ Special hack for JAVA: for pattern `JAVA java lang reflect`
-            "/ complete all Java classes in that package
-            | node |
-
-            node := result context node.
-            node isUnaryMessage ifTrue:[
-                | package |
-                "/ Compute package prefix...
-
-                package := node selector.
-                node := node receiver.
-                [ node isUnaryMessage ] whileTrue:[
-                    package := node selector , '/' , package.
-                    node := node receiver.
-                ].
-                self addJavaClassesInPackage: package.
-                ^ self.
-            ]
-        ]
-    ].
-
-    seen := Set new.
-    classes do: [:each | 
-        | class |
-
-        class := each.
-        [ class notNil and:[(seen includes: class) not]] whileTrue: [
-            seen add: class.
-            "/ Now, special care for Java classes, sigh...
-            (class isMetaclass and:[class theNonMetaclass isJavaClass]) ifTrue:[
-                class theNonMetaclass selectorsAndMethodsDo: [:selector :met | 
-                    met isStatic ifTrue:[
-                        result add: (MethodPO 
-                                    name: selector
-                                    class: met mclass).
-                    ].
-                ].
-            ] ifFalse:[
-                class selectorsAndMethodsDo: [:selector :met | 
-                    met isSynthetic ifFalse:[
-                        (stripprefix isNil or:[ selector size > stripprefix size and:[selector startsWith: stripprefix]]) ifTrue:[
-                            result add: (MethodPO 
-                                        name: selector
-                                        class: met mclass
-                                        stripOff: stripprefix).
-                        ].
-                    ]
-                ].
-            ].
-            class := class superclass.
-        ]
-    ].
+    selector2classesMap keysAndValuesDo: [:selector :classes|
+        result add:(MethodPO 
+                name:selector
+                class:(classes size == 1 ifTrue:[classes anElement] ifFalse:[classes])
+                stripOff: stripprefix)
+    ]
 
     "Created: / 08-04-2014 / 21:23:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-05-2014 / 14:44:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 addPools
--- a/bc.mak	Fri Apr 11 18:13:54 2014 +0200
+++ b/bc.mak	Fri May 09 14:54:07 2014 +0100
@@ -101,7 +101,7 @@
 $(OUTDIR)SmallSense__PO.$(O) SmallSense__PO.$(H): SmallSense__PO.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\HierarchicalItem.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__ParseTreeIndex.$(O) SmallSense__ParseTreeIndex.$(H): SmallSense__ParseTreeIndex.st $(INCLUDE_TOP)\stx\libbasic\Collection.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\OrderedCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\SequenceableCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\SortedCollection.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__ParseTreeIndexEntry.$(O) SmallSense__ParseTreeIndexEntry.$(H): SmallSense__ParseTreeIndexEntry.st $(INCLUDE_TOP)\stx\libbasic\Magnitude.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)SmallSense__ParseNodeInspector.$(O) SmallSense__ParseNodeInspector.$(H): SmallSense__ParseNodeInspector.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libwidg2\HierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ParseTreeInspector.$(O) SmallSense__ParseTreeInspector.$(H): SmallSense__ParseTreeInspector.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libwidg2\HierarchicalItem.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__SelectorNode.$(O) SmallSense__SelectorNode.$(H): SmallSense__SelectorNode.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libcomp\ParseNode.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__SettingsAppl.$(O) SmallSense__SettingsAppl.$(H): SmallSense__SettingsAppl.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\AbstractSettingsApplication.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(STCHDR)
 $(OUTDIR)SmallSense__SmalltalkChecker.$(O) SmallSense__SmalltalkChecker.$(H): SmallSense__SmalltalkChecker.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\lint\SmalllintChecker.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
--- a/smallsense.rc	Fri Apr 11 18:13:54 2014 +0200
+++ b/smallsense.rc	Fri May 09 14:54:07 2014 +0100
@@ -3,7 +3,7 @@
 // automagically generated from the projectDefinition: jv_smallsense.
 //
 VS_VERSION_INFO VERSIONINFO
-  FILEVERSION     6,2,19094,19094
+  FILEVERSION     6,2,32767,32767
   PRODUCTVERSION  6,2,3,0
 #if (__BORLANDC__)
   FILEFLAGSMASK   VS_FF_DEBUG | VS_FF_PRERELEASE
@@ -20,12 +20,12 @@
     BEGIN
       VALUE "CompanyName", "eXept Software AG\0"
       VALUE "FileDescription", "Smalltalk/X Class library (LIB)\0"
-      VALUE "FileVersion", "6.2.19094.19094\0"
+      VALUE "FileVersion", "6.2.32767.32767\0"
       VALUE "InternalName", "jv:smallsense\0"
       VALUE "LegalCopyright", "Copyright Claus Gittinger 1988-2011\nCopyright eXept Software AG 1998-2011\0"
       VALUE "ProductName", "Smalltalk/X\0"
       VALUE "ProductVersion", "6.2.3.0\0"
-      VALUE "ProductDate", "Thu, 10 Apr 2014 07:00:26 GMT\0"
+      VALUE "ProductDate", "Fri, 09 May 2014 13:48:20 GMT\0"
     END
 
   END