diff --git a/doc/template_can_be_templated.md b/doc/template_can_be_templated.md deleted file mode 100644 index 3cb41d10aa7..00000000000 --- a/doc/template_can_be_templated.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -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 _body_; // the body to surround - - @Override - public void block() { - try { - _body_.S(); - } catch (OutOfBoundException e) { - e.printStackTrace(); - } - } -} -``` \ No newline at end of file diff --git a/doc/template_definition.md b/doc/template_definition.md index 5cc953447a9..2cc8e6562bc 100644 --- a/doc/template_definition.md +++ b/doc/template_definition.md @@ -1,24 +1,25 @@ --- -title: Template definition +title: Transformation with Templates 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 +Spoon provides developers a way of writing code transformations called +**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. + +A Spoon template is a regular Java class that taken as input by the Spoon templating engine to perform a transformation. +This is summarized in Figure below. 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. ![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. +Definition of templates +----------------------- + +Class `CheckBoundTemplate` below defines a Spoon template. ```java public class CheckBoundTemplate extends StatementTemplate { @@ -31,7 +32,7 @@ public class CheckBoundTemplate extends StatementTemplate { } ``` -Class `CheckBoundTemplate` defines a Spoon template. This template specifies a +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 @@ -49,5 +50,151 @@ checked. Instead of being executed, the template source code is taken as input b 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. +Template Instantiation +------------- + +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); + +``` + +Kinds of templating +------------------- + +There are different kinds of templating. + +#### Subclassing `StatementTemplate` +Using method `apply()` enables to get a new statement (see example `CheckBoundTemplate` above) + +#### Subclassing `BlockTemplate` +Using method `apply()` enables to get a new block. + +#### Subclassing `ExpressionTemplate` +Using method `apply()` enables to get a new expression. The core template method must be called `expression` and only contain a return with the expression to be templated. + +#### Subclassing `ExtensionTemplate` +Using method `apply()` enables to get a new class where: + +1) methods and field of the templates are injected in the target class + +```java +public class ATemplate1 extends ExtensionTemplate { + int i; + void foo() {}; +} + +// inject `i` and `foo` in aCtClass +Substitution.insertAll(aCtClass, new ATemplate1()); +``` + +2) parametrized superinterfaces are injected in the target class + +```java +class ATemplate2 extends ExtensionTemplate implements Serializable, A, B { + // interface templates supports TypeReference + @Parameter + Class A; +} + +Template t = new ATemplate2(); +t.A = Comparable.class +Substitution.insertAll(aCtClass, t); +// aCtClass now implements Serializable and Serializable + +``` + +3) method parameters + +```java +class ATemplate3 extends ExtensionTemplate { + public void methodWithTemplatedParameters(Object params) { + // code + } + + @Parameter + public List params; +} + +Template t = new ATemplate3(); +t.params = ... +Substitution.insertAll(aCtClass, t); +// aCtClass contains methodmethodWithTemplatedParameters with specific parameters + +``` + +Template parameters +------------------ + +#### AST elements +All meta-model elements can be used as template parameter. For instance, one can +template a try/catch block as shown in the class `TryCatchOutOfBoundTemplate`using a block as parameter. +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. + + +```java +public class TryCatchOutOfBoundTemplate extends BlockTemplate { + TemplateParameter _body_; // the body to surround + + @Override + public void block() { + try { + _body_.S(); + } catch (OutOfBoundException e) { + e.printStackTrace(); + } + } +} +``` + +#### Literal template Parameters + +For literals, Spoon provides developers with *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, annotated with `@Parameter` enables one to have concise template code. + +```java +// with literal template parameter +@Parameter +int val; +... +val = 5; +... +if (list.size()>val) {...} +``` + +Note that AST elements can also be given as parameter using `@Parameter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/template/Parameter.html)) +annotation. + +```java +class ATemplate extends BlockTemplate { +@Parameter +CtExpression exp; +... +if ("er".equals(val)) {...} +} +``` diff --git a/doc/template_instantiation.md b/doc/template_instantiation.md deleted file mode 100644 index 53e9d224e59..00000000000 --- a/doc/template_instantiation.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -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); -``` \ No newline at end of file diff --git a/doc/template_parameter.md b/doc/template_parameter.md deleted file mode 100644 index 83551c3d158..00000000000 --- a/doc/template_parameter.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -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` ([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 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. \ No newline at end of file