I started with the "Xtext Project" wizard of Xtext 2.3.1 using the default parameters. Note that this will use the scoping.ImportNamespacesScopingFragment that provides an easy-to-use global scoping.
Further, I slightly extended the grammar with a cross-reference:
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "www.xtext.org/example/mydsl/MyDsl"
Model:
persons+=Person*
greetings+=Greeting*
;
Person:
"Person" name=ID
;
Greeting:
"Hello" person=[Person] '!'
;
Now, I created a small "JUnit Plug-in Test". It exemplary shows how to create a simple model spread over two resources referring to each other:
package org.xtext.example.mydsl.tests;
import java.io.IOException;
import java.util.Collections;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.ui.XtextProjectHelper;
import org.junit.Test;
import org.xtext.example.mydsl.myDsl.Greeting;
import org.xtext.example.mydsl.myDsl.Model;
import org.xtext.example.mydsl.myDsl.MyDslFactory;
import org.xtext.example.mydsl.myDsl.Person;
import org.xtext.example.mydsl.ui.internal.MyDslActivator;
import com.google.inject.Injector;
public class StoreModelsWithReferenceTest {
@Test
public void test() throws IOException, CoreException {
// create models (simple example with one reference)
MyDslFactory factory = MyDslFactory.eINSTANCE;
Model m1 = factory.createModel();
Model m2 = factory.createModel();
Person p1 = factory.createPerson();
Person p2 = factory.createPerson();
p1.setName("Sven");
p2.setName("Sebastian");
m1.getPersons().add(p1);
m2.getPersons().add(p2);
Greeting g = factory.createGreeting();
g.setPerson(p1);
m2.getGreetings().add(g);
// create project (with Java and Xtext nature)
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
final String PROJECT_NAME = "example";
IProject project = root.getProject(PROJECT_NAME);
project.create(new NullProgressMonitor());
project.open(new NullProgressMonitor());
IProjectDescription description = project.getDescription();
String[] natures = description.getNatureIds();
String[] newNatures = new String[natures.length + 2];
System.arraycopy(natures, 0, newNatures, 0, natures.length);
newNatures[natures.length] = JavaCore.NATURE_ID;
newNatures[natures.length + 1] = XtextProjectHelper.NATURE_ID;
description.setNatureIds(newNatures);
project.setDescription(description, new NullProgressMonitor());
// create resources (two Xtext resources for the two models)
URI uri1 = URI.createPlatformResourceURI("/" + PROJECT_NAME + "/m1.mydsl", true);
URI uri2 = URI.createPlatformResourceURI("/" + PROJECT_NAME + "/m2.mydsl", true);
Injector injector = MyDslActivator.getInstance().getInjector(MyDslActivator.ORG_XTEXT_EXAMPLE_MYDSL_MYDSL);
XtextResourceSet xrs = injector.getInstance(XtextResourceSet.class);
XtextResource xtextResource1 = (XtextResource) xrs.createResource(uri1);
XtextResource xtextResource2 = (XtextResource) xrs.createResource(uri2);
xtextResource1.getContents().add(m1);
xtextResource2.getContents().add(m2);
// store resources (incremental build makes it visible to the second)
xtextResource1.save(Collections.EMPTY_MAP);
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new NullProgressMonitor());
xtextResource2.save(Collections.EMPTY_MAP);
}
}
I now wonder whether some of these steps in the test can be simplified. Any input is welcome.