Fixes and improvements for Java/Groovy completion (part 2)
authorJan Vrany <jan.vrany@fit.cvut.cz>
Sun, 18 May 2014 10:24:28 +0100
changeset 217 6ff466b83ff9
parent 216 595defe6a523
child 218 0f5b160ecb9d
Fixes and improvements for Java/Groovy completion (part 2) * Bettet type-guessing of fields
SmallSense__AbstractJavaCompletionEngine.st
SmallSense__AbstractJavaCompletionSimple.st
SmallSense__EditSupport.st
SmallSense__JavaEditSupport.st
SmallSense__ParseTreeIndexEntry.st
SmallSense__SmalltalkEditSupport.st
jv_smallsense.st
smallsense.rc
--- a/SmallSense__AbstractJavaCompletionEngine.st	Thu May 15 17:58:25 2014 +0100
+++ b/SmallSense__AbstractJavaCompletionEngine.st	Sun May 18 10:24:28 2014 +0100
@@ -70,6 +70,27 @@
     "Created: / 15-05-2014 / 12:05:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+addFieldsForType: type
+    | seen |
+
+    seen := Set new.
+    type classesDo:[:initialCls |
+        (seen includes: initialCls) ifFalse:[ 
+            | cls |
+
+            cls := initialCls.                                    
+            cls staticFields do:[:each | result add: (VariablePO classVariable: each name in: cls) ].
+            [ cls ~~ JavaObject and:[ (seen includes: cls) not ] ] whileTrue:[ 
+                seen add: cls.
+                cls fields do:[:each | result add: (VariablePO instanceVariable: each name in: cls) ]. 
+                cls := cls superclass.
+            ].
+        ]
+    ].
+
+    "Created: / 17-05-2014 / 20:37:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 addImportsStartingWith: prefix
     | packages |
 
--- a/SmallSense__AbstractJavaCompletionSimple.st	Thu May 15 17:58:25 2014 +0100
+++ b/SmallSense__AbstractJavaCompletionSimple.st	Sun May 18 10:24:28 2014 +0100
@@ -71,30 +71,11 @@
 
 !AbstractJavaCompletionSimple methodsFor:'completion-individual'!
 
-addFieldsStartingWith: prefix
-    | klass |
-
-    [ klass notNil ] whileTrue:[
-        klass instVarNames do:[:nm |
-            result add: (VariablePO instanceVariable: nm in: klass).
-        ].
-        klass := klass superclass.
-    ].
+addVariables
+    self addFieldsForType: self guessTypeOfThis.
 
-    "Created: / 03-10-2013 / 11:16:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 13-05-2014 / 17:29:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-addLocalsStartingWith: prefix
-
-    "Created: / 03-10-2013 / 17:46:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 13-05-2014 / 17:29:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-addMethodsForReceiver: maybeReceiverToken startingWith: prefix    
-    ^ self addMethodsStartingWith: prefix
-
-    "Created: / 03-10-2013 / 17:46:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 17-05-2014 / 09:15:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-05-2014 / 20:30:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !AbstractJavaCompletionSimple methodsFor:'completion-private'!
@@ -108,7 +89,7 @@
     line size < (col - 1) ifTrue:[ ^ nil ].
 
 
