Wednesday, June 12, 2013

Using Xcore in Xtext

With Xtext you can easily create your own textual language. The structure of the language is defined in an Ecore model. This model can be automatically derived from the grammar, which allows quick turnarounds in the beginning. But in the long run, this model becomes an increasingly important API to the language. You want to fix it and make it a first class artifact: You are switching from an inferred Ecore model to an imported one in the grammar.

Traditionally, you use EMF's tree editors to edit Ecore models. That can be cumbersome as the tooling is not the nicest to use. Furthermore, the Ecore model only describes the declarative part. Behavior, such as the body of EOperations or the code for derived EStructuralFeatures has to be woven in either from additional models or directly in the generated code. These and more issues are addressed by Xcore. Xcore allows to specify Ecore models textually, including the behavioral parts and the code generation parameters. Having a single source of information facilitates the maintanance of such a model drastically. Xcore is shipped with EMF.

In the upcoming Eclipse release 4.3 (Kepler) Xcore and Xtext can be used together. Here is a step-by-step example how to do this with Xtext's "Greetings" language:
  1. Create an Xtext project File > New > Project > Xtext Project. The defaults are fine. This will create the usual four projects for your Xtext language in your workspace.
  2. By default, Xcore generates its code to the folder src-gen. The same folder is used by Xtext and will be wiped each time you regenerate the language from the grammar. To avoid loosing data, choose a separate output folder for Xcore: Eclipse/Window > Preferences > Xcore > Compiler > Output Folder > Directory > ./emf-gen

  3. Create a new folder model in the root of org.xtext.example.mydsl and file Greetings.xcore inside that folder. Our Ecore model consists of an EPackage org.xtext.example.mydsl, two EClasses Model and Greetings, a containment EReference greetings and an EAttribute name. In Xcore, this looks like
:

  4. Open the grammar MyDsl.xtext. By default, the Ecore model myDsl is generated from the grammar rules. We want to replace this with the Ecore model specified in the Xcore file:

  5. We have to load the Xcore model in the workflow GenerateMyDsl.mwe2 of the language generator. Add an appropriate loadedResource entry to the language section:

    module org.xtext.example.mydsl.GenerateMyDsl
    ...
    Workflow {
      ...
      component = Generator {
        ...
        language = auto-inject {
          loadedResource =
    "platform:/resource/${projectName}/model/Greetings.xcore"
          uri = ...
    
  6. You have to add a dependency to org.eclipse.emf.xcore in the MANIFEST.MF of the project.
  7. Now generate the language infrastructure Run As > MWE2 Workflow. There should not be any error.
  8. Make sure that all folders will be correctly deployed. Your build.properties file should look like this
:
  9. Launch a new Eclipse workbench Run > Run Configurations > Eclipse Application > Launch Runtime Eclipse and enjoy your language in action.
For the geeky fun of it: As Xcore is itself implemented in Xtext with an imported Ecore model, this lays the foundation to replace Xcore.ecore with Xcore.xcore and thereby bootstraping it.
Sorry, I couldn't resist ;-)

11 comments:

Christian Dietrich said...

Does this include the Xcore 2 Java Generation or do i have to use the eclipse builder for that?

Jan Köhnlein said...

Currently we rely on the Eclipse builder for the Xcore code generator. I am not aware of an MWE component for that. Sounds like an enhancement request for bugzilla ;-)

John Kozlov said...

I encountered the following error while editing my *.mydsl file:

org.eclipse.xtext.parser.ParseException: java.lang.IllegalStateException: Unresolved proxy platform:/resource/org.xtext.example.mydsl/model/Greetings.xcore#/EPackage/Greeting. Make sure the EPackage has been registered.

Jérémie Bresson said...

Thank you for blogging on Xcore...

I have started to use it, and using DSL to define EMF model is really cool (in my opinion much better than clicking in the ecore tree editor).

I think the project deserve a bigger audience.

Jan Köhnlein said...

@John Are you using the latest RC4 builds of both projects? Please also make sure the EPackage is correctly registered in the plugin.xml of the org.xtext.example.mydsl plug-in. If it's empty, delete it, then first rerun the Xcore generator and then the Xtext generator.

Oliver L said...

@Jan Do you know if any Xcore standalone generator exists?

Based on that writing an IWorkflowComponent adapter should be straight-forward.

Miles Parker said...

Jan, do you have a longer example of the workflow? I'm moving from a genmodel based implementation, and it's not clear what to do w/ the Standalone setup, or if I even still need that.

Jan Köhnlein said...

StandaloneSetup is still necessary, but you should not have to register the .ecore and .genmodel files of your Xcore model.

Miles Parker said...

Thanks Jan, please see my follow-up at http://www.eclipse.org/forums/index.php/m/1082529/#msg_1082529

Rafael Chaves said...

I know it is an older post, but it seems there isn't an o.e.emf.xcore plugin to require (step 6), however there is a org.eclipse.emf.ecore.xcore plugin.
Same thing?

Jan Köhnlein said...

@Raphael This should be the right one.