Xtext 交叉引用:遵循函数参数名称
Xtext Cross-Referencing: Following function parameter names
我正在努力通过函数定义中的函数参数名称进行交叉引用,和 正在努力争取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
语法如下,它通过简单的表达式语言用非常简单的函数概念定义扩展了标准示例。
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];
此语法解析完美,但函数参数名称的点式使用未正确链接。我的scope provider如下,后面的异常抛出方法是次要的问题。
/*
* 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("", [[=12=] + ]))
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 and Runtime Concepts:Scoping。我以前也看过这个解决方案,但是试了好几天都没有成功 Google 它。
scope_
方法只有在继承自 AbstractDeclarativeScopeProvider
时才有效
它应该被命名为 scope_FeatureRef_featureRef
别忘了return
return Scopes::scopeFor(features)
重要的部分是 return
我正在努力通过函数定义中的函数参数名称进行交叉引用,和 正在努力争取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
语法如下,它通过简单的表达式语言用非常简单的函数概念定义扩展了标准示例。
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];
此语法解析完美,但函数参数名称的点式使用未正确链接。我的scope provider如下,后面的异常抛出方法是次要的问题。
/*
* 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("", [[=12=] + ]))
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 and Runtime Concepts:Scoping。我以前也看过这个解决方案,但是试了好几天都没有成功 Google 它。
scope_
方法只有在继承自 AbstractDeclarativeScopeProvider
时才有效
它应该被命名为 scope_FeatureRef_featureRef
别忘了return
return Scopes::scopeFor(features)
重要的部分是 return