SmallSense__JavaCompletionEngine.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Tue, 13 May 2014 17:38:10 +0100
changeset 206 f74a5ffd8eae
child 210 1922d415c704
permissions -rw-r--r--
Separated JavaCompletionEngine and JavaCompletionEngineSimple. *Simple variant does ony lexical analysis, whereas JavaCompletionEngine relies on Eclipse parse tree.

"{ Package: 'jv:smallsense' }"

"{ NameSpace: SmallSense }"

AbstractJavaCompletionEngine subclass:#JavaCompletionEngine
	instanceVariableNames:'classTree methodTree'
	classVariableNames:''
	poolDictionaries:''
	category:'SmallSense-Java'
!

!JavaCompletionEngine methodsFor:'completion'!

completeNode: node
    Transcript 
        show: 'Java Simple Completion on node: ';
        show: node printString;
        show: ' [';
        show: node class printString;
        showCR: ']'.

    "Created: / 20-10-2013 / 01:34:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!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 |

    classTree notNil ifTrue:[
        (classTree fields ? #()) do:[:field |
            result add: (VariablePO instanceVariable: field name in: class).            
        ].
    ] ifFalse:[
        klass := class.
    ].

    [ klass notNil ] whileTrue:[
        klass instVarNames do:[:nm |
            result add: (VariablePO instanceVariable: nm in: klass).
        ].
        klass := klass superclass.
    ].

    "Created: / 03-10-2013 / 11:16:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 20-10-2013 / 02:04:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

addImportsStartingWith: prefix
    | packages |

    packages := Set new.

    "/ Class imports...
    self javaClassesDo:[:cls|
        | name i |

        name := cls javaName.
        (cls isPublic and:[name startsWith: prefix]) ifTrue:[
            result add: (JavaImportPO new subject: name; klass: cls; yourself).        
            packages add: cls javaPackage.
        ].
    ].
    "/ Package imports...
    packages do:[:each |
        result add: (JavaImportPO new subject: (each , '.*'))
    ].

    "Created: / 19-10-2013 / 17:54:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 20-10-2013 / 00:35:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

addLocalsStartingWith: prefix
    | queue |

    methodTree isNil ifTrue:[ ^ self ].
    methodTree scope isNil ifTrue:[ ^ self ].

    queue := OrderedCollection with: methodTree scope.
    [ queue notEmpty ] whileTrue:[
        | scope |

        scope := queue removeFirst.
        1 to: scope localIndex do:[:i|
            | nm |

            nm := (scope locals at: i) name.
            (nm startsWith: prefix) ifTrue:[
                result add: (VariablePO instanceVariable: nm in: class). 
            ].
        ].
    ].

    "Created: / 03-10-2013 / 17:46:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 20-10-2013 / 02:15:51 / 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>"
!

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>"
    "Modified: / 08-04-2014 / 21:37:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaCompletionEngine methodsFor:'completion-private'!

complete
    
    | position entry node |

    position := context codeView characterPositionOfCursor.
    codeView syntaxElements notEmptyOrNil ifTrue:[
        entry := codeView syntaxElements atCharacterPosition: position - 1. 
        entry notNil ifTrue:[
            node := entry node
        ].
        codeView syntaxElements tree notNil ifTrue:[
            classTree := (codeView syntaxElements tree types ? #()) detect:[:t | (position - 1) between: t declarationSourceStart and: t declarationSourceEnd ] ifNone:[nil].
            classTree notNil ifTrue:[
                methodTree := (classTree methods ? #()) detect:[:m | (position - 1) between: m declarationSourceStart and: m declarationSourceEnd ] ifNone:[nil].
            ]
        ].
    ].

    context node: node position: position.

    node isNil ifTrue:[
        result := JavaCompletionEngineSimple new complete: context.
    ] ifFalse:[
        self completeNode: node.
    ].

    ^ result

    "Created: / 02-10-2013 / 13:55:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 13-05-2014 / 17:21:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !