Template Editor
Table of Contents
Overview
As already seen in Chapter 1.1 Working with models, the Actifsource Template Editor allows you to write meta-code based on the meta-model. Writing meta-code means to write code along the structures which are given by the meta-model without knowing the specific domain model.
New Template
A template is either based on a type (Class, Enum) or not.
Template Type | Description |
---|---|
Based on types | Based on a type means that the Template is applied for every instance of that type. The result is one file per instance. |
Build once | Build once means that the Template is applied exactly once. The result is one file. |
Create a template based on type
Creating a template based on a specific type (Class) is the normal case. Consider a nested Parent-Child structure with the following meta-model.
For every specific parent-child structure there is at least a resource of type Parent to start with. So let’s start writing meta-code based on the class Parent
To create a template based on the class Parent simply choose New/Template from the context menu of the class Parent
The New Template Wizard helps to configure the template settings.
Set the options as needed.
Option | Description |
---|---|
Resource Path | The resource path where the template is located (see Chapter 18 resource-paths) Resource Paths). This option is automatically filled in. |
Package | The package where the template is located. The package is derived from the location where the context menu was called. |
Template Name | The name of the template. The template name is automatically derived from the Base Type. |
BuildConfig | The build configuration where this template is referenced (see Chapter 7 Build Config). |
MetaModel | Make sure to choose Actifsource unless you know exactly what you do. |
Base Type | The base type is derived from the location where the context menu was called. |
Please note that there is a short way for choosing the package. Just type the first few letters of a package followed by a dot. Using content assist (Ctrl+Space) shows the matching packages.
Creating a template based on a type (i.e. class Parent opens an editor with a predefined selector Build.allParent. This means that this template is executed for all resources of type Parent
Create a Build.once Template
To create a Build.once template simply choose New/Template from the context menu of a package. Please note that the template is created in the chosen package.
The New Template Wizard asks for the template name and even allows you to add a base type afterwards using the content assist (Ctrl+Space). Adding a base type leads to a template based on a type (see Chapter 8.2.1 Create a template based on type).
Creating a Build.once template opens an editor with a predefined selector Build.once@BuiltIn. That means that this template is executed only once.
Writing template code
Writing template code is nearly as easy as writing common code – thanks to the Actifsource Template Editor.
Base Context
The Actifsource Template Editor lets you write code in the context of the meta-model.
The orange bar on the left is the context you are in. Creating a template for the class Parent lets you work in the context of this class.
The context derived from the base type (see Chapter 8.2.1 Create a template based on type) is called base context.
File Line
First of all you have to specify a proper name. Since we want to generate a file for any instance of the class Parent, we have to specify a file name that is unique for every Parent instance.
The name of the generated files is derived from the specific resource instance for which code is generated. Use content assist (Ctrl+Space) to access the properties of the class which is bound to the base context by the Selector.
The following file name will create files named Parent.name while Parent.name is replaced by the name of the specific instance of class Parent Text elements referring to the model are called links and displayed underlined.
Please note that the file extension .hpp automatically selects the Language C++ (see Chapter 8.3.3 Language Line and Chapter 8.4 Declaring a Programming Language).
It is also possible to define a folder structure in the file line. The generated files will be placed in the defined folders.
Language Line
The language line defines the programming language for
- Syntax Highlighting
- Comment Style
- String Style including escape rules
Actifsource defines the most common languages. If you are using a language which is not defined by default (see Chapter 8.4.1 Supported Programming Languages), do not hesitate to create one by your own (see Chapter 8.4 Declaring a Programming Language).
You may change the language at any time by using the content assist (Ctrl+Space) on the language line.
Selecting or changing a file extension in the file line (see Chapter 8.3.2 File Line) automatically selects the corresponding language.
Use Ctrl+Click on the language to show the underlying language model (see Chapter 8.4 Declaring a Programming Language).
File Tab
There are always situations where two or more files belong to each other (i.e. hpp/cpp in C++). Actifsource therefore supports file tabs.
Just press the [+] button right next to the file tabs to add a new file tab.
Note that files tabs are always automatically named the same as the file extension.
Press the X button to delete the active file tab.
Press Ctrl+Tab to select next tab from within the code section.
SuperContext
Let’s assume that we want to generate a file for every Child instance.
For that reason we create a template with Child as base type.
Since Child is owned by Parent.child, Actifsource automatically provides you with a super context of type Parent
Please note that the base context (i.e. Child in this example) is the widest bar (
).
Writing Code
Let’s start writing code. First we write a C++ class named Parent.name while Parent.name is replaced by the name of the specific instance of class Parent
Note that the keyword class is bold and has a special color as defined in the language C++ (see Chapter 8.4 Declaring a Programming Language).
To insert a reference to the meta-model just use content assist (Ctrl+Space) at any time.
Underlined words are so called links which are directly linked with your model.
Note that renaming resources in the meta-model automatically renames all links in the template synchronously.
You can always navigate to the corresponding resource in the model by using Ctrl+Click on the links as shown below or the
tool from the toolbar.
Saving the above template leads to one file for every resource of type Parent in your project.
A build config is needed to work with resources from other projects (see Chapter 7 Build Config).
Using type names in the template code
Please note that you might insert type names directly in the template code by using the content assist (Ctrl+Space). If the desired type name is not available, press Ctrl+Space again to get all available type names.
The type name is inserted just as given. The advantage of using type names in the template is the automatic renaming if the name of the type is changed.
Open Link
You can always open a resource link in the template editor.
- Open Link with Default Editor Use one of the following methods to open a link in the default editor (see Chapter 2.11.2 Open with).
To open a function link in the function editor use the default editor. To open the function model use the resource editor (see below).
- Open Link with Resource Editor Use one of the following methods to open a link in the resource editor (see Chapter 2.11.2 Open with).
Line Context, Column Context, Protected Context
Actifsource knows three different types of contexts.
- Line Context The line context consists of one or more lines in a file. The text in the line context is repeated for any resource reached by the selector (see chapter 8.3.10 Working with Context). To insert a line context use the Insert LineContext tool
from the toolbar or press Alt+Insert.
- Column Context The column context consists of one or more columns of a line. The text in the column context is repeated for any resource reached by the selector (see Chapter 8.3.10 Working with Context). To insert a column context use the Insert ColumnContext tool
from the toolbar or press Alt+Shift+Insert.
- Protected Context The protected context allows inserting so called protected regions into the generated files.
The content of the Protected Regions is saved before regenerating and inserted in the newly generated file. Use Protected Regions to insert handwritten code into generated files.
Note that Protected Regions are identified by the GUID of the resource of the current context. Use Ctrl+Click on the GUID to navigate to the corresponding resource.
The protected context consists of one or more lines in a file. The text in the protected context is repeated for any resource reached by the selector (see Chapter 8.3.10 Working with Context) and generated. To insert a protected context use the Insert ProtectedContext tool
from the toolbar.
Note that you can control the GUIDs that identify the protected regions by checking the resources in the context path. Just make sure that the resulting set of GUIDs is unique in your generated file. You might also define a name for the Protected Region.
Please note that changing the name of the Protected Region or the involved resources leads to new Protected Regions while the old once are moved to the end of the file.
Working with Contexts
Adding and removing a context is one of the most important operations when working with the Template Editor.
Use the Template Editor Toolbar to add, remove or navigate contexts.
-
Navigate Context via Select Tools Using the Context Select Tools in the Toolbar you might change the selection of the context from parent to child and vice versa.
-
Navigate Context via Breadcrumb A context can be selected by clicking on the Breadcrumb.
-
Navigate Context via Context Bar A context can also be selected by clicking on the context bar.
-
Add Context A new context is always added after the actually selected context. Navigate to a certain context before inserting a new context as shown above.
Let’s assume that we want create a functionidentifyChild.name
for every child in the parent context. For that reason we insert a new context using the Insert LineContext toolfrom the toolbar.
As a second step you have to declare a selector (see Chapter 8.3.12 Selector) to define the context.
Since our base context is Parent we have to traverse the relation Parent.child to reach all children from parent.
Choose the relation Parent.child for the selector using content assist (Ctrl+Space).
Using content assist in the new context you are now able to use links on resources of type Child
To complete the task from above insert a function named identifyChild.name
Line 4 is now repeated for any resource of type Child reached by the relation Parent.child
- Add Context via Quick-Assist Using the quick assist is the most efficient way to add a new context.
To create a new context with the selector Parent.child just insert the link Parent.child using context assist (Ctrl+Space). A light bulb
indicates that there is a quick assist available. Click on the light bulb or press Ctrl+1 to open the quick assist.
You are now allowed to create a line context or a column context directly with Parent.child as the selector.
A new context is inserted with the desired selector. Parent.child is automatically replaced by Child which is the result of the selector.
- Automatic Context growth Adding new lines (pressing return) automatically lets the context grow.
- Add Content between existing Contexts
Consider two contexts that follow each other (line 4 and 5 in the following example). How to insert new content between line 4 and line but in the base context?
Place the cursor on the end of line 4 as shown above and press cursor right. The cursor will still remain at the same position but the context selection will change to the parent context.
Entering a new line is done in the selected parent context and results in a new line between the existing contexts.
Copy/Paste
Copy (Ctrl+C) and Paste (Ctrl+V) in the Template Editor has some special features to work with links and contexts.
- Copy/Paste with Link Links can be easily copied like text.
- Copy/Paste with Context The Copy action takes care on all nested contexts in the current context. The following situation won’t copy the selected line context C on line 2 but the nested column context D
If you have to copy the line context C on line 2 just navigate to the base context (see Chapter 8.3.10 Working with Contexts) what makes the line context a nested context.
There is also a command Copy with Context in the context menu which allows to specify the position from which context are copied. The following situation shows a selection on line 2 where the copy operation allows to copy with context C or B
Please note that it makes no sense to copy the base context (see Chapter 8.3.1 Base Context) or even the super context (see Chapter 8.3.5 SuperContext) because they are part of the whole template.
Selector
The selector allows navigating the meta-model and is extremely powerful. Please consult Chapter 9.3.2 SelectorFunction for details.
Use the Switch to Selector tool from the tool bar or Alt+Enter to navigate from the code to the selector. Use Enter in the selector to jump back to the code.
- Break Flag Consider the following situation:
The subsequent template iterates over Container.element and prints the name of every element.
Let’s assume that we write template code that shall produce different code depending whether Container.element is of type ElementA ElementB or ElementC
A straightforward solution is introducing a context with a type cast for type in the inheritance hierarchy.
The problem is that a resource type of ElementC is also of type ElementB and ElementA Therefore the above template prints lines 2, 3 and 4 for resources f type ElementC But the intention is that only line 2 is printed.
Use the break flag in the selector for the desired behavior. If the break flag is set all subsequent context of the same level are skipped. Users familiar with programming language C or C++ can think of the switch/case/break statement.
The following template prints line 2 for resource types of ElementC and then breaks the current iteration to continue with the next resource for Container.element
Line Attributes
Use line attributes on a line context to control the output specific positions of a resource in a list. Place the cursor on the desired line to apply a line attribute.
There are five different types of line attributes which might be applied to a line context.
The following template prints the comment on line 7 only for the first element of the iteration over the list Parent.child Please note that line 7 is not printed if Parent.child is empty.
The following example prints a comment on line 8 if Parent.child is empty.
Column Attributes
Use column attributes on a column context to control the output specific positions of a resource in a list. Select the desired characters to apply a line attribute.
There are five different types of column attributes which might be applied to a column context.
The following example prints the comma after Param.name for all elements of the iteration except the last.
The next example prints void on line 7 if Parent.child is empty.
FunctionSpace
As shown in Chapter 9.2 Function Space the Template acts as a Functions Space. Therefore functions might be placed directly in the template (see Chapter 9 Functions for details).
Function calls are displayed in italic. In the subsequent example there is a call to Parent.className where className is the function.
To see the model of a function within a template just open the folding
on the template.
If a function is placed in a function space other than the own template the function call is displayed with the name of the function space after the @ sign. Parent.className@MyFunctionSpace indicates a function call where the function className is located in the function space MyFunctionSpace
Extract Function
The Actifsource Template Editor allows you to extract selected expressions as functions. Please consider extracting complex expression if you use them more than once.
Selecting an expression which might also contain links leads to a
light bulb on the left side which indicates that there is a Quick Assist available. Click on the light bulb or press Ctrl+1 to open the Quick Assist.
Context Path
The path from the outermost to the innermost context is called Context Path. Actifsource uses the Context Path to determine the parameters of a function (see Chapter 9.2.1 Function Parameters).
Consider the following meta-model:
The subsequent template shows nested contexts based on the above meta-model. Please note that the breadcrumb displays the context path for the actual cursor position.
The template shows the following context paths.
Line | Context Path |
---|---|
ine 1 | A |
Line 2 | A, B |
Line 3 | A, B, C |
Line 4 | A, B, C, D |
Calling a function with parameters is only allowed if the context path is matching.
The following function fD C B A is based on Class D and declaring the parameters c of type C b of type B and a of type A
Calling fD C B A is only allowed if the context path contains at least A B C, and D in the given order.
Consider a function fD A which is based on Class D and declaring a parameter a of type A It is allowed to call this function on the context path A B C, and D because it contains A and D in the correct order.
Declaring a Programming Language
The Actifsource Template editor does syntax highlighting for keywords, comments, and strings. The actual selected language is determined by the Language Line (see Chapter 8.3.3 Language Line).
Supported Programming Languages
Currently Actifsource supports syntax highlighting for the following programming, script, markup, or domain languages.
Programming Language | Description | File Name Extension |
---|---|---|
Ada | ada | |
C | c, h | |
C# | Microsoft C Sharp | cs |
C++ | cpp, hpp | |
Cobol | cob | |
Css | Cascading Style Sheet | css |
D | d | |
Delphi | dfm | |
Eiffel | e | |
Erlang | erl, hrl | |
GraphViz | www.graphviz.org | dot |
Groovy | groovy | |
Haskell | hs | |
Html | Hyper Text Markup Language | html, xtml |
Java | java | |
JavaScript | js | |
Modula2 | mod | |
Oberon | pas | |
OmgIdl | www.omg.org | idl |
Pascal | pas | |
Perl | pl | |
Php | php | |
Python | py | |
Ruby | rb | |
Scala | scala | |
Sql | Structured Query Language for RDBMS | sql |
StructuredText | see wikipedia | st |
Svg | Scalable Vector Graphics | svg |
Text | Plain text | txt |
VisualBasic | Microsoft Visual Basic | vb, vba |
Xml | Extensible Markup Language | xml |
TemplateLanguage Model
To create your own template language model just instantiate the class TemplateLanguage.
-
fileNameExtension The file name extension of the template language is used to automatically select the language line (see Chapter 8.3.3 Language Line) from the file extension in the file line (see Chapter 8.3.2 File Line).
-
keywordStyle A list of keywords including the syntax style (color, font modifier)
-
stringStyle A declaration of start and end tag for strings including the syntax style (color, font modifier)
-
singleLineComment A declaration of the start tag for single-line comments including the syntax style (color, font modifier)
-
mutliLineComment A declaration of start and end tag for multi-line comments including the syntax style (color, font modifier)
File Extension Priority Rules
You might define your own template language defining the same file name extension as a built-in language. Actifsource will handle user-defined template languages with higher priority so that you can overwrite the standard.