|
Translation of "ComplexClass.tj" into "ComplexClass.java" provides
a more complex example of code generated by tjpp.
The most significant code fragments are described below.
Directive attach is similar to include, but
instructs tjpp to simply copy the contents of the attached file,
without processing it.
$attach(copyright.tjh)
Directive enumeration provides a means to define
enumerated types:
$ enumeration(Color,%
RED, %
GREEN, %
BLUE %
)
The percent sign "%" is tjpp's line concatenation operator.
The above directive generates the following code:
// Map enum 'Color' onto an int with a set of values
public static final int RED = 0;
public static final int GREEN = 1;
public static final int BLUE = 2;
User-defined numeric values can also be provided as follows:
$ enumeration(Color,%
RED=1, %
GREEN=2, %
BLUE=4 %
)
Directives property, getters, setters and to_string
allow to concisely define the set of properties of a
class and produce a toString method:
$ property(int, a_unique_id, readonly)
$ property(Object, a_thing)
$ getters
$ setters
$ to_string
Directive property accepts a Java type, an identifier
(in lower case letters, digits, and underscores) and an optional
readonly flag. The list of properties is then
scanned by getter and setter to generate the accessors
and mutators. No mutator is generated for properties declared
as readonly. In a similar way, directive to_string scans
the list of properties to generate the toString method.
The fragment above translates to the
following Java code:
private int aUniqueId; // read-only
private Object aThing;
/*
* Get methods
*/
public int getAUniqueId() {
return aUniqueId;
}
public Object getAThing() {
return aThing;
}
/*
* Set methods
*/
public void setAThing( Object aThing ) {
this.aThing = aThing;
}
public String toString() {
String s = "[" +
" aUniqueId = '" + aUniqueId + "'" +
" aThing = '" + aThing + "'" +
" ]";
return s;
}
The assert directive of tjpp provides a rather
mild implementation of assertions, in comparison with regular
Java assertions. The generated
code checks the assertion and prints a message similar to the
trace message if the asserted condition
evaluates to false, raising neither errors, nor exceptions.
The following fragments show the input to, and output from, tjpp.
Input:
$ assert(aRange >= 0 && aRange < 20000)
Output:
{
if (! (aRange >= 0 && aRange < 20000)) {
System.err.println("[A] -------------");
System.err.println("[A] --- File ComplexClass.java, line 153
(src: ComplexClass.tj, 54)");
System.err.println("[A] --- Assertion 'aRange >= 0 && aRange
< 20000' failed");
System.err.println("[A] -------------");
}
}
As for most tjpp directives, it
is also possible to customize this directive, for instance to add code
that prints a stack trace or raises an error. The macro source code
is commented at the end of this chapter.
|
Code Example 5 - Input code to generate ComplexClass.java
|
Line 1 uses directive $attach to include a
copyright file without any processing, ensuring
that the contents of the include file is faithfully
copied to the generated file.
Lines 5 and 13 use tjpp variable PACKAGE_ROOT.
Lines 18-22 contain a tjpp comment.
Lines 23-42 use the property-oriented directives of tjpp,
namely enumeration, property, getters, and
setters.
Variable trace directives are used on lines 53, 66-67, 69-70:
in particular, tracing is switched off between lines 66 and 68.
Line 54 shows an example of $assert.
A user-defined macro, "tjpp_include/my_macros/perc", is used
on line 68.
Directive to_string is used on line 74.
|
|
|
Source code - File "input_code/ComplexClass.tj"
|
1 $attach(copyright.tjh)
2 $include(header.tjh)
3 $include(subinc/subhdr.tjh)
4
5 package PACKAGE_ROOT;
6
7 /**
8 * Class ComplexClass:
9 *
10 * A software entity with several fields and collections.
11 */
12
13 import PACKAGE_ROOT.subpackage.SimpleClass;
14 import java.util.Date;
15
16 public class ComplexClass extends SimpleClass {
17
18 |---
19 | This is a tjpp comment that will not appear in the
20 | generated Java file. The "%" in the lines below is
21 | tjpp's line-concatenation operator.
22 |---
23 $ enumeration(Color,%
24 RED, %
25 GREEN, %
26 BLUE %
27 )
28
29 $ property(boolean, a_bool)
30 $ property(int, a_color)
31 $ property(double, a_float)
32 $ property(int, a_range)
33 $ property(String, a_string)
34 $ property(Date, a_time)
35 $ property(int, a_unique_id, readonly)
36 $ property(int, an_int, readonly)
37 $ property(int, another_color, readonly)
38 $ property(Object, a_thing)
39 $ property(int [][], an_int_array)
40
41 $ getters
42 $ setters
43
44 /**
45 * Method 'A function'
46 */
47
48 public boolean aFunction (
49 int aRange,
50 int aColor
51 )
52 {
53 $ trace(aRange,aColor)
54 $ assert(aRange >= 0 && aRange < 20000)
55 return true;
56 }
57
58 /**
59 * Method 'A function'
60 */
61
62 public double aFunction (
63 int anInt
64 )
65 {
66 : TRACE_SWITCH=off
67 $ trace(anInt)
68 double d = $my_macros/perc(anInt,1000);
69 : TRACE_SWITCH=on
70 $ trace(d)
71 return d;
72 }
73
74 $ to_string
75
76 }
|
|
|
Code Example 6 - Code generated from ComplexClass.tj
|
The $attached copyright file has been copied to lines 4-8.
Lines 34-37 show the code generated by directive enumeration.
Lines 39-49 result from directive member.
Lines 51-98 result from directive getters.
Lines 99-134 result from directive setters: no set method
has been generated for properties declared read-only.
The values of two traced variables are printed out on lines
145-147.
Lines 148-155 show the code generated by directive assert.
Line 167 contains the result of
$my_macros/perc(anInt),1000.
Lines 168-169 trace variable d, while no tracing statements
have been generated for parameter anInt, as $trace(anInt)
followed a ": TRACE_SWITCH=off" directive.
Lines 173-188 show the code generated by directive to_string.
|
|
|
Source code - File "generated_code/ComplexClass.java"
|
1 // WARNING: file "ComplexClass.java" generated from "ComplexClass.tj"
2 // Changes should be applied on the source file.
3
4 //
5 // Sample copyright file for Java preprocessor
6 //
7 // Copyright (c) _____________ , 2003 - All rights reserved.
8 //
9 // begin include "header.tjh"
10 //
11 // Sample header file for Java preprocessor
12 //
13 // end include "header.tjh"
14 // begin include "subinc/subhdr.tjh"
15 //
16 // Sample header file for Java preprocessor from a subdirectory
17 // of include root directory "tjpp_inst/tjpp_include"
18 //
19 // end include "subinc/subhdr.tjh"
20
21 package com.somusar.tjpptest;
22
23 /**
24 * Class ComplexClass:
25 *
26 * A software entity with several fields and collections.
27 */
28
29 import com.somusar.tjpptest.subpackage.SimpleClass;
30 import java.util.Date;
31
32 public class ComplexClass extends SimpleClass {
33
34 // Map enum 'Color' onto an int with a set of values
35 public static final int RED = 0;
36 public static final int GREEN = 1;
37 public static final int BLUE = 2;
38
39 private boolean aBool;
40 private int aColor;
41 private double aFloat;
42 private int aRange;
43 private String aString;
44 private Date aTime;
45 private int aUniqueId; // read-only
46 private int anInt; // read-only
47 private int anotherColor; // read-only
48 private Object aThing;
49 private int anIntArray[][];
50
51 /*
52 * Get methods
53 */
54
55 public boolean getABool() {
56 return aBool;
57 }
58
59 public int getAColor() {
60 return aColor;
61 }
62
63 public double getAFloat() {
64 return aFloat;
65 }
66
67 public int getARange() {
68 return aRange;
69 }
70
71 public String getAString() {
72 return aString;
73 }
74
75 public Date getATime() {
76 return aTime;
77 }
78
79 public int getAUniqueId() {
80 return aUniqueId;
81 }
82
83 public int getAnInt() {
84 return anInt;
85 }
86
87 public int getAnotherColor() {
88 return anotherColor;
89 }
90
91 public Object getAThing() {
92 return aThing;
93 }
94
95 public int[][] getAnIntArray() {
96 return anIntArray;
97 }
98
99 /*
100 * Set methods
101 */
102
103 public void setABool( boolean aBool ) {
104 this.aBool = aBool;
105 }
106
107 public void setAColor( int aColor ) {
108 this.aColor = aColor;
109 }
110
111 public void setAFloat( double aFloat ) {
112 this.aFloat = aFloat;
113 }
114
115 public void setARange( int aRange ) {
116 this.aRange = aRange;
117 }
118
119 public void setAString( String aString ) {
120 this.aString = aString;
121 }
122
123 public void setATime( Date aTime ) {
124 this.aTime = aTime;
125 }
126
127 public void setAThing( Object aThing ) {
128 this.aThing = aThing;
129 }
130
131 public void setAnIntArray( int anIntArray[][] ) {
132 this.anIntArray = anIntArray;
133 }
134
135
136 /**
137 * Method 'A function'
138 */
139
140 public boolean aFunction (
141 int aRange,
142 int aColor
143 )
144 {
145 System.err.println("[T] File ComplexClass.java, line 145 (src: ComplexClass.tj, 53)");
146 System.err.println("[T] [aRange = '" + aRange + "']");
147 System.err.println("[T] [aColor = '" + aColor + "']");
148 {
149 if (! (aRange >= 0 && aRange < 20000)) {
150 System.err.println("[A] -------------");
151 System.err.println("[A] --- File ComplexClass.java, line 149 (src: ComplexClass.tj, 54)");
152 System.err.println("[A] --- Assertion 'aRange >= 0 && aRange < 20000' failed");
153 System.err.println("[A] -------------");
154 }
155 }
156 return true;
157 }
158
159 /**
160 * Method 'A function'
161 */
162
163 public double aFunction (
164 int anInt
165 )
166 {
167 double d = ((anInt) * 100.0 / (1000));
168 System.err.println("[T] File ComplexClass.java, line 168 (src: ComplexClass.tj, 70)");
169 System.err.println("[T] [d = '" + d + "']");
170 return d;
171 }
172
173 public String toString() {
174 String s = "[" +
175 " aBool = '" + aBool + "'" +
176 " aColor = '" + aColor + "'" +
177 " aFloat = '" + aFloat + "'" +
178 " aRange = '" + aRange + "'" +
179 " aString = '" + aString + "'" +
180 " aTime = '" + aTime + "'" +
181 " aUniqueId = '" + aUniqueId + "'" +
182 " anInt = '" + anInt + "'" +
183 " anotherColor = '" + anotherColor + "'" +
184 " aThing = '" + aThing + "'" +
185 " anIntArray = '" + anIntArray + "'" +
186 " ]";
187 return s;
188 }
189
190 }
191
192 // WARNING: file "ComplexClass.java" generated from "ComplexClass.tj"
193 // Changes should be applied on the source file.
|
|
|
Code Example 7 - Implementation of assert
|
Generation of assertion code is controlled by
tjpp's variable ASSERTION_SWITCH (lines 11-13).
Line 14 defines a string pattern to be printed out
by each assertion message.
Line 16 retrieves the current line numbers of both
input (".tj") and output (".java") files.
The assertion expression passed as argument to assert
is referred to by means of tjpp's variable REG_ALL
on lines 17 and 20.
The code fragment pattern generated for each assert is defined by
lines 15 and 17-23, and can easily be customized as needed, for instance
adding error-raising statements.
|
|
|
Source code - File "input_code/tjpp_lib/assert"
|
1 @ INTERFACE(...)
2 |
3 | Generate a block of statements to check an assertion.
4 | The assertion expression is passed as one or more arguments
5 | and used below as REG_ALL.
6 | When an assertion evaluates to false, the generated code
7 | prints out a trace message with source file and line, then
8 | continues normal execution flow.
9 | No code is generated if ASSERTION_SWITCH is not "on".
10 |
11 @ IF ASSERTION_SWITCH#on
12 @ QUIT
13 @ ENDIF
14 @ SET ASSERTIONBANNER=[A] ---
15 {
16 @ SET FILELOC=$jfileloc
17 if (! (REG_ALL)) {
18 System.err.println("ASSERTIONBANNER----------");
19 System.err.println("ASSERTIONBANNER FILELOC");
20 System.err.println("ASSERTIONBANNER Assertion 'REG_ALL' failed");
21 System.err.println("ASSERTIONBANNER----------");
22 }
23 }
|
|
[Previous chapter]
[Next chapter]
[Back to top]
|