java - Xtext 2.9 范围提供者

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

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

关于java - Xtext 2.9 范围提供者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36224089/

相关文章:

java - Java 中如何杀死一个线程?

java - 使用 java 在 JavaScript 中创建文件

dart - Dart 是否支持编写嵌入式 DSL?

language-agnostic - 序列图能否以与代码相同的深度真实地捕捉您的逻辑?

Cassandra 建模,我有十亿个某种数字代码要存储,我应该使用宽行(带有簇键的 CQL)吗?

timeout - 不同应用程序之间的超时建模

java - 性能 : Iterating through a List in Java

java - 在 Xtend 循环中使用唯一的变量名称(代码生成)

java - 基于条件的平均 Elasticsearch 查询

java - 为什么 try-with-resources catch block 是选择性可选的?