#FEATURE by cg
authorClaus Gittinger <cg@exept.de>
Thu, 10 May 2018 11:17:30 +0200
changeset 4249 a308dc806db6
parent 4248 6ad8e090ff16
child 4250 2903262d8033
#FEATURE by cg class: Parser class changed: #findBest:selectorsFor:in:forCompletion:
Parser.st
--- 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.