Перекрестная ссылка на Xtext: следующие имена параметров функции - PullRequest
0 голосов
/ 30 августа 2018

Я изо всех сил пытаюсь сделать перекрестную ссылку через имя параметра функции в определении функции, и сражаются с 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];

Эта грамматика отлично разбирается, но пунктирное использование имени параметра функции не связывает должным образом. Мой провайдер контекста следующий, последний метод создания исключений касается вторичной проблемы.

/*
 * 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 и Dot / Path и Концепции времени выполнения: Scoping . Я также видел решение раньше, но несколько дней безуспешно пытался его найти.

1 Ответ

0 голосов
/ 30 августа 2018

scope_ методы действительны только если вы наследуете от AbstractDeclarativeScopeProvider и он должен быть назван scope_FeatureRef_featureRef

и не забудьте вернуть

return Scopes::scopeFor(features)

важной частью является возврат

...