Search code examples
javadslxtext

Importing Java class from Xtext dsl


I am new to Xtext. I use a model class in my dsl like that:

Model abc:
 variable1
 variable2

and import class like that:

import a.b.c

What I want to do is, when I say import a.b.c (which is a java class in same directory). Editor must recognise this a.b.c class and refer it as a model like:

modelname = classname

variable names = variables in the class.

I wrote a different class too, which gets the references of variables in model class. So, if I say variable1 in that class and if there is no variable named variable1 in all models there will be a syntax error. It works when I write a model class in dsl, however I could not do it with using my import class.

Thanks for any help.


Solution

  • here may be a starting point

    grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.xbase.Xbase
    
    generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
    
    import "http://www.eclipse.org/xtext/common/JavaVMTypes" as types
    
    Model:
        imports=XImportSection?
        elements+=Element*
        ;
    
    Element:
        "element" "{"
            "modelname" "=" type=JvmTypeReference
            "variable" "names" "=" memberReferences+=MemberReference ("," memberReferences+=MemberReference)*
        "}"
    ;
    
    MemberReference:
        member=[types::JvmField|ID]
    ;
    

    and following adaption of the scope provider

    package org.xtext.example.mydsl.scoping
    
    import org.eclipse.emf.ecore.EObject
    import org.eclipse.emf.ecore.EReference
    import org.eclipse.xtext.EcoreUtil2
    import org.xtext.example.mydsl.myDsl.Element
    import org.xtext.example.mydsl.myDsl.MyDslPackage
    import org.eclipse.xtext.scoping.IScope
    import org.eclipse.xtext.scoping.Scopes
    import org.eclipse.xtext.common.types.JvmDeclaredType
    import org.eclipse.xtext.naming.QualifiedName
    
    class MyDslScopeProvider extends AbstractMyDslScopeProvider {
    
        override getScope(EObject context, EReference reference) {
            if (reference == MyDslPackage.Literals.MEMBER_REFERENCE__MEMBER) {
                val element = EcoreUtil2.getContainerOfType(context, Element)
                if (element != null)  {
                    val type = element.type.type
                    if (type instanceof JvmDeclaredType) {
                        return Scopes.scopeFor(type.declaredFields, [QualifiedName.create(simpleName)], IScope.NULLSCOPE)
                    }
                }
                return IScope.NULLSCOPE
            }
            super.getScope(context, reference)
        }
    
    }
    

    proposal provider

    class MyDslProposalProvider extends AbstractMyDslProposalProvider {
    
        override protected isKeywordWorthyToPropose(Keyword keyword) {
            true
        }
    
    }