Before you can start, you need to install the following features:
Altenatively you may install the Xtend Backend SDK and Xpand Middleend SDK
As a quickstart you may use the Xpand Project wizard and select "Generate a sample EMF based Xpand project". After completion of the wizard you will find the workflow file "generatorWithBackend.mwe" in the "workflow"-folder. The workflow is ready to use the backend for generation.
The compiler can be activated as a builder by adding M2T Backend Compiler nature to the project. This is done selecting "Configure" > "Add M2T Backend Compiler" from the context menu of the Xpand project. All Xpand/Xtend/Check resources will then be compiler to Java source files into the "backend-gen" folder of the project. When selecting "Clean..." from the project menu the Backend Compiler will do a full build, while changing a Xpand/Xtend/Check resource will compile this resource incrementally.
The compiler is still experimental.
The backend can execute functions and templates that have been compiled to Java or other resources that can be handled by one of the available middleends. It automatically recognizes compiled resources if available on the build path and prefers them over native Xpand/Xtend/Check resources.
The best way to execute compiled functions/templates is to use the XpandComponent or XtendComponent. The name of the function to be called is the same fully qualified name as defined in Xpand/Xtend/Check.
Before you can use a language like Xpand with the backend, the
responsible middleend must be registered at the backend. This is done
with the org.eclipse.xtend.middleend.LanguageSetup
.
Middleends are being called a languageContributor
here. You can register any language specific middleend. Language
specific middleend implement the interface
org.eclipse.xtend.middleend.plugins.LanguageSpecificMiddleEnd
. To register the Xpand, Xtend and Check middleends, do the
following in the workflow before invoking the middleend component of
any of the respective languages:
<component class="org.eclipse.xtend.middleend.LanguageSetup"> <languageContributor value="org.eclipse.xtend.middleend.xtend.plugin.OldXtendRegistryFactory"/> <languageContributor value="org.eclipse.xtend.middleend.xtend.plugin.OldCheckRegistryFactory"/> <languageContributor value="org.eclipse.xtend.middleend.xpand.plugin.OldXpandRegistryFactory"/> </component>
Now that the middleends are registered, you can use the respective middleend workflow components to use the backend in interpreted mode.
The Xpand middleend introduces a new component to be used instead of
org.eclipse.xpand2.Generator
to call Xpand templates from a workflow. The component has the same
parameters as the Xpand Generator
component. Hence, the following workflow fragment calls the template
template::Template::main
:
<component class="org.eclipse.xtend.middleend.xpand.XpandComponent"> <metaModel idRef="mm_emf"/> <expand value="template::Template::main FOR model" /> <outlet path="${src-gen}" > <postprocessor class="org.eclipse.xpand2.output.JavaBeautifier" /> </outlet> </component>
The component supports all properties of Generator
,
except collectProfileSummary
and
verboseProfileFilename
Just as the Xpand middleend, the Check middleend also provides a new component
to execute checks on the backend. The component
org.eclipse.xtend.check.CheckComponent
has to be replaced with org.eclipse.xtend.middleend.xtend.CheckComponent
. The new component uses the same properties as
org.eclipse.xtend.check.CheckComponent
.
Hence calling checks using the backend would look like this:
<component class="org.eclipse.xtend.middleend.xtend.CheckComponent"> <metaModel idRef="mm_emf"/> <checkFile value="metamodel::Checks" /> <emfAllChildrenSlot value="model"/> </component>
To invoke Xtend extensions from the workflow, the Xtend middleend
introduces the new component
org.eclipse.xtend.middleend.xtend.XtendComponent
. The new component provides the same configuration
properties as the old one. Hence, you may invoke the extension
extensions::modification::modify
using the following workflow fragment:
>component class="org.eclipse.xtend.middleend.xtend.XtendComponent"> <metaModel idRef="mm_emf"/> <invoke value="extensions::modification::modify(model)"/> </component>
Functions may also be contributed by the Java Annotations Middleend
to the M2T Backend. The middleend is implemented by
org.eclipse.xtend.middleend.javaannotations.JavaFunctionClassContributor
. Registration of Java classes is done by calling the method
classAsResource
with a class.
Functions have qualified names in the backend represented by
org.eclipse.xtend.backend.common.QualifiedName
consisting of a namespace and a simple name. E.g. the Xpand
definition template::Template::main
has the namespace template::Template
and the simple name main
. The String representation
of the QualifiedName would be template::Template::main
.
When registering Java Defined Functions, normally only the simple
name of a function will be defined as it's name. The simple name is method name.
To set the qualified name of a function use the annotation
@M2tQualifiedName
. The namespace will be
derived from the fully qualified class name.
Per default, all public methods will be registered as functions. To
prevent the registration of a method, annotate it with
@M2tNoFunction
.
You may also use one of the following annotations:
@M2tCached
- use caching
@M2tPrivateFunction
- mark the function as private
@M2tAroundAdvice(pointcut)
- use the method as around advice. The pointcut has the
parameters:
namePattern
- a pattern for function names as in Xpand
paramTypeNames
- an array with patterns of parameter type names
hasVarArgs
- true, if the matching functions have any number of
parameters after paramTypeNames
the specified in the pointcut
Functions defined by methods of a Java class can be directly called
on the facade
org.eclipse.xtend.middleend.javaannotations.JavaAnnotationBackendFacade
. Call the method invoke to invoke functions defined in Java:
invokeFunction(String className, BackendTypesystem ts, QualifiedName functionName, List<?> params)