Feb 19th 2016

Xtext's new Generator: migration

Dr. Jan KöhnleinDr. Jan Köhnlein

Xtext 2.9 ships with a new generator architecture, which is described in the previous post. Even though there is no immediate urge to migrate an existing language to the new generator infrastructure, here is how to do it. Make sure to keep a copy of your old code in order to safely roll back in case something goes wrong. If you customized a lot or if you want additional functionality such as IDEA, Web or Maven support, it may be easier to create new plug-ins using the New Xtext Project wizard and then copy existing files over.

Prepare the ide plug-in

Core UI functionality that could be used for Eclipse, IDEA and Web editors, is extracted to a new plug-in <myLang>.ide. As it is usually created by the New Xtext Project wizard, you have to create it manually when migrating.

  1. Create the plug-in using File > New > Project… > Plug-in Project. Make sure it is physically located in the same directory as the other plug-in projects of your language (e.g. eGit links directories from different locations into the workspace)
  2. Add a new source folder src-gen and don’t forget to add it in the source… section of the build.properties.
  3. In the MANIFEST.MF, add a plug-in dependency to
    • <myLang>
    • org.eclipse.xtext.ide
    • org.eclipse.xtext.xbase.ide (if your language uses Xbase)
  4. You may want to add the new plug-in to the automatically refresh list in the workflow’s launch configuration: Run as… > Run configurations… > MWE launch > Generate language infrastructure (<myLang>) > Refresh > Specific Resources > Specify Resources…

Optional: Prepare a test.ui plug-in

This is only necessary when you have JUnit plug-in tests. These should be moved into a separate plug-in <myLang>.ui.tests now. Create the plug-in analogously to the ide plug-in above, and add a plug-in dependency to <myLang>.ui.

Convert modules and standalone setup to Xtend

The new generator will by default generate <myLang>RuntimeModule, <myLang>StandaloneSetup and <myLang>UiModule in Xtend. To avoid duplicate classes, convert the existing ones to Xtend by using Convert to Xtend from the context menu of the respective Java files.

Change the workflow

If you have not changed anything in the initially generated workflow, you can replace it by something like this

// adapt name
module <myPlugin>.Generate`<MyLang>`

import org.eclipse.xtext.xtext.generator.*
import org.eclipse.xtext.xtext.generator.model.project.*

var rootPath = ".."

Workflow {
  component = XtextGenerator {
    configuration = {
      project = StandardProjectConfig {
        // replace with your base plug-in's name 
        baseName = "<myPlugin>" 
        rootPath = rootPath
        runtimeTest = {
          enabled = true
        }
        genericIde = {
          enabled = true
        }
        eclipsePlugin = {
          enabled = true
        }
        // only needed if you have plug-in tests
        eclipsePluginTest = {
          enabled = true
        }
        createEclipseMetaData = true
      }
      code = {
        encoding = "UTF-8"
        fileHeader = "/*n * generated by Xtext ${version}n */"
        // preferXtendStubs = false
      }
    }
    language = StandardLanguage {
      // replace with your language’s qualified name
      name = "`<myLang>`"
      // needed when you import an Ecore model in the grammar
      referencedResource = "platform:/resource/path/to/genmodel"
      // needed when you import an Xcore model in the grammar
      referencedResource = "platform:/resource/path/to/Xcore/model"
      // replace file extensions here
      fileExtensions = "myLang"

      serializer = {
        generateStub = false
      }
    }
  }
}
  1. Note that we no longer use auto-inject, so if you want to generate only Java stubs, you have to do that in the code section.
  2. Use code completion for a list of available fragments and their properties if you want to customize them.
  3. If your grammar uses imported Ecore models, load the genmodels as referencedResource in the StandardLanguage section.
  4. If your grammar uses imported Xcore models, load them as referencedResource in the StandardLanguage section.

Run the workflow and fix remaining compile errors

The MWE2 workflow should run without errors. After that some plug-ins may have compile errors.

<myLang>.ui

  • In the MANIFEST.MF, add <myLang>.ide as a dependency and remove the Antlr contentassist packages from package exports.
  • To better serve the use case of multiple languages per plug-in, the Activator is now named the same as the plug-in. This may yield a different case if your languages name uses camel case, e.g. the former MyCamelCaseLanguageActivator will now become MycamelcaseActivator. If that is the case, the manifest shows a warning that you have to fix manually. Some repositories have problems when filenames are changed to a different case, e.g. in Git you have to delete the file, stage the deletion, restore the file from history and stage the new one to make it work.

<myLang>.tests:

  • The runtime injection provider has moved to <myLang>.tests. Fix compile errors with Organize Imports and remove the stale package import from the manifest.
  • You can remove the dependency to the <myLang>.ui plug-in.

<myLang>.ui.tests:

  • The UI injection provider has moved to the <myLang>.ui.tests package.

Adapt plugin.xml files

Compare the plugin.xml and plugin.xml_gen in the runtime and the UI project using the compare editor. We have harmonized the whitespaces in generated files, so the button Ignore Whitespace may help you track down the real differences you have to merge manually.

Use new APIs

  1. (Semantic) highlighting has moved to the <myLang>.ide plug-in. If you see deprecation warnings in classes you customized, just redirect the deprecated imports from org.eclipse.xtext.ui.editor.syntaxcoloring.X to org.eclipse.xtext.ide.editor.syntaxcoloring.XXX. For the binding in the module, you might have to override bindIdeISemanticHighlightingCalculator instead.
  2. Same holds for bracket matching and parser based content assist.

That is it, I hope you were successful. For further assist, ask us in the Xtext forum.

About the Author

Dr. Jan Köhnlein

Dr. Jan Köhnlein

Jan is one of the founders of TypeFox. Specialized in IDE development and language engineering, he is a long-term committer to various open-source projects, such as Xtext, Xtend and Theia. Jan also initiated the visualisation projects Sprotty and FXDiagram.

Read more about this topic

read the article

Mar 18th 2024

Article

Irina Artemeva

Run fast, debug easy: Exploring the synergy of Langium and LLVM

Ensuring your language is both executable and debuggable is an interesting challenge. Let's discover how to achieve this using Langium and LLVM.

read the article
watch the videoOpen Video

Mar 7th 2024

Video

Benjamin F. Wilson

Getting started with Langium – Part 7 "Generating Drawing Commands"

In this tutorial Ben will demonstrate how we can generate drawing commands from a MiniLogo program, building on the generator work we’ve already established in the prior tutorial.

watch the video
read the article

Mar 5th 2024

Article

Benjamin F. Wilson

Langium 3.0 is Released!

Langium 3.0 is released! This release brings us new improvements & features, like reduced bundle size, ESM support, and more.

read the article
LOAD MORE