Fix in SmallSense::Recognizer: use customized SmalltalkParser to parse smalltalk code.
SmalltalkParser can do some basic error-recovery and thus provides better
tree for completion.
"{ Package: 'jv:smallsense' }"
"{ NameSpace: SmallSense }"
Object subclass:#Recognizer
instanceVariableNames:'resultSet collector'
classVariableNames:''
poolDictionaries:''
category:'SmallSense-Core'
!
!Recognizer class methodsFor:'utilities'!
old_resultSetFor: mode source: source class: class row: row column: col
| parser tree |
mode == #method ifTrue:[
parser := Parser new.
parser
parseMethod:source asString
in: class
ignoreErrors:false
ignoreWarnings:false.
] ifFalse:[
parser := Parser for: (source asString readStream).
"JV@2011-06-13: HACK, use polymorphism"
tree := parser
parseExpressionWithSelf:nil
notifying:nil
ignoreErrors:false
ignoreWarnings:false
inNameSpace:nil.
parser tree: tree.
].
^ self new
recognize:row
position:col
collector:parser
"Modified: / 07-04-2011 / 22:55:58 / Jakub <zelenja7@fel.cvut.cz>"
"Created: / 26-11-2011 / 14:40:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
resultSetFor: mode source: source class: class line: line column: col
| inferencer tree |
mode == #method ifTrue:[
inferencer := SmalltalkInferencer forClass: class methodSource: source asString.
inferencer parserClass: SmalltalkParser.
inferencer process.
] ifFalse:[
self breakPoint: #jv.
^nil.
inferencer := Parser for: (source asString readStream).
"JV@2011-06-13: HACK, use polymorphism"
tree := inferencer
parseExpressionWithSelf:nil
notifying:nil
ignoreErrors:false
ignoreWarnings:false
inNameSpace:nil.
inferencer tree: tree.
].
^ self new
completeAtLine:line
column:col
collector:inferencer
"Modified: / 07-04-2011 / 22:55:58 / Jakub <zelenja7@fel.cvut.cz>"
"Created: / 26-11-2011 / 17:53:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 02-09-2013 / 14:43:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!Recognizer methodsFor:'adding'!
addClassVariables
| class |
class := collector klass theNonMetaclass.
class classVarNames do:[:nm|
resultSet add:(VariablePO classVariable: nm in: class).
].
"Created: / 24-07-2013 / 17:00:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 30-07-2013 / 23:32:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addGlobalsStartingWith: prefix
| class ns cls |
class := collector klass.
ns := class nameSpace.
"nameSpace may return private class, sigh"
[ ns isNameSpace ] whileFalse:[ ns := ns nameSpace ].
ns keysDo:[:nm|
(nm startsWith: prefix) ifTrue:[
cls := ns classNamed: nm.
cls notNil ifTrue:[
cls isBehavior ifTrue:[
resultSet add:(ClassPO new subject: cls; name: nm).
] ifFalse:[
resultSet add:(VariablePO globalVariable: cls).
]
]
].
].
ns ~~ Smalltalk ifTrue:[
Smalltalk keysDo:[:nm|
(nm startsWith: prefix) ifTrue:[
cls := Smalltalk classNamed: nm.
cls notNil ifTrue:[
cls isBehavior ifTrue:[
resultSet add:(ClassPO new subject: cls; name: nm ).
] ifFalse:[
resultSet add:(VariablePO globalVariable: cls).
]
]
]
].
]
"Created: / 26-11-2011 / 17:29:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 24-07-2013 / 17:00:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addMethods: type
type classesDo:[:each|
| class |
class := each.
[ class isNil ] whileFalse:[
class
selectorsAndMethodsDo:[:selector :met |
resultSet add:(MethodPO
name:selector
description:"met source"nil
class:class).
].
class := class superclass.
].
].
"Created: / 26-11-2011 / 17:03:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addMethodsStartingWith: prefix
Smalltalk allClassesDo:[:class|
class selectorsAndMethodsDo:[:selector :met |
(selector startsWith: prefix) ifTrue:[
resultSet add:(MethodPO
name:selector
description:"met source"nil
class:class).
]
].
].
"Created: / 24-07-2013 / 13:10:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addPools
| class |
class := collector klass theNonMetaclass.
class theNonMetaclass sharedPools do:[:pool|
pool theNonMetaclass classVarNames do:[:nm|
resultSet add:(VariablePO classVariable: nm in: pool).
]
].
"Created: / 24-07-2013 / 16:59:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 30-07-2013 / 23:32:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addPrivateClasses
| class |
class := collector klass theNonMetaclass.
class privateClassesDo:[:pclass|
| nm |
nm := pclass fullName copyFrom: class fullName size + 3.
resultSet add:(ClassPO new subject: pclass; name: nm).
]
"Created: / 06-08-2013 / 12:28:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addVariablesFor: node
| n |
"Add Instance variables"
collector klass allInstVarNames do:[:nm|
resultSet add: (VariablePO instanceVariable: nm in: collector klass).
].
"Add pseudo variables"
#(self super here thisContext) do:[:nm|
resultSet add: (VariablePO new name: nm).
].
"Add arguments"
collector parser methodArgs ? #() do:[:nm|
resultSet add: (VariablePO argument: nm).
].
"Add temporaries"
collector parser methodVars ? #() do:[:nm|
resultSet add: (VariablePO variable: nm).
].
n := node.
[ n notNil ] whileTrue:[
n isBlockNode ifTrue:[
n arguments ? #() do:[:barg|resultSet add: (VariablePO variable: barg name)].
n variables ? #() do:[:bvar|resultSet add: (VariablePO variable: bvar name)].
].
n := n parent.
]
"Created: / 31-07-2013 / 00:32:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!Recognizer methodsFor:'completion'!
completeAtLine:line column:col collector:coll
"find most possible codeCompletion object"
| position |
resultSet := ResultSet new.
collector := coll.
(collector tree isNil or:[collector tree == #Error]) ifTrue:[
^ resultSet
].
position := Finder new
findNodeIn: collector source tree: collector tree
line: line column: col.
resultSet position: position.
position isAfterNode ifTrue:[
self completeAfter:position node.
] ifFalse:[
position isInNode ifTrue:[
self completeIn:position node.
] ifFalse:[
position isBeforeNode ifTrue:[
self completeBefore:position node.
]]].
resultSet isEmpty ifTrue:[
nil "/Only to set breakpoint here
].
^resultSet.
"Created: / 04-03-2011 / 13:01:14 / Jakub <zelenja7@fel.cvut.cz>"
"Modified: / 08-04-2011 / 10:52:59 / Jakub <zelenja7@fel.cvut.cz>"
"Created: / 26-11-2011 / 17:05:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified (format): / 24-07-2013 / 16:00:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!Recognizer methodsFor:'completion-private'!
completeAfter:node
"return collection of completion items after given node"
self addMethods: node inferedType
"Created: / 04-03-2011 / 15:45:28 / Jakub <zelenja7@fel.cvut.cz>"
"Modified: / 08-04-2011 / 10:55:09 / Jakub <zelenja7@fel.cvut.cz>"
"Created: / 26-11-2011 / 17:07:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
completeBefore:node
self breakPoint: #jv. "Not yet implemented"
"Created: / 04-03-2011 / 15:45:28 / Jakub <zelenja7@fel.cvut.cz>"
"Modified: / 08-04-2011 / 10:55:09 / Jakub <zelenja7@fel.cvut.cz>"
"Created: / 26-11-2011 / 17:07:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
completeIn:node
"return collection which can be afterNode"
node isVariableNode ifTrue:[
node name first isUppercase ifTrue:[
self addGlobalsStartingWith: node name.
self addClassVariables.
self addPools.
self addPrivateClasses.
] ifFalse:[
self addVariablesFor: node
].
^self.
].
node isMessage ifTrue:[
| type |
type := node receiver inferedType.
type isUnknownType ifFalse:[
self addMethods: type
] ifTrue:[
self addMethodsStartingWith: node selector
].
^self.
].
self breakPoint: #jv.
"Created: / 07-03-2011 / 18:59:02 / Jakub <zelenja7@fel.cvut.cz>"
"Modified: / 08-04-2011 / 09:31:51 / Jakub <zelenja7@fel.cvut.cz>"
"Created: / 26-11-2011 / 17:07:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 06-08-2013 / 12:28:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!Recognizer class methodsFor:'documentation'!
version_HG
^ '$Changeset: <not expanded> $'
!
version_SVN
^ '$Id: SmallSenseRecognizer.st 7826 2011-11-27 09:48:43Z vranyj1 $'
! !