Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Acceleo/User Guide"

(For Loops)
(For Loops)
Line 167: Line 167:
 
Will generate the following text:
 
Will generate the following text:
  
<code>sequence: 1, 2, 3<code>;
+
<code>sequence: 1, 2, 3</code>;
  
 
====If Conditions====
 
====If Conditions====

Revision as of 07:09, 21 February 2018

Installing Acceleo

Acceleo can be downloaded and installed in a number of ways. If you have an existing Eclipse installation and simply wish to install Acceleo in it, Installing through the update site is the easiest way. If you'd rather install a new Eclipse with Acceleo, you may want to take a look at the facilities provided by the amalgamation project.

For those of you that need to retrieve the zips of Acceleo, you can either look at the latest releases or the legacy releases if you need one of the 2.x releases.

Note: Whatever the installation procedure you choose, examples are available from the menu right-click => New => Examples => Acceleo Plug-ins.

The Acceleo language

Acceleo 3 is an implementation of the MOFM2T specification defined by the OMG. The Acceleo language, named as MTL by the OMG, is composed of two main types of structures (templates and queries) inside of a module. In Acceleo, you can create expressions using a subset of OCL in order query the input models.

Modules

An Acceleo module is a ".mtl" file, which contains templates (to generate code) and/or queries (to extract information from the manipulated models). The file must start with the module declaration in the form:

[module <module_name>('metamodel_URI_1', 'metamodel_URI_2')]

A module can extend another module, in which case its templates will be able to override its parent's "public" and "protected" templates. It will also have access to its parent's public and protected templates and queries. A module can also import another module to access its public templates and queries.

Import

An Acceleo module generally depends on other modules for its execution. Consequently, Acceleo modules explicitly declare the modules they depend on via import declarations.

The syntax is the following:

import qualified::name::of::imported::module

The content assistant (Ctrl + Space) will propose you all accessible modules. Select the module you want to import and its qualified name will be inserted.

Note: It is possible to use a non-qualified name in an import, but this is not recommended since it can easily lead to bugs that are hard to understand in case of name conflicts between Acceleo modules.

The content assistant can be invoked to generate an import tag: just enter import, then Ctrl + Space, and the completion proposes "import" and generates an [import... /] tag.

Static Overriding

Acceleo allows you to override a part of the behavior of another module by extending it and by overriding some of its templates (all templates except those without with a private visibility). It can be very useful to re-use some common part of a module and to create common parents to several modules just like in object oriented programming.

Templates

Templates are sets of Acceleo statements used to generate text. They are delimited by [template...][/template] tags.

To create a new template, just place the cursor in an Acceleo module file at a relevant position (i.e. one where it is possible to insert a template!) and hit Ctrl + Space. The content assistant proposes, among other things, to create a new template. It's also possible to type template, Ctrl + Space, then Return, and a new template is created:

You can fill-in its name, parameter name, and parameter type. Just hit Tab to pass from an element to the next.

Templates can also have optional elements:

  • Overriding (which will be detailed in The Overrides View);
  • Pre-conditions (or guard conditions);
  • Post-treatments;
  • Variable initializations.

Once again, the content assistant can help you here. just hit Ctrl + Space before the final ] of your template declaration, and see what it proposes.

Pre-Conditions

Imagine you want to implement different behavior for a template depending on certain conditions.

One way to do that would be to use if blocks to distinguish between those cases. Another, more elegant, way is to use pre-conditions. Let's say that you want to generate different code for associations whether or not they are declared ordered.

The above example shows the ? (condition) syntax that tells Acceleo that the template must only be run if the pre-condition is satisfied.


Note:

  • The order of declaration of templates in a module is important: The first template for which the guard condition evaluates to true will be executed. No guard condition on a template is exactly equivalent to ? (true).
  • Pre-conditions also exist on for blocks.


Post-Treatments

It is often useful, especially for code formatting, to apply certain treatments on the text generated by a template before actually writing it to the output file.

For instance, trimming the result of a template is really very useful to make sure of your formatting while keeping a readable formatting for your templates.

Let's see an example to make things clear:

In the above example, without the post-treatment post (trim()), the template invocation would write the name followed by a carriage return. With the post-treatment, whenever the template is called, it will just write the expected name, without a carriage return, which is probably what you need.

The most common uses of post-treatments is output code formatting, thanks to post (trim()). It's up to you to figure out what else you will use it for!

Variable Initialization

Templates (and other blocks as well) can define some variables and initialize them directly in their main syntactic block.

You can declare 0, 1, or several variables. If you declare several variables, it may be opportune to format the template this way:

Note: Variable initilization also exists on for blocks.

Queries

Queries are used to extract information from the model. Queries return values, or collections of values. They use OCL, enclosed in a [query ... /] tag.

Queries are specified to always return the same value each time they are invoked with the same arguments.

Wrapping Java Services

