Fixes and improvements for Java/Groovy completion (part 2)
* Bettet type-guessing of fields
--- 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