我正在努力通过函数定义中的函数参数名称进行交叉引用,和正在与Google寻求解决方案。请考虑以下示例。
def helloWorld() {
return "Hello World!"
}
def combine(Person person, Place place) {
return person.name + place.code // ❎ Couldn't resolve reference to Feature 'name'.
}
entity Person {
name: String
title : String
occupation : String
}
entity Place {
name: String
code:String
}
datatype String
语法如下,它通过简单的表达语言以非常简单的功能 definition 的简单概念扩展了标准示例。
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Domainmodel :
(
elements+=Type |
functions+=Function // Note Functions
)*;
/******************** Functions ********************/
Function : 'def' name=ID '('
(parameters+=Parameter (',' parameters+=Parameter)*)?
')' '{' 'return' exp=Exp '}'
;
Parameter: type=[Entity] name=ID;
Exp:
TerminalExp
({Exp.left=current}
'+'
right=TerminalExp)*;
TerminalExp : value=STRING | dotExpression = DotExpression;
/******************** PROBLEM AREA ********************/
DotExpression : parameterRef=[Parameter] '.' featureRef=FeatureRef;
FeatureRef : featureRef=[Feature];
/******************** THE USUAL ********************/
Type:
DataType | Entity;
DataType:
'datatype' name=ID;
Entity:
'entity' name=ID '{'
(features+=Feature)*
'}';
Feature:
name=ID ':' type=[Type];
此语法可完美解析,但是点缀使用函数参数名称不能正确链接。我的作用域提供者如下,后一种异常抛出方法涉及一个次要问题。
/*
* generated by Xtext 2.14.0
*/
package org.xtext.example.mydsl.scoping
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes
import org.xtext.example.mydsl.myDsl.DotExpression
import org.xtext.example.mydsl.myDsl.FeatureRef
class MyDslScopeProvider extends AbstractMyDslScopeProvider {
override getScope(EObject context, EReference reference) {
if (context instanceof FeatureRef) {
val myDotExpression = (context as EObject/*?*/).eContainer as DotExpression
val features = myDotExpression.parameterRef.type.features
println("### " + features.stream.map["[" + name + "]"].reduce("", [$0 + $1]))
Scopes::scopeFor(features)
}
super.getScope(context, reference)
}
def IScope scope_FeatureRef(FeatureRef context, EReference ref) {
println("### I have been called")
throw new RuntimeException("I HAVE BEEN CALLED!");
}
}
以下输出证明(1)找到了正确的对象,并且它们具有预期的名称;(2)从不调用后一种方法。
### [name][title][occupation]
### [name][code]
### [name][title][occupation]
### [name][code]
我已阅读Xtext and Dot/Path-Expressions和Runtime Concepts:Scoping。我之前也曾看过该解决方案,但尝试使用Google几天却失败了。
答案 0 :(得分:2)
scope_
方法仅在您从AbstractDeclarativeScopeProvider
继承时才有效
它应该命名为scope_FeatureRef_featureRef
别忘了回来
return Scopes::scopeFor(features)
重要的部分是返回