【问题标题】:Xtext Cross-Referencing: Following function parameter namesXtext 交叉引用:以下函数参数名称
【发布时间】:2018-08-30 19:19:53
【问题描述】:

我正在努力通过函数定义中的函数参数名称进行交叉引用,并且与谷歌争夺解决方案。考虑以下示例。

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

此语法解析完美,但函数参数名称的虚线使用未正确链接。我的范围提供程序如下,后一种异常抛出方法涉及次要问题。

/*
 * 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]
  1. 我在第一个范围方法中犯了什么错误?
  2. 为什么从不调用后一种方法?

我已阅读 Xtext and Dot/Path-ExpressionsRuntime Concepts:Scoping。我之前也看到过解决方案,但尝试了几天谷歌都没成功。

【问题讨论】:

    标签: xtext


    【解决方案1】:

    scope_ 方法只有在继承自 AbstractDeclarativeScopeProvider 时才有效 并且应该命名为scope_FeatureRef_featureRef

    别忘了回来

    return Scopes::scopeFor(features)

    重要的部分是回报

    【讨论】:

    • 那么,您打算如何解决这个问题?让类继承还是改变其他部分?
    • 两者都可以。我建议在 getScope 中替换 scope_with if else
    • 但这不是我在第一种方法中所做的吗?第二个 scope_ 方法没有被调用。正在调用纯 getScope 方法,但不明白为什么它不起作用。它正在返回似乎是正确的提案,并且这些提案似乎从输出中具有正确的名称。 getScope 方法有什么问题?
    • 我已更改为 AbstractDeclarativeScopeProvider。输出和之前一模一样:没有调用scope_方法,调用了getScope方法,输出和上面一样。
    • 假名应该是scope_FeatureRef_feature
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多