Xtext 2.9 scope provider
Asked Answered
A

1

6

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)
    }
}
Acquainted answered 25/3, 2016 at 16:39 Comment(0)
G
3

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.

Gibeonite answered 25/3, 2016 at 21:5 Comment(1)
What I still don't quite get: What is the AbstractMyDslScopeProvider class used for? MyDslScopeProvider could extend DelegateScopeProvider directly without the empty abstract class in between.Acquainted

© 2022 - 2024 — McMap. All rights reserved.