XText如何从另一个插件获取EObjects?

时间:2014-07-16 07:06:01

标签: xtext ecore

我开始开发一种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]

1 个答案:

答案 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;。