Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Create new object when can't resolve reference(Make referencing a non-existent object create a new object, instead of producing an error.)
Create new object when can't resolve reference [message #1647720] Tue, 03 March 2015 15:27 Go to next message
Orlando Hill is currently offline Orlando HillFriend
Messages: 5
Registered: March 2015
Junior Member
Hi,

I would like to allow users to make cross-references to non-existent objects. Instead of producing an error, I would like to create a new object, based on the name used in the reference.

For example, with the following grammar,

Model:
        elements+=Element*;

Element:
        Person | Greeting;

Person:
        'person' name=ID;

Greeting:
        'Hello' person=[Person|ID] '!';


and the following input file,

Hello World!


a new Person object with name="World" should be created, because no such object is within scope.

Any suggestions on the cleanest way to achieve this behavior?

Thanks,
Orlando
Re: Create new object when can't resolve reference [message #1648164 is a reply to message #1647720] Tue, 03 March 2015 20:06 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14025
Registered: July 2009
Senior Member
Hi,
did you have a look at https://www.eclipse.org/forums/index.php/m/803468/
https://www.eclipse.org/forums/index.php/m/634532/ already


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/it-services/methods-and-tools/xtext
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Tue, 03 March 2015 20:07]

Report message to a moderator

Re: Create new object when can't resolve reference [message #1649926 is a reply to message #1648164] Wed, 04 March 2015 15:27 Go to previous messageGo to next message
Orlando Hill is currently offline Orlando HillFriend
Messages: 5
Registered: March 2015
Junior Member
Hi Christian,

Thanks, for your help. I hadn't seen those posts.

I now have the feature working.

I created a class that extends DefaultLinkingService,

package org.example.dsl;

import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.linking.impl.DefaultLinkingService;
import org.eclipse.xtext.linking.impl.IllegalNodeException;
import org.eclipse.xtext.nodemodel.INode;
import org.example.dsl.greeting.GreetingFactory;
import org.example.dsl.greeting.Person;

public class GreetingLinkingService extends DefaultLinkingService {
	@Override
	public List<EObject> getLinkedObjects(EObject context, EReference ref, INode node)
			throws IllegalNodeException {
		List<EObject> list = super.getLinkedObjects(context, ref, node);

		if (!list.isEmpty()) {
			return list;
		}
		
		String name = node.getText();
		// create a dummy URI with the DSL's file extension
		URI uri = URI.createURI("dummy:/" + name + ".greeting");
		ResourceSet resourceSet = context.eResource().getResourceSet();
		Resource resource = resourceSet.getResource(uri, false);
		Person person;

		if (resource == null) {
			person = GreetingFactory.eINSTANCE.createPerson();
			person.setName(name);
			resource = resourceSet.createResource(uri);
			List<EObject> contents = resource.getContents();
			contents.add(person);
		} else {
			person = (Person) resource.getContents().get(0);
		}

		return Collections.singletonList((EObject)person);
	}
}


and I use that class in the RuntimeModule.

package org.example.dsl;

import org.eclipse.xtext.linking.ILinkingService;

public class GreetingRuntimeModule extends org.example.dsl.AbstractGreetingRuntimeModule {
	@Override
	public Class<? extends ILinkingService> bindILinkingService() {
		return GreetingLinkingService.class;
	}
}


One small issue is that value conversion has not been run at that stage. In my real application, I use a STRING terminal, and need to manually convert to get the name of the element.

import org.eclipse.xtext.conversion.impl.STRINGValueConverter;
...
String name = new STRINGValueConverter().toValue(node.getText(), node);


Thanks, again,
Orlando
Re: Create new object when can't resolve reference [message #1649942 is a reply to message #1649926] Wed, 04 March 2015 15:39 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14025
Registered: July 2009
Senior Member
Hi,

am not sure about that,
shouldn't

final String crossRefString = getCrossRefNodeAsString(node);


already do that?


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/it-services/methods-and-tools/xtext
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Create new object when can't resolve reference [message #1650058 is a reply to message #1649942] Wed, 04 March 2015 16:46 Go to previous message
Orlando Hill is currently offline Orlando HillFriend
Messages: 5
Registered: March 2015
Junior Member
Hi,

Yes, you're right. Using getCrossRefNodeAsString() works, and is a much nicer solution.
Previous Topic:Injecting XtextSourceViewer
Next Topic:change builder sorter
Goto Forum:
  


Current Time: Tue Jul 27 10:11:44 GMT 2021

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

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

Back to the top