-    stream := TokenStream on: (self scannerClass for: (line readStream readLimit: col - 1)).
+    stream := TokenStream on: (self scannerClass for: line string) cursor: col - 1.
     anyMatched := false.
     self completionPatterns keysAndValuesDo:[ :pattern :action |
         | matcher |
@@ -121,33 +102,43 @@
         ].
     ].
     anyMatched ifFalse:[ 
+        | caretI last lastI |
+
         stream position: 0.
         tokens := stream contents.
-        tokens isEmptyOrNil ifTrue:[ ^ result ].
+        "/ At least there must be CARET token
+        tokens size == 1 ifTrue:[ ^ result ].
+        tokens first type == #CARET ifTrue:[ ^ result ].
 
-        tokens last type == #Identifier ifTrue:[ 
-            tokens size == 1 ifTrue:[ 
+        "/ Find last token before CARET
+        caretI := 2.
+        [ (tokens at: caretI) type ~~ #CARET ] whileTrue:[ caretI := caretI + 1 ].
+        lastI := caretI - 1.
+        last := tokens at: lastI.
+
+        last type == #Identifier ifTrue:[ 
+            lastI == 1 ifTrue:[ 
                 "/ Only one token on line, complete local variable or receiver's field.
-                self completeLocalOrField: tokens.
+                self completeLocalOrFieldIn: tokens before: caretI.
             ] ifFalse:[ 
                 "/ If preceeding token is dot, complete method or field of the receiver.
-                (tokens at: tokens size - 1) type == $. ifTrue:[ 
-                    self completeMethodOrField: tokens.
+                (tokens at: lastI - 1) type == $. ifTrue:[ 
+                    self completeMethodOrFieldIn: tokens before: caretI.
                 ] ifFalse:[ 
                     "/ Else try to complete field.
-                    self completeLocalOrField: tokens.                    
+                    self completeLocalOrFieldIn: tokens before: caretI.
                 ].
             ].
         ] ifFalse:[
         "/ Else if last token in dot, complete method or field of the receiver
-        tokens last type == $. ifTrue:[ 
-            self completeMethodOrField: tokens.
+        last type == $. ifTrue:[ 
+            self completeMethodOrFieldIn: tokens before: caretI.
         ]].
     ].
     ^ result
 
     "Created: / 02-10-2013 / 13:55:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 15-05-2014 / 14:02:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-05-2014 / 18:54:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 completeImport: match
@@ -162,18 +153,19 @@
     "Created: / 15-05-2014 / 06:57:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-completeLocalOrField: tokens
-    ^ self shouldImplement
+completeLocalOrFieldIn: tokens before: caretTokenIndex
+    self addVariables
 
-    "Created: / 15-05-2014 / 14:01:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 15-05-2014 / 18:53:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-05-2014 / 09:15:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-completeMethodOrField: tokens
+completeMethodOrFieldIn: tokens before: caretTokenIndex
     | type dotIndex |
 
-    dotIndex := tokens last type == #Identifier ifTrue:[ tokens size - 1 ] ifFalse:[ tokens size ].  
+    dotIndex := (tokens at: caretTokenIndex - 1) type == #Identifier ifTrue:[ caretTokenIndex - 2 ] ifFalse:[ caretTokenIndex - 1 ].  
     self assert: (tokens at: dotIndex) type == $..
-    type := self guessReceiverTypeFrom: tokens before: dotIndex.
+    type := self guessTypeOfExpressionBefore: dotIndex in: tokens.
     type isUnknownType ifFalse:[
         self addMethodsForType: type.  
         "/self addFieldsForType: type.
@@ -188,8 +180,8 @@
         ].
     ].
 
-    "Created: / 15-05-2014 / 07:44:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 15-05-2014 / 09:44:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 15-05-2014 / 18:51:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-05-2014 / 10:50:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 completeNew: match
@@ -232,7 +224,7 @@
 
 !AbstractJavaCompletionSimple methodsFor:'guesswork'!
 
-guessReceiverTypeFrom: tokens before: end
+guessTypeOfExpressionBefore: end in: tokens
     | i type |
 
     i := end - 1.  
@@ -275,21 +267,46 @@
         name := (tokens at: i) value.
         i > 0 ifTrue:[ 
             (tokens at: i - 1) type == $. ifTrue:[ 
-                type := self guessReceiverTypeFrom: tokens before: i - 1.
+                type := self guessTypeOfExpressionBefore: i - 1 in: tokens.
             ] ifFalse:[ 
-                type := Type withClass: class.
+                type := self guessTypeOfThis.
             ].
             ^ self guessTypeOfMethod: type of: type numArgs: nargs.
         ].
     ].
+    (tokens at: i) type == #Identifier ifTrue:[ 
+        "/ Either field or local
+        | name type |
+
+        name := (tokens at: i) value.
+        (i > 1 and:[ (tokens at: i - 1) type == $. ]) ifTrue:[ 
+            "/ Non-this field
+            type := self guessTypeOfExpressionBefore: i - 1 in: tokens.      
+            ^ self guessTypeOfField: name of: type.  
+        ] ifFalse:[ 
+            "/ This-field
+            ^ self guessTypeOfFieldOrLocal: name
+        ].
+    ].
 
     ^ Type unknown    
 "/    ^ Type withClass: 
 "/        (context environment classNamed:#'JAVA::java::lang::Object')
 "/            ? (context environment classNamed:#'java/lang/Object')
 
-    "Created: / 15-05-2014 / 08:09:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 15-05-2014 / 13:04:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 17-05-2014 / 10:51:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+guessTypeOfField: name of: type
+    ^ Type unknown
+
+    "Created: / 17-05-2014 / 10:47:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+guessTypeOfFieldOrLocal: name
+    ^ Type unknown
+
+    "Created: / 17-05-2014 / 10:47:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 guessTypeOfMethod: name of: type numArgs: nargs
@@ -316,5 +333,11 @@
     self halt.
 
     "Created: / 15-05-2014 / 09:39:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+guessTypeOfThis
