01: /*
02: * Spoon - http://spoon.gforge.inria.fr/
03: * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
04: *
05: * This software is governed by the CeCILL-C License under French law and
06: * abiding by the rules of distribution of free software. You can use, modify
07: * and/or redistribute the software under the terms of the CeCILL-C license as
08: * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
09: *
10: * This program is distributed in the hope that it will be useful, but WITHOUT
11: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12: * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
13: *
14: * The fact that you are presently reading this means that you have had
15: * knowledge of the CeCILL-C license and that you accept its terms.
16: */
17:
18: package spoon.template;
19:
20: import spoon.reflect.code.CtBlock;
21: import spoon.reflect.code.CtExpression;
22: import spoon.reflect.code.CtReturn;
23: import spoon.reflect.declaration.CtClass;
24: import spoon.reflect.declaration.CtSimpleType;
25:
26: /**
27: * This class represents an expression template parameter expressed in Java.
28: *
29: * <p>
30: * To define a new expression template parameter, you must subclass this class
31: * and implement the {@link #expression()} method, which actually defines the
32: * Java expression. It corresponds to a {@link spoon.reflect.code.CtExpression}.
33: */
34: public abstract class ExpressionTemplateParameter<T> implements
35: TemplateParameter<T> {
36:
37: /**
38: * Returns the expression.
39: */
40: @SuppressWarnings("unchecked")
41: public static <T> CtExpression<T> getExpression(
42: CtClass<? extends ExpressionTemplateParameter<?>> p) {
43: CtBlock<?> b = getExpressionBlock(p);
44: return ((CtReturn<T>) b.getStatements().get(0))
45: .getReturnedExpression();
46: }
47:
48: @SuppressWarnings("unchecked")
49: private static CtBlock<?> getExpressionBlock(
50: CtClass<? extends ExpressionTemplateParameter<?>> p) {
51: CtBlock b = p.getMethod("expression").getBody();
52: return b;
53: }
54:
55: /**
56: * Creates a new expression template parameter.
57: */
58: public ExpressionTemplateParameter() {
59: }
60:
61: /**
62: * This method must be implemented to define the template expression. The
63: * convention is that the defined expression corresponds to the expression
64: * returned by the return statement of the method.
65: */
66: public abstract T expression() throws Throwable;
67:
68: @SuppressWarnings("unchecked")
69: public CtExpression<T> getSubstitution(CtSimpleType<?> targetType) {
70: CtClass<? extends ExpressionTemplateParameter<?>> c;
71: CtBlock<?> b;
72: c = targetType.getFactory().Template().get(this .getClass());
73: if (c == null) {
74: c = targetType.getFactory().Class().get(this .getClass());
75: }
76: if (this instanceof Template) {
77: b = Substitution.substitute(targetType, (Template) this ,
78: getExpressionBlock(c));
79: } else {
80: b = targetType.getFactory().Core().clone(
81: getExpressionBlock(c));
82: }
83: return ((CtReturn<T>) b.getStatements().get(0))
84: .getReturnedExpression();
85: }
86:
87: public T S() {
88: return null;
89: }
90: }
|