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)
}
}
最佳答案
你需要实现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 是一个 instanceof Reference
并且 EReference 是 MyDslPackage.Literals.REFERENCE_THING 或 MyDslPackage.Literals.REFERENCE_STUFF。
您需要创建并返回一个IScope
的实例,它可以被链接器和内容助手使用。有关详细信息,请参阅 IScopeProvider
和 IScope
的 JavaDoc。
关于java - Xtext 2.9 范围提供者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36224089/