#FEATURE by cg
class: Parser class
changed: #findBest:selectorsFor:in:forCompletion:
--- a/Parser.st Wed May 09 19:37:55 2018 +0200
+++ b/Parser.st Thu May 10 11:17:30 2018 +0200
@@ -814,7 +814,7 @@
The way spelling distance is computed is a heuristic which works
well in real life (i.e. offer USEFUL suggestions)"
- |info selectorsAlready block lcSelector excludedClasses minNumArgs|
+ |info selectorsAlready checkBlock lcSelector excludedClasses minNumArgs|
excludedClasses := { ProtoObject . Structure . InlineObject prototype }.
@@ -826,44 +826,68 @@
lcSelector := aString asLowercase.
- block := [:sym :mthd|
- |similarity lcSym keepThis nCommon fractionCommon similarityRest|
-
- (forCompletion and:[sym = aString or:[sym argumentCount < minNumArgs]]) ifFalse:[
- lcSym := sym asLowercase.
- (selectorsAlready includes:sym) ifFalse:[
- "/ (info contains:[:i | i key == sym]) ifFalse:[
-
- forCompletion ifTrue:[
- "/ OLD: similarity := 100 * (1 + (lcSelector size / lcSym size)).
-
- nCommon := (lcSelector commonPrefixWith:lcSym) size.
- nCommon > 0 ifTrue:[
- "/ the longer the common prefix...
- fractionCommon := (nCommon / lcSym size).
- "/ bump it to 100+x if lc-prefix; to 200+x if real prefix
- (sym startsWith:aString) ifTrue:[
- similarity := 200 * (1 + fractionCommon).
+ checkBlock :=
+ [:sym :mthd|
+ |similarity similarity2 lcSym keepThis nCommon fractionCommon similarityRest idx|
+
+ (forCompletion and:[sym = aString or:[sym argumentCount < minNumArgs]]) ifFalse:[
+ (selectorsAlready includes:sym) ifFalse:[
+ "/ (info contains:[:i | i key == sym]) ifFalse:[
+
+ lcSym := sym asLowercase.
+ forCompletion ifTrue:[
+ similarity := 0.
+
+ "/ substring?
+ idx := (lcSym indexOfString:lcSelector).
+ idx ~~ 0 ifTrue:[
+ "/ yes
+
+ "/ part of a keyword part?
+ (lcSym includes:$:) ifTrue:[
+ lcSym keywords do:[:each |
+ |withoutColon|
+ (each includesString:lcSelector) ifTrue:[
+ withoutColon := each copyButLast.
+ fractionCommon := (lcSelector size / withoutColon size).
+ ((withoutColon startsWith:lcSelector) or:[withoutColon endsWith:lcSelector]) ifTrue:[
+ fractionCommon := fractionCommon * 1.2.
+ ].
+ similarity := similarity max:(150 * (1 + fractionCommon)).
+ ].
+ ].
+ ].
+ "/ the longer the common substring...
+ fractionCommon := (lcSelector size / lcSym size).
+ similarity := similarity max:(150 * (1 + fractionCommon)).
+ ].
+
+ nCommon := (lcSelector commonPrefixWith:lcSym) size.
+ nCommon > 0 ifTrue:[
+ "/ the longer the common prefix...
+ fractionCommon := (nCommon / lcSym size).
+ "/ bump it to 100+x if lc-prefix; to 200+x if real prefix
+ (sym startsWith:aString) ifTrue:[
+ similarity2 := 200 * (1 + fractionCommon).
+ ] ifFalse:[
+ similarity2 := 100 * (1 + fractionCommon).
+ ].
+ similarityRest := (lcSelector copyFrom:nCommon+1) spellAgainst:(lcSym copyFrom:nCommon+1).
+ similarity2 := similarity2 + similarityRest.
+
+ "/ higher similarity for my own messages
+ ((lcSym startsWith:lcSelector) and:[ aClassOrNil == mthd mclass ]) ifTrue:[
+ similarity2 := similarity2 * 1.2.
+ ].
] ifFalse:[
- similarity := 100 * (1 + fractionCommon).
+ similarity2 := lcSelector spellAgainst:lcSym. "/ 0..100
].
- similarityRest := (lcSelector copyFrom:nCommon+1) spellAgainst:(lcSym copyFrom:nCommon+1).
- similarity := similarity + similarityRest.
-
- "/ higher similarity for my own messages
- ((lcSym startsWith:lcSelector) and:[ aClassOrNil == mthd mclass ]) ifTrue:[
- similarity := similarity * 1.2.
- ].
+ similarity := similarity max:similarity2.
] ifFalse:[
similarity := lcSelector spellAgainst:lcSym. "/ 0..100
- ]
- ] ifFalse:[
- similarity := lcSelector spellAgainst:lcSym. "/ 0..100
- ].
-
- ((similarity > 30 "40") or:[ (lcSelector size>1) and:[(lcSym startsWith:lcSelector)] ]) ifTrue:[
- (selectorsAlready includes:sym) ifFalse:[
- "/ (info contains:[:entry | entry key = sym]) ifFalse:[
+ ].
+
+ ((similarity > 30 "40") or:[ (lcSelector size>1) and:[(lcSym startsWith:lcSelector)] ]) ifTrue:[
keepThis := true.
info size >= nMax ifTrue:[
"will remove last entry anyway - so check if this one will remain..."
@@ -888,27 +912,26 @@
]
]
]
- ]
- ].
+ ].
(aClassOrNil isNil or:[aClassOrNil == Object]) ifTrue:[
Smalltalk allClassesDo:[:cls |
(excludedClasses includes:cls) ifFalse:[
- cls methodDictionary keysAndValuesDo:block.
- cls class methodDictionary keysAndValuesDo:block.
+ cls methodDictionary keysAndValuesDo:checkBlock.
+ cls class methodDictionary keysAndValuesDo:checkBlock.
]
]
] ifFalse:[
aClassOrNil autoload.
aClassOrNil withAllSuperclassesDo:[:cls |
"/ Transcript showCR:'try ',cls name.
- cls methodDictionary keysAndValuesDo:block.
+ cls methodDictionary keysAndValuesDo:checkBlock.
"/ cls class methodDictionary keysAndValuesDo:block.
].
- aClassOrNil withAllSubclassesDo:[:cls |
- cls methodDictionary keysAndValuesDo:block.
- "/ cls class methodDictionary keysAndValuesDo:block.
- ].
+"/ aClassOrNil withAllSubclassesDo:[:cls |
+"/ cls methodDictionary keysAndValuesDo:checkBlock.
+"/ "/ cls class methodDictionary keysAndValuesDo:block.
+"/ ].
].
^ info collect:[:a | a key] as:OrderedCollection.