我开始开发一种XText DSL,它现在有两种子语言,它们相互引用(更准确地说,A指的是B)。它们每个都有自己的插件和生成器工作流程。
相关部分看起来像这样:
语言A:
ARoot:
'rootOfB:' (foos+=Foo)*;
Foo:
'foo' name=ID;
语言B:
import 'url-of-a' as A
BRoot:
'rootOfA:' (bars+=Bar)*;
Bar:
'bar' name=ID 'for' foo=[A::Foo] ;
现在我尝试提供一个范围提供程序,以便在语言B foo
元素被识别,但我还没有找到方法来访问A的已解析元素。
我做了一些调试,看起来参数foo和eReference都没有任何与语言A元素的连接:
class MyScopeProvider extends AbstractDeclarativeScopeProvider {
def IScope scope_Bar_foo(Bar bar, EReference eReference){
// How should i reference and return all the Foo objects here?
}
}
Foo元素也有一个完全限定的名称提供者,因此不应该是一个问题,我从另一个范围测试它,同时仍在处理插件A:
class MyQualifiedNameProvider extends DefaultDeclarativeQualifiedNameProvider {
override qualifiedName(Object o) {
if (o instanceof Foo) {
val f = o as Foo
return QualifiedName.create(f.name)
}
super.qualifiedName(o);
}
}
所以我的问题是:我如何在不同的插件中获得解析的EObject?
使用示例:
使用语法A:
的文件内容rootOfA
foo firstFoo
foo secondFoo
使用语法B的文件内容:
rootOfB
bar firstBar for [i would like reference firstFoo or secondFoo here]
答案 0 :(得分:1)
你必须在插件B的Manifest中为插件A添加一个依赖项。 您还必须在工作流mwe2中添加依赖项。
有关详细信息,请参阅http://www.eclipse.org/Xtext/documentation.html#grammarMixins。
修改1
您正在尝试引用其他资源。本文解释了本地和全球范围之间的差异: http://blogs.itemis.de/leipzig/archives/809
ScopeProvider不适用于此处。您应该为插件A实现自己的ResourceDescriptionStrategy,以描述您想要从资源A导出的EObject。 在ScopeProvider(插件B)中,您必须调用delegateGetScope()以具有全局范围(A + B)。
修改2
如果要在两个不同的项目之间进行链接工作,可以使用以下Eclipse标准机制:
右键单击项目B并打开属性,然后转到"项目参考"。您将看到项目A,您只需选择它。
完成后,清理你的两个项目,你的链接就可以了。
编辑3
这是ResourceDescriptionStrategy的自定义实现示例:
public class MyResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy {
@Override
public boolean createEObjectDescriptions(EObject eObject,
IAcceptor<IEObjectDescription> acceptor) {
if (eObject instanceof Foo) {
QualifiedName fullyQualifiedName = getQualifiedNameProvider().getFullyQualifiedName(eObject);
IEObjectDescription ieObjectDescription = EObjectDescription.create(fullyQualifiedName, eObject);
acceptor.accept(ieObjectDescription);
return true;
}
return super.createEObjectDescriptions(eObject, acceptor);
}
}
您必须在插件A RuntimeModule中绑定此类:
public Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
return MyResourceDescriptionStrategy.class;
}
这是使用&#34;全局范围&#34;:
的ScopeProvider实现示例def IScope scope_Bar_foo(Bar bar, EReference eReference){
return delegateGetScope(bar, eReference);
}
在此示例中,它仅搜索全局范围。如果想要在范围中添加其他东西,您应该使用SimpleScope来管理&#34;父范围&#34;。