-
-
Notifications
You must be signed in to change notification settings - Fork 349
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #360 from GerardPaligot/doc_template
- Loading branch information
Showing
8 changed files
with
369 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ allowed-tags: | |
- meta-model | ||
- quering | ||
- processor | ||
- template |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
title: What can be templated? | ||
tags: [template] | ||
keywords: template, substitution, code, java | ||
last_updated: October 7, 2015 | ||
--- | ||
|
||
All meta-model elements can be templated. For instance, one can | ||
template a try/catch block as shown in the class `TryCatchOutOfBoundTemplate`. | ||
This template type-checks, and can be used as input by the substitution | ||
engine to wrap a method body into a try/catch block. The substitution engine | ||
contains various methods that implement different substitution scenarios. | ||
For instance, method `insertAllMethods` inserts all the methods of a template | ||
in an existing class. It can be used for instance, to inject getters and setters. | ||
|
||
|
||
```java | ||
public class TryCatchOutOfBoundTemplate extends BlockTemplate { | ||
TemplateParameter<Void> _body_; // the body to surround | ||
|
||
@Override | ||
public void block() { | ||
try { | ||
_body_.S(); | ||
} catch (OutOfBoundException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
--- | ||
title: Template definition | ||
tags: [template] | ||
keywords: template, definition, code, java | ||
last_updated: October 7, 2015 | ||
--- | ||
|
||
Spoon provides developers a way of writing code transformations: | ||
code templates. Those templates are statically type-checked, in | ||
order to ensure statically that the generated code will be correct. | ||
Our key idea behind Spoon templates is that they are regular Java code. | ||
Hence, the type-checking is that of the Java compiler itself. | ||
|
||
![Overview of Spoon's Templating System]({{ "/images/template-overview.svg" | prepend: site.baseurl }}) | ||
|
||
A Spoon template is a Java class that is type-checked by the Java compiler, | ||
then taken as input by the Spoon templating engine to perform a transformation. | ||
This is summarized in Figure above. A Spoon template can be seen as a | ||
higher-order program, which takes program elements as arguments, and returns a | ||
transformed program. Like any function, a template can be used in different | ||
contexts and give different results, depending on its parameters. | ||
|
||
```java | ||
public class CheckBoundTemplate extends StatementTemplate { | ||
TemplateParameter<Collection<?>> _col_; | ||
@Override | ||
public void statement() { | ||
if (_col_.S().size() > 10) | ||
throw new OutOfBoundException(); | ||
} | ||
} | ||
``` | ||
|
||
Class `CheckBoundTemplate` defines a Spoon template. This template specifies a | ||
statement (in method `statement`) that is a precondition to check that a list | ||
is smaller than a certain size. This piece of code will be injected at the | ||
beginning of all methods dealing with size-bounded lists. This template has | ||
one single template parameter called `_col_`, typed by `TemplateParameter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/template/TemplateParameter.html)). | ||
In this case, the template parameter is meant to be an expression (`CtExpression`) | ||
that returns a Collection (see constructor, line 3). All meta-model classes, | ||
incl. `CtExpression` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/code/CtExpression.html)), | ||
implement interface `TemplateParameter`. A template parameter has a special method | ||
(named `S`, for Substitution) that is used as a marker to indicate the places where | ||
a template parameter substitution should occur. For a `CtExpression`, method `S()` | ||
returns the return type of the expression. | ||
|
||
A method `S()` is never executed, its only goal is to get the template statically | ||
checked. Instead of being executed, the template source code is taken as input by the | ||
templating engine which is described above. Consequently, the template source is | ||
well-typed, compiles, but the binary code of the template is thrown away. | ||
|
||
There are three kinds of templates: block templates, statement templates and | ||
expression templates. Their names denote the code grain they respectively address. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
title: Template instantiation | ||
tags: [template] | ||
keywords: template, instantiation, code, java | ||
last_updated: October 7, 2015 | ||
--- | ||
|
||
In order to be correctly substituted, the template parameters need | ||
to be bound to actual values. This is done during template instantiation. | ||
|
||
The code at the end of this page shows how to use the check-bound | ||
of template, `CheckBoundTemplate`, presented in the previous section. | ||
One first instantiates a template, then one sets the template parameters, | ||
and finally, one calls the template engine. In last line, the bound check | ||
is injected at the beginning of a method body. | ||
|
||
Since the template is given the first method parameter which is in the | ||
scope of the insertion location, the generated code is guaranteed to compile. | ||
The Java compiler ensures that the template compiles with a given scope, the | ||
developer is responsible for checking that the scope where she uses | ||
template-generated code is consistent with the template scope. | ||
|
||
```java | ||
// creating a template instance | ||
Template t = new CheckBoundTemplate(); | ||
t._col_ = createVariableAccess(method.getParameters().get(0)); | ||
|
||
// getting the final AST | ||
CtStatement injectedCode = t.apply(); | ||
|
||
// adds the bound check at the beginning of a method | ||
method.getBody().insertBegin(injectedCode); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
--- | ||
title: Literal Template Parameter | ||
tags: [template] | ||
keywords: template, substitution, code, java | ||
last_updated: October 7, 2015 | ||
--- | ||
|
||
We have already seen one kind of template parameter (`TemplateParameter<T>` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/template/TemplateParameter.html))). | ||
Sometimes, templates are parameterized literal values. This can be done with | ||
a template parameter set to a `CtLiteral` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/code/CtLiteral.html)), | ||
for instance, | ||
|
||
``` | ||
// with TemplateParameter | ||
TemplateParameter<Integer> val; | ||
... | ||
val = Factory.createLiteral(5); | ||
... | ||
if (list.size()>val.S()) {...} | ||
// with literal template parameter | ||
@Parameter | ||
int val; | ||
... | ||
val = 5; | ||
... | ||
if (list.size()>val) {...} | ||
``` | ||
|
||
For convenience, Spoon provides developers with another kind of template | ||
parameters called *literal template parameters*. When the parameter is known to | ||
be a literal (primitive types, `String`, `Class` or a one-dimensional array of | ||
these types), a template parameter enables one to simplify the template code. | ||
To indicate to the substitution engine that a given field is a template parameter, | ||
it has to be annotated with a `@Parameter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/template/Parameter.html)) | ||
annotation. The code above illustrates this feature with two equivalent templates. | ||
By using a literal template parameter, it is not necessary to call the `S()` method | ||
for substitution: the templating engine looks up all usages of the field annotated with | ||
`@Parameter`. The listing above shows those differences. |