Поставщик области видимости Xtext 2.9

Xtext 2.9 изменил способ работы поставщиков областей, и я не понимаю, как они работают сейчас.

Допустим, у меня есть следующая грамматика:

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] 
;

Чтобы предложение Reference работало, мне нужен поставщик области.

XText 2.9 генерирует для вас следующий код поставщика области (в MyDslScopeProvider.xtend):

class MyDslScopeProvider extends AbstractMyDslScopeProvider {
}

AbstractMyDslScopeProvider не имеет собственных методов, он просто наследуется от DelegatingScopeProvider.

Я не могу понять, как это работает или куда должен идти код для поиска области. "Документация" не очень помогает, потому что вместо полного рабочего примера есть только бесполезные фрагменты кода.

Более ранние версии XText использовали AbstractDeclarativeScopeProvider, и это было довольно легко понять и использовать, до версии 2.9 это было бы так:

class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
    def IScope scope_Reference_stuff(Reference reference, EReference ref) {
        scopeFor(reference?.thing.stuff)
    }
}

person J Burns    schedule 25.03.2016    source источник


Ответы (1)


Вам нужно реализовать метод getScope

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

В вашем случае вы получите вызов, в котором EObject является экземпляром Reference, а EReference — либо MyDslPackage.Literals.REFERENCE_THING, либо MyDslPackage.Literals.REFERENCE_STUFF.

Вам нужно создать и вернуть экземпляр IScope, который может использоваться компоновщиком и помощником по содержимому. Дополнительные сведения см. в JavaDoc IScopeProvider и IScope.

person Sven Efftinge    schedule 25.03.2016
comment
Чего я до сих пор не совсем понимаю: для чего используется класс AbstractMyDslScopeProvider? MyDslScopeProvider может расширять DelegateScopeProvider напрямую, без промежуточного пустого абстрактного класса. - person J Burns; 26.03.2016