+    ^ Type withClass: class.
+
+    "Created: / 17-05-2014 / 10:52:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
--- a/SmallSense__EditSupport.st	Thu May 15 17:58:25 2014 +0100
+++ b/SmallSense__EditSupport.st	Sun May 18 10:24:28 2014 +0100
@@ -267,7 +267,7 @@
     ^false
 
     "Created: / 24-07-2013 / 23:31:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (format): / 20-01-2014 / 09:20:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-05-2014 / 21:22:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 keyPressIgnored: key
--- a/SmallSense__JavaEditSupport.st	Thu May 15 17:58:25 2014 +0100
+++ b/SmallSense__JavaEditSupport.st	Sun May 18 10:24:28 2014 +0100
@@ -149,6 +149,13 @@
     lastTypedKey1 := lastTypedKey0.
     lastTypedKey0 := key.
 
+    key == #CodeCompletion ifTrue:[ 
+        completionController notNil ifTrue:[
+            ^ completionController handleKeyPress:key x:x y:y 
+        ].
+        ^ false
+    ].     
+
     key == ${ ifTrue:[
         ^ self keyPressOpenCurly
     ].
@@ -160,7 +167,7 @@
     ^ false
 
     "Created: / 07-03-2010 / 09:36:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 20-01-2014 / 09:20:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 17-05-2014 / 21:23:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 keyPressOpenCurly
--- a/SmallSense__ParseTreeIndexEntry.st	Thu May 15 17:58:25 2014 +0100
+++ b/SmallSense__ParseTreeIndexEntry.st	Sun May 18 10:24:28 2014 +0100
@@ -262,3 +262,10 @@
     "Created: / 21-08-2011 / 09:31:33 / cg"
 ! !
 
+!ParseTreeIndexEntry class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- a/SmallSense__SmalltalkEditSupport.st	Thu May 15 17:58:25 2014 +0100
+++ b/SmallSense__SmalltalkEditSupport.st	Sun May 18 10:24:28 2014 +0100
@@ -183,6 +183,13 @@
     lastTypedKey1 := lastTypedKey0.
     lastTypedKey0 := key.
 
+    key == #CodeCompletion ifTrue:[ 
+        completionController notNil ifTrue:[
+            ^ completionController handleKeyPress:key x:x y:y 
+        ].
+        ^ false
+    ].     
+
     key == #BackSpace ifTrue:[
         backspaceIsUndo ifTrue:[
              textView undo.
@@ -219,7 +226,7 @@
     ^ false.
 
     "Created: / 07-03-2010 / 09:36:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 29-01-2014 / 10:31:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-05-2014 / 21:22:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 keyPressDoubleColon
--- a/jv_smallsense.st	Thu May 15 17:58:25 2014 +0100
+++ b/jv_smallsense.st	Sun May 18 10:24:28 2014 +0100
@@ -343,8 +343,12 @@
     "Swizzle all methods annotated as <swizzle:>"
 
     Swizzled ifTrue:[ ^ self ].
-    self extensionMethods do:[:m|self swizzle: m].
-    Swizzled := true.
+    [
+        self extensionMethods do:[:m|self swizzle: m].
+        Swizzled := true.
+    ] on: Error do:[:ex |
+        Logger log: ('Cannot swizzle: %1' bindWith: ex description) severity: #error
+    ].
 
 
     "
@@ -360,9 +364,13 @@
 
     | annotation |
 
-    annotation := method annotationAt: #swizzle:.
-    annotation notNil ifTrue:[
-        self swizzle: method as: (annotation argumentAt: 1).
+    [
+        annotation := method annotationAt: #swizzle:.
+        annotation notNil ifTrue:[
+            self swizzle: method as: (annotation argumentAt: 1).
+        ]
+    ] on: Error do:[:ex|
+        Logger log: ('Cannot swizzle %1: %2' bindWith: method with: ex description) severity: #error
     ]
 
     "Created: / 19-08-2013 / 14:53:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
--- a/smallsense.rc	Thu May 15 17:58:25 2014 +0100
+++ b/smallsense.rc	Sun May 18 10:24:28 2014 +0100
@@ -25,7 +25,7 @@
       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, 15 May 2014 13:41:10 GMT\0"
+      VALUE "ProductDate", "Sun, 18 May 2014 08:13:44 GMT\0"
     END
 
   END