• No results found

The ArchiType Composition Language is a textual DSL. The purpose of the ArchiType Composition Language and its interpreter is to:

1. Control the code generation process in compliance with the dependen- cies existing between the code templates.

2. Provide values for variables that are used in the code templates. 3. Trigger the Microsoft T4 engine to compile and execute source code

templates in T4 code in a closure operation in order to generate concrete target source code.

4. Evaluate operations, e.g. concatenating strings.

5. Handle errors either from the interpreter (file not found) or from the T4 engine.

6. Generate multiple files. A software system contains a lot of source code files. A generator must be able to generate multiple files. For a contract-based client-server connection, source code for a client proxy, a server stub, a contract, communication codes (for example WS-SOAP or REST), and a lot of configuration files as well as triggering a lot of tools supporting the generation are necessary.

7.5. ARCHITYPE COMPOSITION LANGUAGE 155 7. Comply with existing interdependencies between different template files as specified by the semantics added to the C&C type environment. The composition language file is a text file that contains three sections. These sections have different purposes:

1. The first section is a declarative part, where a collection of template names is declared. The declaration format is function-like. Assume we have a template named T and this template takes three other templates

as its arguments a1, a2, and a3, then the declaration looks like:

T (a1, a2, a3)

2. The second section is used to initialize string variables with values. A generic template file gets specific values via such variables. In order to distinguish template names and variables, variables have to begin with $. The section is also used by ArchiType to apply concrete values, for instance stemming from the UML2 component diagram to variables for a code generation in text templates.

3. The third section contains composition commands in an imperative script form. The script language is a sequence of commands including functional applications. A special binary infix operator ->> has two arguments. The first argument is a command (template name) and the second argument is a string or variable containing a file name. The file name will later be used to write the result of a command into a file designated by the file name. It allows the generation of multiple files during an interpretation of the script. An example line in such a command sequence is:

T(A, B(C,D), E)->>’’path/file1.ext’’

A simple example for an ArchiType Composition Language code file is contained in the appendix in Section A.2 on page 201.

The ArchiType Composition Language interpreter expects that every template name in a script part has a corresponding template file with the same name. It parses an input file and checks if all declarations are correct. Afterwards, it initializes all variables with data from the second section. The second section forms a blackboard architectural pattern as a central data provider for the generation process. In the next phase, it picks the first command and interprets its arguments. The results of the arguments of the command then are passed as values to the first command. Command and

arguments are linked to templates via their name. The interpretation of commands and arguments is made by a call to a controller mapping argument names from a specification to variable names in a T4 template. Then, the ArchiType’s T4 controller loads a template text and assigns this template text to a T4 processor. A T4 processor compiles and executes the template as executable and returns its return value to the ArchiType’s T4 controller. If a first command is an argument of ->>, then a return value is written to ->>’s second argument interpreted as a file name. After that, a second command is interpreted. The interpreter stops, if an error is raised or the last command in a script has been processed.

The Microsoft text template transformation toolkit (T4) is a template based text generation framework included in Visual Studio. The T4 generates arbitrary text files and is therefore agnostic to target languages. T4 accepts a custom template format which can contain .NET code and string literals in it. String literals and .NET code are separated by two special symbols <# and #>. The .NET code contains meta-code for a code generation, is compiled, and executed. The result is embedded into a resulting text that contains a mixture of executed result and string literal parts.

Example 7.1. A simple T4 text template is shown below: Listing 7.1: Example T4 template file

1 <#@ template debug=”true” hostSpecific=”true” #>

2 <#@ output extension=”.cs” #>

3 <#@ Assembly Name=”System.Core” #>

4 <#@ import namespace=”System” #>

5 <#@ import namespace=”System.IO” #>

6 <#@ import namespace=”System.Collections” #>

7 <#@ import namespace=”System.Collections.Generic” #>

8 <#@ parameter name=”className” type=”System.String” #>

9 <#

10 // this is meta code in C# that is executed

11 string Greeting = ”Hello”;

12 #>

13 // This is the output code from your template

14 namespace MyNameSpace{

15 class <#=className#>{

16 static void main (string[] args){

17 System.Console.WriteLine(”<#= Greeting #>, the time is now:

<#= System.DateTime.Now.ToString() #>”);

7.5. ARCHITYPE COMPOSITION LANGUAGE 157

19 }

20 } 21 22 <#

23 // Insert any template procedures here

24 // this is also meta code in C# that is executed

25 void foo(){}

26 #>

In this example template a C# file is produced that contains a namespace and a class declaration with a static void method main. The static method is called if this program is compiled to an executable with console output. The method main outputs a string with time information. The content and the effect of the listing is:

• Lines 1 to 8: Are meta-template codes for configuring the T4-processor. Such a meta-template code is encapsulated by <#@ and #>.

• Line 1: The template directive is used to set compiler specific options, like compiler options or culture variables used for specific cultural system settings (for example the user’s language). If the option hostspecific is set to true, then a variable Host can be used. The variable Host is a connection to the T4 processor host which is in this case the ArchiType’s processor host. If the debug attribute is true, then information for the debugger is provided that enables the debugger to identify a position in the template where a break or an exception occurred more accurately. Analogously, such information is as well used by ArchiType to present warning or error information to the user.

• Line 2: The output directive is used to set the file extension of a file that is used for output. The flag can be used to override the setting that is made with the binary operator ->> in the ArchiType composition language.

• Line 3: The assembly directive loads an assembly that allows a tem- plate code to use types defined in a template meta-code.

• Lines 4 to 7: The import directive allows referring to elements in another namespace without providing a fully-qualified name. The directive corresponds to the using directive in C#.

• Line 8: The parameter directive is used to set parameters externally to provided values. A data type must be provided for a parameter. A

value of a parameter is set by the ArchiType T4 processor and depends on all evaluated values of corresponding arguments of a template in the ArchiType’s composition language.

• Lines 9 to 12: The lines contain meta-code in C# encapsulated by <# and #>. Such a code is compiled and executed by the T4 processor. In line 11 the variable Greeting of type string is set to the value Hello. • Line 13 to 21: These lines are interpreted mostly as string literal and

are inserted in a generated file unchanged as program code in C#. • Line 15: The class declaration is made for a class where the substituted

parameter className is used.

• Line 17: In the meta code <#= Greeting #>, the variable Greeting is used in an execution of the program and a result replaces the cor- responding section. In <#= System.DateTime.Now.ToString() #> a call to the class method now of class System.DateTime is made and the method’s result is converted to a string replacing the original meta-code. • Line 22-26: These lines are an example of declaring a void method in

meta code that can be used during an execution of the T4 processor. The generated output file by ArchiType’s T4 processor of such a template

file with the parameter className set to MyGeneratedClass is:4

Listing 7.2: Output of example T4 template file 7.1 1 using System;

2 // This is the output code from your template

3 namespace MyNameSpace{

4 class MyGeneratedClass{

5 static void main (string[] args){

6 System.Console.WriteLine(”Hello, the time is now: 12:39 on

12.01.2014”);

7 }

8 }

9 }

A more complex file that is used for experiments in Chapter 8 in Section 8.4 on page 179 can be found in the Appendix in Section A.3 on page 202. All experiments in Chapter 8 have been conducted with templates in T4 and the ArchiType composition language.