Xtext 2.9范围提供者

时间:2016-03-25 16:39:33

标签: java dsl modeling xtext xtend

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

要使Ref​​erence子句起作用,我需要一个范围提供者。

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)
    }
}

1 个答案:

答案 0 :(得分:3)

您需要实施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的实例,链接器和内容辅助可以使用该实例。有关详细信息,请参阅IScopeProviderIScope的JavaDoc。