Xtext如何通过实例通过限定名引用变量?
Xtext how to reference variables by qualified name through an instance?
我在构建 dsl 时遇到了这个概念的问题。我不确定这是我遗漏的简单事情还是不是 xtext 的预期功能。希望有人可以在此示例的上下文中向我解释。
给定以下最小语法:
Model:
'ns' name=QualifiedName
classes+=Class*
instances+=Instance*
uses+=Use*
;
Class:
'class' name=ID '{'
variables+=Variable*
'}'
;
Variable:
'var' variable=PrimaryVariable
;
Instance:
variable=PrimaryVariable '=' 'new' type=[Class]
;
Use:
reference=[PrimaryVariable|QualifiedName]
;
PrimaryVariable:
name=ID
;
QualifiedName:
ID ('.' ID)*
;
我希望能够编写以下代码,这当然是无效的:
ns com.mine
class Class1 {
var var1
}
instance1 = new Class1
instance1.var1 // <- error here, can't resolve reference
使用这个语法和默认范围,只有这个可以工作:
ns com.mine
class Class1 {
var var1
}
instance1 = new Class1
Class1.var1
所以我的问题是:我将如何通过实例变量实现通过限定名称引用变量的概念?
我认为我无法 qualifiedNameProvider
实现此目的,因为 PrimaryVariable
不知道它在哪个实例中使用。
我当然可以创建一个使用两个引用的规则(这就是我目前正在做的),一个是实例变量,然后遍历实例变量的类型以获取变量引用范围内的变量,但是这个在嵌套对象的情况下,这似乎是对它应有的方式的一种破解,而不是可扩展的。
这是一个稍微宽泛的问题,我希望在我去做一些完全适得其反的事情之前能得到通知。
这是范围提供程序的示例
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.EcoreUtil2
import org.eclipse.xtext.naming.QualifiedName
import org.eclipse.xtext.resource.EObjectDescription
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.impl.SimpleScope
import org.xtext.example.mydsl6.myDsl.Model
import org.xtext.example.mydsl6.myDsl.MyDslPackage
class MyDslScopeProvider extends AbstractMyDslScopeProvider {
override getScope(EObject context, EReference reference) {
if (reference === MyDslPackage.Literals.USE__REFERENCE) {
val model = EcoreUtil2.getContainerOfType(context, Model)
if (model !== null) {
val result = newArrayList
for (i : model.instances) {
result.add( EObjectDescription.create(
QualifiedName.create( i.variable.name ), i.variable ))
for (v : i.type.variables) {
result.add( EObjectDescription.create(
QualifiedName.create( i.variable.name, v.variable.name ),
v.variable ))
}
}
println(result)
return new SimpleScope(IScope.NULLSCOPE, result)
}
}
super.getScope(context, reference)
}
}
我在构建 dsl 时遇到了这个概念的问题。我不确定这是我遗漏的简单事情还是不是 xtext 的预期功能。希望有人可以在此示例的上下文中向我解释。
给定以下最小语法:
Model:
'ns' name=QualifiedName
classes+=Class*
instances+=Instance*
uses+=Use*
;
Class:
'class' name=ID '{'
variables+=Variable*
'}'
;
Variable:
'var' variable=PrimaryVariable
;
Instance:
variable=PrimaryVariable '=' 'new' type=[Class]
;
Use:
reference=[PrimaryVariable|QualifiedName]
;
PrimaryVariable:
name=ID
;
QualifiedName:
ID ('.' ID)*
;
我希望能够编写以下代码,这当然是无效的:
ns com.mine
class Class1 {
var var1
}
instance1 = new Class1
instance1.var1 // <- error here, can't resolve reference
使用这个语法和默认范围,只有这个可以工作:
ns com.mine
class Class1 {
var var1
}
instance1 = new Class1
Class1.var1
所以我的问题是:我将如何通过实例变量实现通过限定名称引用变量的概念?
我认为我无法 qualifiedNameProvider
实现此目的,因为 PrimaryVariable
不知道它在哪个实例中使用。
我当然可以创建一个使用两个引用的规则(这就是我目前正在做的),一个是实例变量,然后遍历实例变量的类型以获取变量引用范围内的变量,但是这个在嵌套对象的情况下,这似乎是对它应有的方式的一种破解,而不是可扩展的。
这是一个稍微宽泛的问题,我希望在我去做一些完全适得其反的事情之前能得到通知。
这是范围提供程序的示例
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.EcoreUtil2
import org.eclipse.xtext.naming.QualifiedName
import org.eclipse.xtext.resource.EObjectDescription
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.impl.SimpleScope
import org.xtext.example.mydsl6.myDsl.Model
import org.xtext.example.mydsl6.myDsl.MyDslPackage
class MyDslScopeProvider extends AbstractMyDslScopeProvider {
override getScope(EObject context, EReference reference) {
if (reference === MyDslPackage.Literals.USE__REFERENCE) {
val model = EcoreUtil2.getContainerOfType(context, Model)
if (model !== null) {
val result = newArrayList
for (i : model.instances) {
result.add( EObjectDescription.create(
QualifiedName.create( i.variable.name ), i.variable ))
for (v : i.type.variables) {
result.add( EObjectDescription.create(
QualifiedName.create( i.variable.name, v.variable.name ),
v.variable ))
}
}
println(result)
return new SimpleScope(IScope.NULLSCOPE, result)
}
}
super.getScope(context, reference)
}
}