Tag Archives: xbase

Switching to Xcore in your Xtext language

This is a followup of my previous post, Switching from an inferred Ecore model to an imported one in your Xtext grammar. The rationale for switching to manually maintained metamodel can be found in the previous post. In this post, instead of using an Ecore file, we will use Xcore,

Xcore is an extended concrete syntax for Ecore that, in combination with Xbase, transforms it into a fully fledged programming language with high quality tools reminiscent of the Java Development Tools. You can use it not only to specify the structure of your model, but also the behavior of your operations and derived features as well as the conversion logic of your data types. It eliminates the dividing line between modeling and programming, combining the advantages of each.

I took inspiration from Jan Köhnlein’s blog post; after switching to a manually maintained Ecore in Xsemantics, I felt the need to further switch to Xcore, since I had started to write many operation implementations in the metamodel, and while you can do that in Ecore, using Xcore is much easier :) Thus in my case I was starting from an existing language, not to mention the use of Xbase (not covered in Jan’s post). Things were not easy, but once the procedure works, it is easily reproducible, and I’ll detail this for a smaller example.

So first of all, let’s create an Xtext project, org.xtext.example.hellocustomxcore, (you can find the sources of this example online at https://github.com/LorenzoBettini/Xtext2-experiments); the grammar of the DSL is not important: this is just an example. We will first start developing the DSL using the automatic Ecore model inference and later we will switch to Xcore.

(the language is basically the same of the previous post).

The grammar of this example is as follows:

grammar org.xtext.example.helloxcore.HelloXcore with 

generate helloxcore "http://www.xtext.org/example/hellocustomxcore/HelloXcore"


    'Hello' name=ID '!'

    'Greeting' name=ID expression = XExpression

and we run the MWE2 generator.

To have something working, we also write an inferrer

def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
   		acceptor.accept(element.toClass("generated." + element.eResource.URI.lastSegment.split("\\.").head.toFirstUpper))
   				for (hello: element.hellos) {
   					members += hello.toMethod
   							("say" + hello.name.toFirstUpper, hello.newTypeRef(String)) [
   						body = '''return "Hello «hello.name»";'''
   				for (greeting : element.greetings) {
   					members += greeting.toMethod
   							("say" + greeting.name.toFirstUpper, greeting.newTypeRef(String)) [
   						body = greeting.expression

With this DSL we can write programs of the shape (nothing interesting, this is just an example)

Hello foo!

Greeting bar {
    sayFoo() + "bar"

Now, let’s say we want to check in the validator that there are no elements with the same name; since both “Hello” and “Greeting” have the feature name, we can introduce in the metamodel a common interface with the method getName(). OK, we could achieve this also by introducing a fake rule in the Xtext grammar, but let’s do that with Xcore.

Switching to Xcore

Of course, first of all, you need to install Xcore in your Eclipse.

Before we use the export wizard, we must make sure we can open the generated .genmodel with the “EMF Generator” editor (otherwise the export will fail). If you get an error opening such editor about resolving proxy to JavaJVMTypes.ecore like in the following screenshot…


..then we must tweak the generated .genmodel and add a reference to JavaVMTypes.genmodel: open HelloXcore.genmodel with the text editor, and search for the part (only the relevant part of the line is shown)


and add the reference to the JavaVMTypes.genmodel:

usedGenPackages="../../../org.eclipse.xtext.common.types/model/JavaVMTypes.genmodel#//types ../../../org.eclipse.xtext.xbase/model/Xbase.genmodel#//xbase

Since we’re editing the .genmodel file, we also take the chance to modify the output folder for the model files to emf-gen (see also later in this section for adding emf-gen as a source folder):


And we remove the properties that relate to the edit and the editor plug-ins (since we don’t want to generate them anyway):


Now save the edited file, refresh the file in the workspace by selecting it and pressing F5 (yes, also this operation seems to be necessary), and this time you should be able to open it with the “EMF Generator” editor. We can go on exporting the Xcore file.

We want the files generated by Xcore to be put into the emf-gen source folder; so we add a new source folder to our project, say emf-gen, where all the EMF classes will be generated; we also make sure to include such folder in the build.properties file.

First, we create an .xcore file starting from the generated .genmodel file:

  • navigate to the HelloXcore.genmodel file (it is in the directory model/generated)
  • right click on it and select “Export Model…”
  • in the dialog select “Xcore”
  • The next page should already present you with the right directory URI
  • In the next page select the package corresponding to our DSL, org.xtext.example.helloxcore.helloxcore (and choose the file name for the exported .xcore file corresponding Helloxcore.xcore file)
  • Then press Finish
  • If you get an error about a missing EObjectDescription, remove the generated (empty) Helloxcore.xcore file, and just repeat the Export procedure from the start, and the second time it should hopefully work


The second time, the procedure should terminate successfully with the following result:

  • The xcore file, Helloxcore.xcore has been generated in the same directory of the .genmodel file (and the xcore file is also opened in the Xcore editor)
  • A dependency on org.eclipse.emf.ecore.xcore.lib has been added to the MANIFEST.MF
  • The new source folder emf-gen is full of compilation errors


Remember that the model files will be automatically generated when you modify the .xcore file (one of the nice things of Xcore is indeed the automatic building).

Fixing the Compilation Errors

These compilation errors are expected since Java files for the model are both in the src-gen and in the emf-gen folder. So let’s remove the ones in the src-gen folders (we simply delete the corresponding packages):


After that, everything compile fines!

Now, you can move the Helloxcore.xcore file in the “model” directory, and remove the “model/generated” directory.

Modifying the mwe2 workflow

In the Xtext grammar, HelloXcore.xtext, we replace the generate statement with an import:

//generate helloxcore "http://www.xtext.org/example/helloxcore/HelloXcore"
import "http://www.xtext.org/example/helloxcore/HelloXcore"

The DirectoryCleaner fragment related the “model” directory should be removed (otherwise it will remove our Helloxcore.xcore file as well); and we don’t need it anymore after we manually removed the generated folder with the generated .ecore and .genmodel files.

Then, in the language part, you need to loadResource the XcoreLang.xcore, the Xbase and Ecore ecore and genmodel, and finally the xcore file you have just exported, Helloxcore.xcore.

We can comment the ecore.EMFGeneratorFragment (since we manually maintain the metamodel from now on).

The MWE2 files is now as follows (I highlighted the modifications):

Workflow {
    bean = StandaloneSetup {
    	scanClassPath = true
    	platformUri = "${runtimeProject}/.."
    	// The following two lines can be removed, if Xbase is not used.
    	registerGeneratedEPackage = "org.eclipse.xtext.xbase.XbasePackage"
    	registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel"

    component = DirectoryCleaner {
    	directory = "${runtimeProject}/src-gen"

      // switch to xcore
//    component = DirectoryCleaner {
//    	directory = "${runtimeProject}/model"
//    }

    component = DirectoryCleaner {
    	directory = "${runtimeProject}.ui/src-gen"

    component = DirectoryCleaner {
    	directory = "${runtimeProject}.tests/src-gen"

    component = Generator {
    	pathRtProject = runtimeProject
    	pathUiProject = "${runtimeProject}.ui"
    	pathTestProject = "${runtimeProject}.tests"
    	projectNameRt = projectName
    	projectNameUi = "${projectName}.ui"
    	encoding = encoding
    	language = auto-inject {
    		// switch to xcore
        	loadedResource = "platform:/resource/org.eclipse.emf.ecore.xcore.lib/model/XcoreLang.xcore"
			loadedResource = "classpath:/model/Xbase.ecore"
    		loadedResource = "classpath:/model/Xbase.genmodel"
    		loadedResource = "classpath:/model/Ecore.ecore"
			loadedResource = "classpath:/model/Ecore.genmodel"
        	loadedResource = "platform:/resource/${projectName}/model/Helloxcore.xcore"

    		uri = grammarURI

    		// Java API to access grammar elements (required by several other fragments)
    		fragment = grammarAccess.GrammarAccessFragment auto-inject {}

    		// generates Java API for the generated EPackages
    		// switch to xcore
    		// fragment = ecore.EMFGeneratorFragment auto-inject {}

Before running the workflow, you also need to add org.eclipse.emf.ecore.xcore as a dependency in your MANIFEST.MF.

We can now run the mwe2 workflow, which should terminate successfully.

We must now modify the plugin.xml (note that there’s no plugin.xml_gen anymore), so that the org.eclipse.emf.ecore.generated_package extension point contains the reference to the our Xcore file:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>


  <extension point="org.eclipse.emf.ecore.generated_package">
       uri = "http://www.xtext.org/example/helloxcore/HelloXcore" 
       class = "org.xtext.example.helloxcore.helloxcore.HelloxcorePackage"
       genModel = "model/Helloxcore.xcore" /> 



Fixing Junit test problems

As we saw in the previous post, Junit tests do not work anymore with errors of the shape

org.eclipse.xtext.parser.ParseException: java.lang.IllegalStateException: Unresolved proxy http://www.xtext.org/example/helloxcore/HelloXcore#//Hello. Make sure the EPackage has been registered.

All we need to do is to modify the StandaloneSetup in the src folder (NOT the generated one, since it will be overwritten by subsequent MWE2 workflow runs) and override the register method so that it performs the registration of the EPackage (as it used to do before):

public class HelloXcoreStandaloneSetup extends HelloXcoreStandaloneSetupGenerated{

	public static void doSetup() {
		new HelloXcoreStandaloneSetup().createInjectorAndDoEMFRegistration();

	public void register(Injector injector) {
		// added after the switching to Xcore
		if (!EPackage.Registry.INSTANCE.containsKey("http://www.xtext.org/example/helloxcore/HelloXcore")) {
			EPackage.Registry.INSTANCE.put("http://www.xtext.org/example/helloxcore/HelloXcore", org.xtext.example.helloxcore.helloxcore.HelloxcorePackage.eINSTANCE);


And now the Junit tests will run again.

Modifying the metamodel with Xcore

We can now customize our metamodel, using the Xcore editor.

For example, we add the interface Element, with the method getName() and we make both Hello and Greeting implement this interface (they both have getName() thus the implementation of the interface is automatic).

interface Element {
	op String getName()

class Hello extends Element {
	String name

class Greeting extends Element {
	String name
	contains XExpression expression

Using the Xcore editor is easy, and you have content assist; as soon as you press save, the Java files will be automatically regenerated:


We also add a method getElements() to the Model class returning an Iterable<Element>(containing both the Hello and the Greeting objects). This time, with Xcore, it is really easy to do so (compare that with the procedure of the previous post, requiring the use of EAnnotation in the Ecore file), since Xcore uses Xbase expression syntax for defining the body of the operations (with full content assist, not to mention automatic import statement insertions). See also the generated Java code on the right:


And now we can implement the validator method checking duplicates, using the new getElements() method and the fact that now both Hello and Greeting implement Element:

package org.xtext.example.helloxcore.validation

import org.eclipse.xtext.validation.Check
import org.eclipse.xtext.xbase.typesystem.util.Multimaps2
import org.xtext.example.helloxcore.helloxcore.Element
import org.xtext.example.helloxcore.helloxcore.Model

class HelloXcoreValidator extends AbstractHelloXcoreValidator {

	public static val DUPLICATE_NAME = 'HelloXcoreDuplicateName'

	def checkDuplicateElements(Model model) {
		val nameMap = <String,Element>Multimaps2.newLinkedHashListMultimap
		for (e : model.elements)
			nameMap.put(e.name, e)
		for (entry : nameMap.asMap.entrySet) {
			val duplicates = entry.value
			if (duplicates.size > 1) {
				for (d : duplicates)
						"Duplicate name '" + entry.key + "' (" + d.eClass.name + ")",

That’s all! I hope you found this tutorial useful :)


Be Sociable, Share!

The XImportSection in Xbase 2.4

I know that Xtext 2.4 has not been released yet, but I could not resist blogging about a very cool new feature in Xbase: improved automatic import functionalities!

Actually, import functionalities were already great when using Xbase also in previous versions of Xtext, but now they provide a much better experience for the user of your DSL! Indeed, all the import functionalities you are used to with JDT (like automatic import insertion, and organize imports) are available also for your Xbase language; these features were already available in Xtend, and they have been ported to Xbase itself.

At the time of writing, you need to get the very latest updates of Xtext 2.4, using the update site http://download.eclipse.org/modeling/tmf/xtext/updates/composite/latest/ .

Before you used to do something like

grammar org.xtext.example.helloinferrer.HelloInferrer with 

generate helloInferrer "http://www.xtext.org/example/helloinferrer/HelloInferrer"

	imports += Import*

  'import' importedNamespace = QualifiedNameWithWildcard


Now, you can use in your grammar the new Xbase rule: XImportSection:

grammar org.xtext.example.helloinferrer.HelloInferrer with 

generate helloInferrer "http://www.xtext.org/example/helloinferrer/HelloInferrer"



In this post I’m reusing some experiments you can find here (https://github.com/LorenzoBettini/Xtext2-experiments, I had blogged about these experiments in previous posts).

If you now rerun the MWE2 generator, and make sure you merge the plugin.xml_gen with plugin.xml in the .ui project, your editor will provide some interesting features for free (if you use my examples, you can find a project wizard “New Project” => “Xtext” => “HelloInferrer Project”):

Imports with wildcards are deprecated:


You now have the context menu “Organize Imports” (Shift + Control + O); try that one in the presence of such deprecation warning and imports are organized for you:


Similarly, unused imports are reported as warnings:


Again, use “Organize Imports” to fix that!

The new feature I like most is the automatic insertion of imports! (just like in JDT and Xtend): try to get content assist for a Java type, for instance,


Accept a proposal and the import will be automatically inserted (instead of the fully qualified name):


Xtext rocks! :)

Be Sociable, Share!