Couldn't resolve reference in DSL using Xtext [message #1810568] |
Tue, 13 August 2019 10:38  |
Eclipse User |
|
|
|
Hi,
i have this grammar:
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl
Root:
'root' name=ROOT_FQN ('extends' parentRoot=[Root|ROOT_FQN])? '{'
('Values-Catalog' '{'
values+=(Values)*
'}')?
('Models-Catalog' '{'
models+=(Model)*)?
'}'
'}';
Values:
StringValue | ModelValue;
StringValue:
name=ID type='string' (array?='[' length=INT ']')?;
ModelValue:
name=ID type=[Model|MODEL_FQN] (description=STRING)? ;
Model:
type=('data' | 'static')? name=ID ('extends' parentModel=[Model|MODEL_FQN])? '{'
data+=Data*
'}';
Data:
name=ID;
terminal VERSION:
INT '.' INT '.' INT;
terminal ROOT_FQN:
ID '-' VERSION;
terminal MODEL_FQN:
ROOT_FQN '.' ID;
The root should be able to have a parent root. A value can be a simple type or a model from the current root or it's parents. A model can have a parent model from the current root or it's parents. With this grammar i can extend another model and crate a model value using a model from any root that is in the workspace without having the reference issue. I have wrote a scope provider that will limit the models to the ones from the current root or it's parents. I get the right list of models in the context menu but when want to extend a model and select one from the list i get 'Couldn't resolve a reference to rootName.modelName', however when i try to create a value using a model from the same restricted list i don't get any errors. Here's the scope provider:
class MyDslScopeProvider extends AbstractMyDslScopeProvider {
val ePackage = MyDslPackage.eINSTANCE
override getScope(EObject context,EReference reference){
if(reference == ePackage.model_ParentModel){
return scopeForParentModel(context as Model, reference)
}
if(reference == ePackage.values){
return scopeForValueParentModel(context,reference);
}
return super.getScope(context, reference)
}
//scope for the parent of a model
def protected IScope scopeForParentModel(Model context, EReference reference) {
val container=context.eContainer as Root;
val List<Model> models=newArrayList;
setModels(container, models);
return Scopes::scopeFor(models, [QualifiedName.create((it.eContainer as Root).name , it.name)],IScope.NULLSCOPE) [img]index.php/fa/36091/0/[/img]
}
//scope for model values
def protected IScope scopeForValueParentModel(EObject context, EReference reference) {
val container = context as Root
val List<Model> entities = newArrayList;
setModels(container, entities);
return Scopes::scopeFor(entities, [QualifiedName.create((it.eContainer as Root).name, it.name)],
IScope.NULLSCOPE);
}
//recursive method that will store all the models from the root hierarchy in the models list
def protected void setModels(Root context, List<Model> models) {
models.addAll(context.models);
if (context.parentRoot !== null) {
setModels(context.parentRoot, models);
}
}
}
As i have looked through similar topics and question online i have created a simple QualifiedNameProvider and one using a converter ( converter.toQualifiedName(object.eContainer.fullyQualifiedName + "." + object.name) , and i bound it to the runtime module ) but i still get the reference error, any suggestions?
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04500 seconds