Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xtext 2.9 scope provider

Xtext 2.9 changed the way scope providers work and I don't understand how they work now.

Let's say I have the following grammar:

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"

Model:
    ((things+=Thing) | (refs+=Reference))*
;

Thing:
    'thing' name=ID '{'
        stuff += Stuff* 
    '}'
;

Stuff:
    'stuff' name=ID
;

Reference:
    'reference' thing=[Thing] stuff=[Stuff] 
;

For the Reference clause to work, I need a scope provider.

XText 2.9 generates the following scope provider code for you (in MyDslScopeProvider.xtend):

class MyDslScopeProvider extends AbstractMyDslScopeProvider {
}

AbstractMyDslScopeProvider has no methods of it's own, it just inherits from DelegatingScopeProvider.

I can't wrap my head around how this works or where the code for the scope lookup should go. The "documentation" doesn't really help, because there's only useless code snippets instead of a complete working example.

Earlier versions of XText used AbstractDeclarativeScopeProvider and that was quite easy to understand and use, pre 2.9 it would have been:

class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
    def IScope scope_Reference_stuff(Reference reference, EReference ref) {
        scopeFor(reference?.thing.stuff)
    }
}
like image 765
J Burns Avatar asked Oct 18 '22 12:10

J Burns


1 Answers

You need to implement the getScope method

override getScope(EObject ctx, EReference ref) {
   if (ref == MyDslPackage.Literals.REFERENCE_THING) {
      return createScopeForThings()
   } else if (ref == MyDslPackage.Literals.REFERENCE_STUFF) {
      return createScopeForStuff()
   }
}

In your case you will get a call where the EObject is an instanceof Reference and the EReference is either MyDslPackage.Literals.REFERENCE_THING or MyDslPackage.Literals.REFERENCE_STUFF.

You need to create and return an instance of IScope, which can be used by the linker and content assist. See the JavaDoc of IScopeProvider and IScope for more details.

like image 57
Sven Efftinge Avatar answered Oct 21 '22 04:10

Sven Efftinge