1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.codehaus.groovy.ast.expr;
47
48 import java.util.ArrayList;
49 import java.util.Iterator;
50 import java.util.List;
51
52 import org.codehaus.groovy.ast.ASTNode;
53 import org.codehaus.groovy.classgen.AsmClassGenerator2;
54 import groovy.lang.GroovyRuntimeException;
55
56 /***
57 * Represents a base class for expressions which evaluate as an object
58 *
59 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
60 * @version $Revision: 1.3 $
61 */
62 public abstract class Expression extends ASTNode {
63 protected boolean typeResolved = false;
64
65 public boolean isResolveFailed() {
66 return resolveFailed;
67 }
68
69 public void setResolveFailed(boolean resolveFailed) {
70 this.resolveFailed = resolveFailed;
71 }
72
73 public String getFailure() {
74 return failure;
75 }
76
77 public void setFailure(String failure) {
78 this.failure = failure;
79 }
80
81 String failure = "";
82 private boolean resolveFailed = false;
83
84 public Class getTypeClass() {
85 return typeClass;
86 }
87
88 public void setTypeClass(Class typeClass) {
89 if (typeClass != null) {
90 this.typeClass = typeClass;
91 type = typeClass.getName();
92 setTypeResolved(true);
93 }
94 }
95
96 public Class typeClass = null;
97
98 public String getType() {
99 if (type != null){
100 return type;
101 } else {
102 Class cls = getTypeClass();
103 return cls != null? cls.getName() : null;
104 }
105 }
106
107 /***
108 * true if the datatype can be changed, false otherwise.
109 * @return
110 */
111 public boolean isDynamic() {
112 return true;
113 }
114
115 protected String type = null;
116 /***
117 * Return a copy of the expression calling the transformer on any nested expressions
118 * @param transformer
119 * @return
120 */
121 public abstract Expression transformExpression(ExpressionTransformer transformer);
122
123 /***
124 * Transforms the list of expressions
125 * @return a new list of transformed expressions
126 */
127 protected List transformExpressions(List expressions, ExpressionTransformer transformer) {
128 List list = new ArrayList(expressions.size());
129 for (Iterator iter = expressions.iterator(); iter.hasNext(); ) {
130 list.add(transformer.transform((Expression) iter.next()));
131 }
132 return list;
133 }
134
135 public void setType(String name) {
136 if (name == null)
137 throw new GroovyRuntimeException("cannot set null on type");
138
139 if (name.equals("int")) {
140 setTypeClass(Integer.TYPE);
141 return;
142 }
143 else if (name.equals("long")) {
144 setTypeClass(Long.TYPE);
145 return;
146 }
147 else if (name.equals("short")) {
148 setTypeClass(Short.TYPE);
149 return;
150 }
151 else if (name.equals("float")) {
152 setTypeClass(Float.TYPE);
153 return;
154 }
155 else if (name.equals("double")) {
156 setTypeClass(Double.TYPE);
157 return;
158 }
159 else if (name.equals("byte")) {
160 setTypeClass(Byte.TYPE);
161 return;
162 }
163 else if (name.equals("char")) {
164 setTypeClass(Character.TYPE);
165 return;
166 }
167 else if (name.equals("boolean")) {
168 setTypeClass(Boolean.TYPE);
169 return;
170 }
171
172 if (name.endsWith("[]")) {
173 String prefix = "[";
174 name = name.substring(0, name.length() - 2);
175
176 if (name.equals("int")) {
177 type = prefix + "I";
178 }
179 else if (name.equals("long")) {
180 type = prefix + "J";
181 }
182 else if (name.equals("short")) {
183 type = prefix + "S";
184 }
185 else if (name.equals("float")) {
186 type = prefix + "F";
187 }
188 else if (name.equals("double")) {
189 type = prefix + "D";
190 }
191 else if (name.equals("byte")) {
192 type = prefix + "B";
193 }
194 else if (name.equals("char")) {
195 type = prefix + "C";
196 }
197 else if (name.equals("boolean")) {
198 type = prefix + "Z";
199 } else {
200 type = prefix + "L" + name + ";";
201 }
202 }
203 else {
204 type = name;
205 }
206 if (type == null) {
207 System.out.println("Expression.setType(): null");
208 System.out.println("name = " + name);
209 }
210 try {
211 this.setTypeClass(Class.forName(type, false, this.getClass().getClassLoader()));
212 } catch (Throwable e) {
213 this.typeResolved = false;
214 }
215 }
216
217 public boolean isTypeResolved() {
218 return typeResolved;
219 }
220
221 public void setTypeResolved(boolean b) {
222 this.typeResolved = b;
223 this.resolveFailed = false;
224 }
225
226 public void resolve(AsmClassGenerator2 cg) {
227 if (shouldContinue()) {
228 resolveType(cg);
229 }
230 }
231
232 protected abstract void resolveType(AsmClassGenerator2 resolver);
233
234 protected boolean shouldContinue() {
235 return !isResolveFailed() && !isTypeResolved();
236 }
237
238 }