KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > spoon > reflect > factory > CodeFactory


1 package spoon.reflect.factory;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.List JavaDoc;
5 import java.util.Set JavaDoc;
6 import java.util.TreeSet JavaDoc;
7
8 import spoon.reflect.Factory;
9 import spoon.reflect.code.BinaryOperatorKind;
10 import spoon.reflect.code.CtAssignment;
11 import spoon.reflect.code.CtBinaryOperator;
12 import spoon.reflect.code.CtBlock;
13 import spoon.reflect.code.CtExpression;
14 import spoon.reflect.code.CtFieldAccess;
15 import spoon.reflect.code.CtInvocation;
16 import spoon.reflect.code.CtLiteral;
17 import spoon.reflect.code.CtLocalVariable;
18 import spoon.reflect.code.CtNewArray;
19 import spoon.reflect.code.CtStatement;
20 import spoon.reflect.code.CtStatementList;
21 import spoon.reflect.code.CtVariableAccess;
22 import spoon.reflect.declaration.CtNamedElement;
23 import spoon.reflect.declaration.CtVariable;
24 import spoon.reflect.declaration.ModifierKind;
25 import spoon.reflect.reference.CtExecutableReference;
26 import spoon.reflect.reference.CtFieldReference;
27 import spoon.reflect.reference.CtLocalVariableReference;
28 import spoon.reflect.reference.CtReference;
29 import spoon.reflect.reference.CtTypeReference;
30 import spoon.reflect.reference.CtVariableReference;
31
32 /**
33  * This sub-factory contains utility methods to create code elements. To avoid
34  * over-using reflection, consider using {@link spoon.template.Template}.
35  */