It is sometimes useful to invoke some java code from inside an Acceleo template. The acceleo non-standard library provides a service invoke which allows just that. The invoked java service can be wrapped in an Acceleo query.

To facilitate the creation of such a wrapper, proceed like this: 1- Right-click on the package you want to create your Acceleo module in, and select New > Acceleo Module File 2- In the wizard, enter the relevant information in the usual fields, then click on the Advanced >> button 3- Check the Initialize Content checkbox 4- Select Create a Java services wrapper in the listbox below 5- Select the java file that contains the services to wrap 6- Click on the Finish button

That's it!

An Acceleo module is created, with a query for each service found in the original java class.

Language Elements

File Tags

File tags are used to tell the Acceleo engine it must generate the content of the [file ...] tag in an actual file.

The syntax is the following:

[file(<uri_expression>, <append_mode>, <output_encoding>)] (...) [/file]

  • <uri_expression> denotes the output file name;
  • <append_mode> (optional) indicates whether the output text must be appended to the file or replace its content;
  • <output_encoding> (optional) indicates the encoding to use for the output file. This encoding need not be the same as the module's encoding.

Note: A template that contains a [file] tag does not necessarily have an annotation @main. @main annotations are used to indicate to the Acceleo eclipse plug-in that a java class must be generated to encapsulate the code required to run a generation. @main annotations can be placed on templates which have no [file] tag, but such templates must eventually call one or more templates that do have [file] tags if you want to get a result!

Please refer to the official MTL Specification for more details.

For Loops

For loops in Acceleo can be expressed with two syntaxes:

  • The full syntax (conformant with the MTL specification): [for (i : E | e)]...[/for]
  • The light syntax: [for (<iterable_expression>)]...[/for]

Note: When using the light syntax, an implicit variable i is created, which contains the index of current iteration, starting at 1.

Content assistant can be very helpful to make sure you use the right syntax. For example, imagine that you want to insert a for loop, but you don't remember for sure the Acceleo syntax for these loops.

Just type for in the editor, then Ctrl + Space. Acceleo proposes the for loop to be automatically inserted.

Hit Return to confirm that you actually want to insert a for loop:


You can now enter:

  • The iterator variable name;
  • The iterator type;
  • The iterable expression.


Just hit the Tab key to jump from one element to the next, as usual with eclipse code templates.

Here is an example of a for loop to generate some code for each attribute of a UML class:


Finally, it is useful to know that it is possible to specify behavior to be run before, between, or after each iteration of a for loop.

The content assistant proposes the corresponding options when invoked in the declaration of a for loop, as can be seen on the picture below.


The syntactic structure are respectively before(), separator()<c/ode>, and <code>after().

Example:

[for (Sequence{1, 2, 3}) before ('sequence: ') separator (', ') after (';')][self/][/for]

Will generate the following text:

sequence: 1, 2, 3;

If Conditions

If conditions are written like this: [if (condition)]...[/if]

You can enter if<code>, hit Ctrl + Space, then Return, and the Acceleo editor will insert the right syntax so you just have to enter the condition expression.

And that's all there is to it!


Let Blocks

It is important to understand that variables in Acceleo are final, which means that their value cannot be changed after they have been initialized.

Please also note that the Acceleo let hasn't got the same semantics nor the same behavior as the OCL let

The syntax is the following: <code>[let (variableName : VariableType = expression)]...[/let]

Where variableName is the variable's name and VariableType the variable's type, and expression is an expression which value will be assigned to the variable if its type corresponds (Acceleo let blocks are equivalent to if (expression.oclIsKindOf(VariableType)).

Variables only exist inside of a let block. Their lifetime consequently cannot exceed that of their template. They are only visible inside of the let block, which means that templates called within this block cannot "see" them. If you need a sub-template to access a variable, you have to pass it as an argument.

Variables are especially useful to store a value and prevent computing it several times in a row.

You can enter let, hit Ctrl + Space, then Return, and the Acceleo editor will insert the right syntax so you just have to enter the variable name and type.


Comments

Comments are entered in [comment/] blocks, and appear in some shade of green. The [comment/] tag can be self closed:

[comment Here is some comment of utter importance/]

But you can also surround a block of text between comment tags:

[comment]Here is some commented text, which cannot contain a right bracket character.[/comment]

Such comments are part of the official MTL specification. They cannot be placed inside OCL code, such as queries for instance. They cannot be placed in the middle of an Acceleo statement either.

It is possible to comment some portion of code or text of an Acceleo module with the Ctrl + / shortcut, or by right-clicking on the selected text and then Source > Comment.

The behavior depends on what is selected:

  • If nothing is selected, the current line (not the line you right-clicked on, but the line where the cursor is located) is surrounded with [comment]...[/comment] tags.
  • If some text is selected, it is surrounded with [comment]...[/comment]tags, whether it spans multiple lines or not.

Back to the top