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)
--- 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