AbstractJavaCompletionEngineSimple refactored to use token patterns. Initial support for receiver type guessing.
--- a/SmallSense__AbstractJavaCompletionEngine.st Wed May 14 15:23:05 2014 +0100
+++ b/SmallSense__AbstractJavaCompletionEngine.st Thu May 15 10:40:02 2014 +0100
@@ -22,24 +22,42 @@
!AbstractJavaCompletionEngine methodsFor:'completion-individual'!
addClassesStartingWith: prefix
+ ^ self addClassesStartingWith: prefix fullName: false
+
+ "Created: / 03-10-2013 / 11:16:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 15-05-2014 / 07:25:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addClassesStartingWith: prefixArg fullName: matchFullName
+ | prefix |
+
+ prefix := prefixArg.
+ matchFullName ifTrue:[
+ prefix := prefix copyReplaceAll: $. with: $/.
+ ].
context environment allClassesDo: [:cls |
- cls isJavaClass and:[
+ cls isJavaClass ifTrue:[
| name i |
- name := cls lastName.
- i := name lastIndexOf: $/.
- ((name size >= (i + prefix size))
- and:[(name at: i + 1) == prefix first
- and:[(name at: i + prefix size) == prefix last
- and:[(2 to: prefix size - 1) allSatisfy:[:o| (name at: i + o) == (prefix at: o)]]]])
- ifTrue:[
- result add: (ClassPO new subject: cls).
+ matchFullName ifTrue:[
+ (cls binaryName startsWith: prefix) ifTrue:[
+ result add: (ClassPO new subject: cls; showPrefix: true; yourself).
].
+ ] ifFalse:[
+ name := cls lastName.
+ i := name lastIndexOf: $/.
+ ((name size >= (i + prefix size))
+ and:[(name at: i + 1) == prefix first
+ and:[(name at: i + prefix size) == prefix last
+ and:[(2 to: prefix size - 1) allSatisfy:[:o| (name at: i + o) == (prefix at: o)]]]])
+ ifTrue:[
+ result add: (ClassPO new subject: cls).
+ ].
+ ].
].
].
- "Created: / 03-10-2013 / 11:16:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 14-05-2014 / 12:50:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Created: / 15-05-2014 / 07:24:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addImportsStartingWith: prefix
@@ -49,12 +67,12 @@
"/ Class imports...
context environment allClassesDo: [:cls |
- cls isJavaClass ifTrue:[
+ cls isJavaClass ifTrue:[
| name |
name := cls javaName.
(cls isPublic and:[name startsWith: prefix]) ifTrue:[
- result add: (JavaImportPO new subject: name; klass: cls; yourself).
+ result add: (JavaImportPO new subject: name; klass: cls; yourself).
packages add: cls javaPackage.
].
]
@@ -68,7 +86,7 @@
"Modified (format): / 14-05-2014 / 12:48:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
-addMethodsStartingWith: prefix
+addMethodsStartingWith: prefix
^ self addMethodsStartingWith: prefix stripOff: nil filter: [:m | m isJavaMethod ]
"Created: / 03-10-2013 / 18:01:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
--- a/SmallSense__AbstractJavaCompletionSimple.st Wed May 14 15:23:05 2014 +0100
+++ b/SmallSense__AbstractJavaCompletionSimple.st Thu May 15 10:40:02 2014 +0100
@@ -9,13 +9,40 @@
category:'SmallSense-Java-Abstract'
!
-AbstractJavaCompletionSimple class instanceVariableNames:'patterns'
+AbstractJavaCompletionSimple class instanceVariableNames:'CompletionPatterns AnalysisPatterns'
"
No other class instance variables are inherited by this class.
"
!
+!AbstractJavaCompletionSimple class methodsFor:'initialization'!
+
+initializeCompletionPatterns
+ CompletionPatterns isNil ifTrue:[ CompletionPatterns := Dictionary new ].
+
+ #(
+ '[[:import:]] ( [[:Identifier:]](.[[:Identifier:]])*\.? )?' #completeImport:
+ '[[:new:]] ( [[:Identifier:]](.[[:Identifier:]])*\.?)?' #completeNew:
+
+ ) pairWiseDo:[:pattern :action |
+ CompletionPatterns at: (TokenPatternParser parse: pattern) put: action
+ ].
+
+ "Created: / 14-05-2014 / 16:51:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionSimple class methodsFor:'accessing'!
+
+completionPatterns
+ CompletionPatterns isNil ifTrue:[
+ self initializeCompletionPatterns.
+ ].
+ ^ CompletionPatterns
+
+ "Created: / 14-05-2014 / 16:55:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
!AbstractJavaCompletionSimple class methodsFor:'queries'!
isAbstract
@@ -26,6 +53,22 @@
^ self == SmallSense::AbstractJavaCompletionSimple.
! !
+!AbstractJavaCompletionSimple methodsFor:'accessing'!
+
+completionPatterns
+ ^ self class completionPatterns
+
+ "Created: / 14-05-2014 / 17:02:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionSimple methodsFor:'accessing-class'!
+
+scannerClass
+ "raise an error: must be redefined in concrete subclass(es)"
+
+ ^ self subclassResponsibility
+! !
+
!AbstractJavaCompletionSimple methodsFor:'completion-individual'!
addFieldsStartingWith: prefix
@@ -57,107 +100,174 @@
!AbstractJavaCompletionSimple methodsFor:'completion-private'!
complete
- | line col scanner token tokenTypes values startPositions stopPositions maybeReceiverToken |
+ | line col stream tokens anyMatched |
line := codeView listAt: codeView cursorLine.
col := codeView cursorCol.
line isNil ifTrue:[ ^ nil ].
line size < (col - 1) ifTrue:[ ^ nil ].
-"/ "/ we need at least three characters in order to reduce
-"/ "/ completions...
-"/ line size < 3 ifTrue:[ ^ nil ].
-"/ col - 3 to: col - 1 do:[:i|
-"/ | c |
-"/
-"/ c := line at: i.
-"/ (c isLetterOrDigit or:[c == $_ or:[ c == $$ ] ]) ifFalse:[ ^ nil ]
-"/ ].
- "/ Setup some context vars
- method := codeView editedMethod.
- class := method notNil ifTrue:[method mclass] ifFalse:[codeView editedClass ].
+ stream := TokenStream on: (self scannerClass for: (line readStream readLimit: col - 1)).
+ anyMatched := false.
+ self completionPatterns keysAndValuesDo:[ :pattern :action |
+ | matcher |
- "/ ok, we got three character prefix, now scan the current line...
- scanner := self scannerClass for: line.
- tokenTypes := OrderedCollection new.
- values := OrderedCollection new.
- startPositions := OrderedCollection new.
- stopPositions := OrderedCollection new.
- [
- [ (token := scanner nextToken) ~~ #EOF and:[ scanner tokenStartPosition < (col - 1) ] ] whileTrue:[
- tokenTypes add: token.
- values add: scanner tokenValue.
- startPositions add: scanner tokenStartPosition.
- stopPositions add: scanner tokenEndPosition.
+ stream position: 0. "/ Reset the position
+ matcher := TokenPatternMatcher for: pattern.
+ matcher matchesOnStream: stream do:[:match |
+ self perform: action with: match.
+ anyMatched := true.
].
- ] on: Error do:[
- ^ nil
+ ].
+ anyMatched ifFalse:[
+ stream position: 0.
+ tokens := stream contents.
+ (tokens size > 2 and:[tokens last type == $. or:[tokens last type == #Identifier and:[ (tokens at: tokens size - 1) type == $. ]]]) ifTrue:[
+ self completeMethodOrField: tokens.
+ ].
].
- tokenTypes isEmpty ifTrue:[ ^ nil ].
- "/ now, simple check for import declaration
- tokenTypes first == #import and:[
- | prefix |
-
- prefix := String streamContents:[:s|
- | i |
-
- i := 2.
- [ i <= tokenTypes size ] whileTrue:[
- (tokenTypes at: i) == #Identifier ifTrue:[
- s nextPutAll: (values at: i).
- ] ifFalse:[
- ^ nil "/ malformed import
- ].
- (i < tokenTypes size) ifTrue:[
- (tokenTypes at: i + 1) == $. ifTrue:[
- s nextPut: $.
- ] ifFalse:[
- ^ nil "/ malformed import
- ].
- ].
- i := i + 2.
- ].
- ].
- self addImportsStartingWith: prefix.
- ^ result.
- ].
-
- "/ We need at least three characters to complete methods/fields.
- (tokenTypes last ~~ #Identifier or:[values last size < 3]) ifTrue:[ ^ nil ].
-
- "/ Complete after new keyword
- (tokenTypes size > 1 and:[(tokenTypes at: tokenTypes size - 1) == #new]) ifTrue:[
- self addClassesStartingWith: values last.
- ^ result.
- ].
-
-
- "/ now check whether the butlast token is dot...
- maybeReceiverToken := nil.
- (tokenTypes size > 1 and:[(tokenTypes at: tokenTypes size - 1) == $.]) ifTrue:[
- "/ if so, it's likely a message send, then complete methods...
- tokenTypes size > 2 ifTrue:[
- maybeReceiverToken := values at: values size - 2.
- ].
- ] ifFalse:[
- "/ if not, then complete local variables, fields and methods defined in the class itself.
- maybeReceiverToken := 'this'.
- ].
- maybeReceiverToken = 'this' ifTrue:[
- values last first isUppercase ifTrue:[
- self addClassesStartingWith: values last.
- ] ifFalse:[
- self addFieldsStartingWith: values last.
- self addLocalsStartingWith: values last.
- ].
- ].
- self addMethodsForReceiver: maybeReceiverToken startingWith: values last.
^ result
"Created: / 02-10-2013 / 13:55:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 13-05-2014 / 17:46:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (format): / 15-05-2014 / 07:52:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeImport: match
+ | prefix |
+
+ prefix := nil.
+ match size > 1 ifTrue:[
+ prefix := String streamContents:[:s | 2 to: match size do:[:i | s nextPutAll: (match at: i) value asString] ].
+ ].
+ self addImportsStartingWith: prefix
+
+ "Created: / 15-05-2014 / 06:57:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeMethodOrField: tokens
+ | type dotIndex |
+
+ dotIndex := tokens last type == #Identifier ifTrue:[ tokens size - 1 ] ifFalse:[ tokens size ].
+ self assert: (tokens at: dotIndex) type == $..
+ type := self guessReceiverTypeFrom: tokens before: dotIndex.
+ type isUnknownType ifFalse:[
+ self addMethodsForType: type.
+ "/self addFieldsForType: type.
+ ] ifTrue:[
+ tokens last type == #Identifier ifTrue:[
+ | prefix |
+
+ prefix := tokens last value.
+ (prefix size >= 3 and:[ prefix ~= 'get' and:[prefix ~= 'set' ]]) ifTrue:[
+ self addMethodsStartingWith: prefix.
+ ].
+ ].
+ ].
+
+ "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>"
+!
+
+completeNew: match
+ | prefix |
+
+ prefix := nil.
+ match size > 2 ifTrue:[
+ prefix := String streamContents:[:s | 2 to: match size do:[:i | s nextPutAll: (match at: i) value asString] ].
+ self addClassesStartingWith: prefix fullName: true.
+ ] ifFalse:[
+ prefix := (match at: 2) value.
+ self addClassesStartingWith: prefix
+ ].
+
+ "Created: / 15-05-2014 / 07:16:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!AbstractJavaCompletionSimple methodsFor:'guesswork'!
+
+guessReceiverTypeFrom: tokens before: end
+ | i type |
+
+ i := end - 1.
+
+ (tokens at: i) type == $) ifTrue:[
+ "/ OK, end of message send, scan for method name...
+ | nparens nargs name |
+
+ nparens := 1.
+
+ i := i - 1.
+ nargs := 0.
+ (tokens at: i) type == $( ifTrue:[
+ i := i - 1.
+ ] ifFalse:[
+ nargs := 1.
+ [ i > 0 and:[ nparens ~~ 0 ] ] whileTrue:[
+ (tokens at: i) type == $) ifTrue:[
+ nparens := nparens + 1
+ ] ifFalse:[
+ (tokens at: i) type == $( ifTrue:[
+ nparens := nparens - 1
+ ] ifFalse:[
+ (((tokens at: i) type == $,) and:[nparens == 1]) ifTrue:[
+ nargs := nargs + 1.
+ ]
+ ].
+ ].
+ i := i - 1.
+ ].
+ ].
+ nparens ~~ 0 ifTrue:[
+ "/ Malformed input
+ ^ Type unknown
+ ].
+ (tokens at: i) type == #Identifier ifFalse:[
+ "/ Malformed input
+ ^ Type unknown
+ ].
+ name := (tokens at: i) value.
+ i > 0 ifTrue:[
+ (tokens at: i - 1) type == $. ifTrue:[
+ type := self guessReceiverTypeFrom: tokens before: i - 1.
+ ] ifFalse:[
+ type := Type withClass: class.
+ ].
+ ^ self guessTypeOfMethod: type of: type numArgs: nargs.
+ ].
+ ].
+
+ ^ Type withClass: (context environment classNamed:#'JAVA::java::lang::Object')
+
+ "Created: / 15-05-2014 / 08:09:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 15-05-2014 / 09:42:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+guessTypeOfMethod: name of: type numArgs: nargs
+ | methods |
+
+ methods := Set new.
+ type classesDo:[:initialClass |
+ | class |
+
+ class := initialClass.
+ [ class notNil and:[ class ~~ JavaObject ] ] whileTrue:[
+ class selectorsAndMethodsDo:[:selector :method |
+ method isJavaMethod ifTrue:[
+ (selector size > name size
+ and:[ method numJavaArgs = nargs
+ and:[ (selector at: name size + 1) == $(
+ and:[ (selector startsWith: name) ]]])
+ ifTrue:[ methods add: method ].
+ ].
+ ].
+ ].
+ ].
+
+ self halt.
+
+ "Created: / 15-05-2014 / 09:39:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- a/SmallSense__ClassPO.st Wed May 14 15:23:05 2014 +0100
+++ b/SmallSense__ClassPO.st Thu May 15 10:40:02 2014 +0100
@@ -39,7 +39,7 @@
showPrefix ifTrue:[
nm := subject name.
(context notNil and:[subject isJavaClass]) ifTrue:[
- context language isJava ifTrue:[
+ context language isJavaLike ifTrue:[
nm := subject javaName
] ifFalse:[
context language isSmalltalk ifTrue:[
@@ -53,7 +53,7 @@
^nm
"Created: / 26-08-2013 / 10:26:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 17-12-2013 / 22:16:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 15-05-2014 / 07:28:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
showPrefix
@@ -67,20 +67,26 @@
stringAlreadyWritten
"Answers a string already written in the textview"
- (subject isJavaClass and:[context language isSmalltalk]) ifTrue:[
- | rec |
+ subject isJavaClass ifTrue:[
+ context language isSmalltalk ifTrue:[
+ | rec |
- rec := context node .
- [ rec isUnaryMessage ] whileTrue:[
- rec := rec receiver.
- ].
- (rec isVariableNode and:['JAVA' startsWith: rec name]) ifTrue:[
- ^ context codeView contents asString copyFrom: rec startPosition to: context node endPosition
- ].
+ rec := context node .
+ [ rec isUnaryMessage ] whileTrue:[
+ rec := rec receiver.
+ ].
+ (rec isVariableNode and:['JAVA' startsWith: rec name]) ifTrue:[
+ ^ context codeView contents asString copyFrom: rec startPosition to: context node endPosition
+ ].
+ ] ifFalse:[
+ context language isJavaLike ifTrue:[
+ ^ context wordBeforeCursorConsisitingOfCharactersMatching:[:c | c isAlphaNumeric or:['$_.' includes: c] ]
+ ]].
].
^ super stringAlreadyWritten
"Created: / 20-10-2013 / 02:46:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 15-05-2014 / 07:31:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
stringToCompleteForLanguage: language
--- a/SmallSense__CompletionEngine.st Wed May 14 15:23:05 2014 +0100
+++ b/SmallSense__CompletionEngine.st Thu May 15 10:40:02 2014 +0100
@@ -92,6 +92,159 @@
!CompletionEngine methodsFor:'completion-individual'!
+addMethodsForType: type
+ | 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:[
+ result add: (MethodPO
+ name: selector
+ class: met mclass).
+ ]
+ ].
+ ].
+ class := class superclass.
+ ]
+ ].
+
+ "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.
+ ]
+ ].
+
+ "Created: / 08-04-2014 / 21:23:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
addMethodsStartingWith: prefix
^ self addMethodsStartingWith: prefix stripOff: nil filter: nil
--- a/SmallSense__JavaCompletionEngine.st Wed May 14 15:23:05 2014 +0100
+++ b/SmallSense__JavaCompletionEngine.st Thu May 15 10:40:02 2014 +0100
@@ -24,25 +24,6 @@
!JavaCompletionEngine methodsFor:'completion-individual'!
-addClassesStartingWith: prefix
- self javaClassesDo:[:cls|
- | name i |
-
- name := cls lastName.
- i := name lastIndexOf: $/.
- ((name size >= (i + prefix size))
- and:[(name at: i + 1) == prefix first
- and:[(name at: i + prefix size) == prefix last
- and:[(2 to: prefix size - 1) allSatisfy:[:o| (name at: i + o) == (prefix at: o)]]]])
- ifTrue:[
- result add: (ClassPO new subject: cls).
- ].
- ].
-
- "Created: / 03-10-2013 / 11:16:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 20-10-2013 / 01:27:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
addFieldsStartingWith: prefix
| klass |
--- a/SmallSense__SmalltalkCompletionEngine.st Wed May 14 15:23:05 2014 +0100
+++ b/SmallSense__SmalltalkCompletionEngine.st Thu May 15 10:40:02 2014 +0100
@@ -151,159 +151,6 @@
"Modified: / 14-05-2014 / 12:48:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
-addMethodsForType: type
- | 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:[
- result add: (MethodPO
- name: selector
- class: met mclass).
- ]
- ].
- ].
- class := class superclass.
- ]
- ].
-
- "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.
- ]
- ].
-
- "Created: / 08-04-2014 / 21:23:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
addPools
| class |
--- a/SmallSense__TokenStream.st Wed May 14 15:23:05 2014 +0100
+++ b/SmallSense__TokenStream.st Thu May 15 10:40:02 2014 +0100
@@ -36,6 +36,18 @@
"Created: / 06-05-2014 / 15:25:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!TokenStream methodsFor:'* As yet uncategorized *'!
+
+contents
+ ^ Array streamContents:[ :s |
+ [ self atEnd ] whileFalse:[
+ s nextPut: self next
+ ].
+ ].
+
+ "Created: / 15-05-2014 / 07:49:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
!TokenStream methodsFor:'accessing'!
sourceStream