Search code examples
xtext

Xtext Scope and Name provider


How do you integrate a scope provider and a custom name for a grammar rule?

The grammar

Model:
    g+=Greeting+
    (vis+=Visible)*
    ref=Ref;
Ref:
    'ref_greeting' grt=[Greeting];
Visible:
     'vis' make=[Greeting]; 
Greeting:
    'Hallo' name=ID '!';

The rule Visible is used to define Greeting that are visible from other, for the scope of the rule Ref. The two input files are:

Hallo hallo!
Hallo hallo_other_vis!
ref_greeting hallo

and

Hallo h!
vis hallo_other_vis
ref_greeting hallo_other_vis   <--- error here

For the scope of the second file h is visible but not hallo_other_vis which must be visible for the desired results.

The scope provider is:

override getScope(EObject context, EReference reference) {
    if(context instanceof Ref && reference == MyDslPackage.Literals.REF__GRT){
        var root =  EcoreUtil2.getContainerOfType(context, Model)
        var scope = Scopes.scopeFor(root.g)
        if(root.vis !== null){
            return Scopes.scopeFor(root.vis, scope) /// XXX is this correct
        }
    }
    return super.getScope(context, reference)
}

Solution

  • when you scope greetings you have to collect greetings

    return Scopes.scopeFor(root.vis, scope)
    

    collects Visibles and not Greetings so you should fix that e.g.

    return Scopes.scopeFor(root.vis.map[make], scope)