36 public class CodeFactory extends SubFactory {
37
38     private static final long serialVersionUID = 1L;
39
40     /**
41      * Creates a {@link spoon.reflect.code.CtCodeElement} sub-factory.
42      */

43     public CodeFactory(Factory factory) {
44         super(factory);
45     }
46
47     /**
48      * Creates a binary operator.
49      *
50      * @param <T>
51      * the type of the expression
52      * @param left
53      * the left operand
54      * @param right
55      * the right operand
56      * @param kind
57      * the operator kind
58      * @return a binary operator expression
59      */

60     public <T> CtBinaryOperator<T> createBinaryOperator(CtExpression<?> left,
61             CtExpression<?> right, BinaryOperatorKind kind) {
62         CtBinaryOperator<T> op = factory.Core().createBinaryOperator();
63         op.setLeftHandOperand(left);
64         op.setRightHandOperand(right);
65         setParent(op, left, right);
66         op.setKind(kind);
67         return op;
68     }
69
70     /**
71      * Creates a class access expression of the form <code>C.class</code>.
72      *
73      * @param <T>
74      * the actual type of the accessed class if available
75      * @param type
76      * a type reference to the accessed class
77      * @return the class access expression.
78      */

79     @SuppressWarnings JavaDoc("unchecked")
80     public <T> CtFieldAccess<Class JavaDoc<T>> createClassAccess(CtTypeReference<T> type) {
81         CtFieldAccess<Class JavaDoc<T>> ca = factory.Core().createFieldAccess();
82         CtTypeReference classType = factory.Type().createReference(Class JavaDoc.class);
83
84         ca.setType(classType);
85         CtFieldReference field = factory.Core().createFieldReference();
86         field.setDeclaringType(type);
87         field.setType(classType);
88         field.setSimpleName("class");
89         ca.setVariable(field);
90         return ca;
91     }
92
93     /**
94      * Creates an invocation (can be a statement or an expression).
95      *
96      * @param <T>
97      * the return type of the invoked method
98      * @param target
99      * the target expression
100      * @param executable
101      * the invoked executable
102      * @param arguments
103      * the argument list
104      * @return the new invocation
105      */

106     public <T> CtInvocation<T> createInvocation(CtExpression<?> target,
107             CtExecutableReference<T> executable, CtExpression<?>... arguments) {
108         List JavaDoc<CtExpression<?>> ext = new ArrayList JavaDoc<CtExpression<?>>();
109         for (CtExpression<?> arg : arguments) {
110             ext.add(arg);
111         }
112         return createInvocation(target, executable, ext);
113     }
114
115     /**
116      * Creates an invocation (can be a statement or an expression).
117      *
118      * @param <T>
119      * the return type of the invoked method
120      * @param target
121      * the target expression
122      * @param executable
123      * the invoked executable
124      * @param arguments
125      * the argument list
126      * @return the new invocation
127      */

128     public <T> CtInvocation<T> createInvocation(CtExpression<?> target,
129             CtExecutableReference<T> executable, List JavaDoc<CtExpression<?>> arguments) {
130         CtInvocation<T> invocation = factory.Core().createInvocation();
131         invocation.setTarget(target);
132         invocation.setExecutable(executable);
133         invocation.setArguments(arguments);
134         return invocation;
135     }
136
137     /**
138      * Creates a literal with a given value.
139      *
140      * @param <T>
141      * the type of the literal
142      * @param value
143      * the value of the litteral
144      * @return a new literal
145      */

146     public <T> CtLiteral<T> createLiteral(T value) {
147         CtLiteral<T> l = factory.Core().createLiteral();
148         l.setValue(value);
149         return l;
150     }
151
152     /**
153      * Creates a one-dimension array that must only contain literals.
154      */

155     @SuppressWarnings JavaDoc("unchecked")
156     public <T> CtNewArray<T[]> createLiteralArray(T[] value) {
157         if (!value.getClass().isArray())
158             throw new RuntimeException JavaDoc("value is not an array");
159         if (value.getClass().getComponentType().isArray())
160             throw new RuntimeException JavaDoc("can only create one-dimension arrays");
161         CtNewArray<T[]> array = factory.Core().createNewArray();
162         array.setType(factory.Type().createArrayReference(
163                 factory.Type().createReference(
164                         (Class JavaDoc<T>)value.getClass().getComponentType())));
165         for (T e : value) {
166             CtLiteral<T> l = factory.Core().createLiteral();
167             l.setValue(e);
168             l.setParent(array);
169             array.getElements().add(l);
170         }
171         return array;
172     }
173
174     /**
175      * Creates a local variable declaration.
176      *
177      * @param <T>
178      * the local variable type
179      * @param type
180      * the reference to the type
181      * @param name
182      * the name of the variable
183      * @param defaultExpression
184      * the assigned default expression
185      * @return a new local variable declaration
186      */

187     public <T> CtLocalVariable<T> createLocalVariable(CtTypeReference<T> type,
188             String JavaDoc name, CtExpression<T> defaultExpression) {
189         CtLocalVariable<T> var = factory.Core().createLocalVariable();
190         var.setSimpleName(name);
191         var.setType(type);
192         var.setDefaultExpression(defaultExpression);
193         return var;
194     }
195
196     /**
197      * Creates a local variable reference that points to an existing local
198      * variable (strong referencing).
199      */

200     public <T> CtLocalVariableReference<T> createLocalVariableReference(
201             CtLocalVariable<T> localVariable) {
202         CtLocalVariableReference<T> ref = factory.Core()
203                 .createLocalVariableReference();
204         ref.setType(localVariable.getType());
205         ref.setSimpleName(localVariable.getSimpleName());
206         ref.setDeclaration(localVariable);
207         return ref;
208     }
209
210     /**
211      * Creates a local variable reference with its name an type (weak
212      * referencing).
213      */

214     public <T> CtLocalVariableReference<T> createLocalVariableReference(
215             CtTypeReference<T> type, String JavaDoc name) {
216         CtLocalVariableReference<T> ref = factory.Core()
217                 .createLocalVariableReference();
218         ref.setType(type);
219         ref.setSimpleName(name);
220         return ref;
221     }
222
223     /**
224      * Creates a new statement list from an existing block.
225      */

226     @SuppressWarnings JavaDoc("unchecked")
227     public CtStatementList createStatementList(CtBlock<?> block) {
228         CtStatementList l = factory.Core().createStatementList();
229         for (CtStatement s : block.getStatements()) {
230             l.getStatements().add(factory.Core().clone(s));
231         }
232         return l;
233     }
234
235     /**
236      * Creates an access to a <code>this</code> variable (of the form
237      * <code>type.this</code>).
238      *
239      * @param <T>
240      * the actual type of <code>this</code>
241      * @param type
242      * the reference to the type that holds the <code>this</code>
243      * variable
244      * @return a <code>type.this</code> expression
245      */

246     public <T> CtFieldAccess<T> createThisAccess(CtTypeReference<T> type) {
247         CtFieldAccess<T> fa = factory.Core().createFieldAccess();
248         fa.setType(type);
249         CtFieldReference<T> field = factory.Core().createFieldReference();
250         field.setDeclaringType(type);
251         field.setType(type);
252         field.setSimpleName("this");
253         fa.setVariable(field);
254         return fa;
255     }
256
257     /**
258      * Creates a variable access.
259      */

260     public <T> CtVariableAccess<T> createVariableAccess(
261             CtVariableReference<T> variable, boolean isStatic) {
262         CtVariableAccess<T> va;
263         if (variable instanceof CtFieldReference) {
264             va = factory.Core().createFieldAccess();
265             // creates a this target for non-static fields to avoid name
266
// conflicts...
267
if (!isStatic) {
268                 ((CtFieldAccess<T>) va)
269                         .setTarget(createThisAccess(((CtFieldReference<T>) variable)
270                                 .getDeclaringType()));
271             }
272         } else {
273             va = factory.Core().createVariableAccess();
274         }
275         va.setVariable(variable);
276         va.setType(variable.getType());
277         return va;
278     }
279
280     /**
281      * Creates a list of variable accesses.
282      *
283      * @param variables
284      * the variables to be accessed
285      */

286     public List JavaDoc<CtExpression<?>> createVariableAccesses(
287             List JavaDoc<? extends CtVariable<?>> variables) {
288         List JavaDoc<CtExpression<?>> result = new ArrayList JavaDoc<CtExpression<?>>();
289         for (CtVariable<?> v : variables) {
290             result.add(createVariableAccess(v.getReference(), v.getModifiers()
291                     .contains(ModifierKind.STATIC)));
292         }
293         return result;
294     }
295
296     /**
297      * Creates a variable assignment (can be an expression or a statement).
298      *
299      * @param <T>
300      * the type of the assigned variable
301      * @param variable
302      * a reference to the assigned variable
303      * @param isStatic
304      * tells if the assigned variable is static or not
305      * @param expression
306      * the assigned expression
307      * @return a variable assignment
308      */

309     public <T> CtAssignment createVariableAssignment(
310             CtVariableReference<T> variable, boolean isStatic,
311             CtExpression<T> expression) {
312         CtAssignment<T, T> va = factory.Core().createAssignment();
313         va.setAssignment(expression);
314         expression.setParent(va);
315         CtVariableAccess<T> vaccess = createVariableAccess(variable, isStatic);
316         va.setAssigned(vaccess);
317         vaccess.setParent(va);
318         return va;
319     }
320
321     /**
322      * Creates a list of statements that contains the assignments of a set of
323      * variables.
324      *
325      * @param variables
326      * the variables to be assigned
327      * @param expressions
328      * the assigned expressions
329      * @return a list of variable assignments
330      */

331     @SuppressWarnings JavaDoc("unchecked")
332     public CtStatementList createVariableAssignments(
333             List JavaDoc<? extends CtVariable> variables,
334             List JavaDoc<? extends CtExpression> expressions) {
335         CtStatementList<?> result = factory.Core().createStatementList();
336         for (int i = 0; i < variables.size(); i++) {
337             result.getStatements().add(
338                     createVariableAssignment(variables.get(i).getReference(),
339                             variables.get(i).getModifiers().contains(
340                                     ModifierKind.STATIC), expressions.get(i)));
341         }
342         return result;
343     }
344
345     /**
346      * Gets a list of references from a list of elements.
347      *
348      * @param <R>
349      * the expected reference type
350      * @param <E>
351      * the element type
352      * @param elements
353      * the element list
354      * @return the corresponding list of references
355      */

356     @SuppressWarnings JavaDoc("unchecked")
357     public <R extends CtReference, E extends CtNamedElement> List JavaDoc<R> getReferences(
358             List JavaDoc<E> elements) {
359         List JavaDoc<R> refs = new ArrayList JavaDoc<R>();
360         for (E e : elements) {
361             refs.add((R) e.getReference());
362         }
363         return refs;
364     }
365
366     /**
367      * Creates a modifier set.
368      *
369      * @param modifiers
370      * to put in set
371      * @return Set of given modifiers
372      */

373     public Set JavaDoc<ModifierKind> modifiers(ModifierKind... modifiers) {
374         Set JavaDoc<ModifierKind> ret = new TreeSet JavaDoc<ModifierKind>();
375         for (ModifierKind m : modifiers)
376             ret.add(m);
377         return ret;
378     }
379
380 }
381
Popular Tags