Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Couldn't resolve reference in DSL using Xtext
Couldn't resolve reference in DSL using Xtext [message #1810568] Tue, 13 August 2019 14:38 Go to next message
Loredana Hozan is currently offline Loredana HozanFriend
Messages: 34
Registered: January 2019
Member
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?
index.php/fa/36091/0/
Re: Couldn't resolve reference in DSL using Xtext [message #1810636 is a reply to message #1810568] Wed, 14 August 2019 20:19 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
you create Qualified Names with

QualifiedName.create

in this case you have to make sure the segments are correct (dont contain .)
as you have already found out you can use qualfied name converter for that
(or make sure otherwise e.g.)

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.split("\\.")).append(it.name)
		],IScope.NULLSCOPE)
	
	}


or

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, [
			converter.toQualifiedName((it.eContainer as Root).name + "."+it.name)
		],IScope.NULLSCOPE)
	
	}
	
	@Inject
	IQualifiedNameConverter converter


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Couldn't resolve reference in DSL using Xtext [message #1810925 is a reply to message #1810636] Thu, 22 August 2019 07:19 Go to previous message
Loredana Hozan is currently offline Loredana HozanFriend
Messages: 34
Registered: January 2019
Member
Thank you so much, it worked :)
Previous Topic:Fine-grained control of caching in Xtext
Next Topic:Is there a recommended way to turn the inferred Ecore model into imported one?
Goto Forum:
  


Current Time: Fri Apr 26 03:25:46 GMT 2024

Powered by FUDForum. Page generated in 0.03158 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top