Source code: openjava/ptree/util/ExpansionApplier.java
1 /*
2 * ExpansionApplier.java
3 *
4 * comments here.
5 *
6 * @author Michiaki Tatsubori
7 * @version %VERSION% %DATE%
8 * @see java.lang.Object
9 *
10 * COPYRIGHT 1998 by Michiaki Tatsubori, ALL RIGHTS RESERVED.
11 */
12 package openjava.ptree.util;
13
14 import openjava.mop.Environment;
15 import openjava.mop.OJClass;
16 import openjava.ptree.AllocationExpression;
17 import openjava.ptree.ArrayAccess;
18 import openjava.ptree.ArrayAllocationExpression;
19 import openjava.ptree.AssignmentExpression;
20 import openjava.ptree.BinaryExpression;
21 import openjava.ptree.CastExpression;
22 import openjava.ptree.ClassLiteral;
23 import openjava.ptree.ConditionalExpression;
24 import openjava.ptree.Expression;
25 import openjava.ptree.FieldAccess;
26 import openjava.ptree.InstanceofExpression;
27 import openjava.ptree.Literal;
28 import openjava.ptree.MethodCall;
29 import openjava.ptree.ParseTreeException;
30 import openjava.ptree.SelfAccess;
31 import openjava.ptree.Statement;
32 import openjava.ptree.TypeName;
33 import openjava.ptree.UnaryExpression;
34 import openjava.ptree.Variable;
35 import openjava.ptree.VariableDeclaration;
36 import openjava.tools.DebugOut;
37
38 /**
39 * The class <code>ExpansionApplier</code> is an evaluator of each
40 * objects of <code>ParseTree</code> family. Each methods in
41 * this class is invoked from the class <code>EvaluationShuttle</code>.
42 * <p>
43 * The method <code>evaluateDown()</code> is invoked before evaluating
44 * the children of the parse tree object, and <code>evaluateUp()</code>
45 * is invoked after the evaluation.
46 * <p>
47 * For a class <code>P</code> and a object <code>p</code> statically
48 * typed as P, the parts in source code each expantion will be applied
49 * are:
50 * <ul>
51 * <li>Allocation <code>new P()</code>
52 * <li>ArrayAllocation <code>new P[expr]</code>
53 * <li>MethodCall <code>P.m()</code>, <code>p.m()</code>
54 * <li>FieldRead <code>P.f</code>, <code>p.f</code> as a right side value
55 * <li>FieldWrite <code>P.f = expr</code>, <code>p.f = expr</code>
56 * <li>ArrayAccess <code>ap[expr]</code> for <code>P[] ap;</code>
57 * <li>Expression <code>p</code>
58 * </ul>
59 * in feature version:
60 * <ul>
61 * <li>CastExpression <code>(P) expr</code> including implicit cast
62 * <li>CastedExpression <code>(Q) p</code> including implicit cast
63 * </ul>
64 *
65 * @author Michiaki Tatsubori
66 * @version 1.0
67 * @since $Id: ExpansionApplier.java,v 1.2 2003/02/19 02:55:00 tatsubori Exp $
68 * @see openjava.ptree.ParseTree
69 * @see openjava.ptree.util.EvaluationShuttle
70 */
71 public class ExpansionApplier extends VariableBinder {
72 public ExpansionApplier(Environment env) {
73 super(env);
74 }
75
76 private OJClass getType(Expression p) throws ParseTreeException {
77 OJClass result = null;
78 try {
79 result = p.getType(getEnvironment());
80 } catch (Exception e) {
81 e.printStackTrace();
82 throw new ParseTreeException(e);
83 }
84 DebugOut.println("type eval - " + p + "\t: " + result);
85 if (result == null) {
86 System.err.println("cannot resolve the type of expression");
87 System.err.println(p.getClass() + " : " + p);
88 System.err.println(getEnvironment());
89 /*****DebugOut.println(getEnvironment().toString());*/
90 if (p instanceof ArrayAccess) {
91 ArrayAccess aaexpr = (ArrayAccess) p;
92 Expression refexpr = aaexpr.getReferenceExpr();
93 OJClass refexprtype = null;
94 OJClass comptype = null;
95 try {
96 refexprtype = refexpr.getType(getEnvironment());
97 comptype = refexprtype.getComponentType();
98 } catch (Exception ex) {
99 }
100 System.err.println(
101 refexpr + " : " + refexprtype + " : " + comptype);
102 }
103 }
104 return result;
105 }
106
107 private OJClass getSelfType() throws ParseTreeException {
108 OJClass result;
109 try {
110 Environment env = getEnvironment();
111 String selfname = env.currentClassName();
112 result = env.lookupClass(selfname);
113 } catch (Exception ex) {
114 throw new ParseTreeException(ex);
115 }
116 return result;
117 }
118
119 private OJClass getType(TypeName typename) throws ParseTreeException {
120 OJClass result = null;
121 try {
122 Environment env = getEnvironment();
123 String qname = env.toQualifiedName(typename.toString());
124 result = env.lookupClass(qname);
125 } catch (Exception ex) {
126 throw new ParseTreeException(ex);
127 }
128 DebugOut.println("type eval - class access : " + result);
129 if (result == null) {
130 System.err.println("unknown type for a type name : " + typename);
131 }
132 return result;
133 }
134
135 private OJClass computeRefType(TypeName typename, Expression expr)
136 throws ParseTreeException {
137 if (typename != null)
138 return getType(typename);
139 if (expr != null)
140 return getType(expr);
141 return getSelfType();
142 }
143
144 public void visit(AssignmentExpression p) throws ParseTreeException {
145 Expression left = p.getLeft();
146 if (!(left instanceof FieldAccess)) {
147 super.visit(p);
148 return;
149 }
150 FieldAccess fldac = (FieldAccess) left;
151 Expression refexpr = fldac.getReferenceExpr();
152 TypeName reftype = fldac.getReferenceType();
153 Expression value = p.getRight();
154 /* custom version of visit() skipping the field */
155 Expression newp;
156 newp = this.evaluateDown(p);
157 if (newp != p) {
158 p.replace(newp);
159 newp.accept(this);
160 return;
161 }
162
163 if (refexpr != null) {
164 refexpr.accept(this);
165 } else if (reftype != null) {
166 reftype.accept(this);
167 }
168 value.accept(this);
169
170 newp = this.evaluateUp(p);
171 if (newp != p)
172 p.replace(newp);
173 }
174
175 /**
176 * Includes expandAllocation() and expandExpression().
177 */
178 public Expression evaluateUp(AllocationExpression p)
179 throws ParseTreeException {
180 OJClass type = getType(p);
181 Expression newp;
182 newp = type.expandAllocation(getEnvironment(), p);
183 if (newp != p)
184 return newp;
185 newp = type.expandExpression(getEnvironment(), p);
186 if (newp != p)
187 return newp;
188 return super.evaluateUp(p);
189 }
190
191 /**
192 * Includes expandArrayAccess() and expandExpression().
193 */
194 public Expression evaluateUp(ArrayAccess p) throws ParseTreeException {
195 OJClass type = getType(p);
196 Expression newp;
197 newp = type.expandArrayAccess(getEnvironment(), p);
198 if (newp != p)
199 return newp;
200 newp = type.expandExpression(getEnvironment(), p);
201 if (newp != p)
202 return newp;
203 return super.evaluateUp(p);
204 }
205
206 /**
207 * Includes expandArrayAllocation() and expandExpression().
208 */
209 public Expression evaluateUp(ArrayAllocationExpression p)
210 throws ParseTreeException {
211 OJClass type = getType(p);
212 Expression newp;
213 newp = type.expandArrayAllocation(getEnvironment(), p);
214 if (newp != p)
215 return newp;
216 newp = type.expandExpression(getEnvironment(), p);
217 if (newp != p)
218 return newp;
219 return super.evaluateUp(p);
220 }
221
222 /**
223 * Includes expandFieldWrite(), expandAssignmentExpression()
224 * and expandExpression().
225 */
226 public Expression evaluateUp(AssignmentExpression p)
227 throws ParseTreeException {
228 Expression left = p.getLeft();
229 if (left instanceof FieldAccess) {
230 FieldAccess fldac = (FieldAccess) left;
231 OJClass reftype =
232 computeRefType(
233 fldac.getReferenceType(),
234 fldac.getReferenceExpr());
235 if (reftype != getSelfType()) {
236 Expression newp = reftype.expandFieldWrite(getEnvironment(), p);
237 if (!(newp instanceof AssignmentExpression))
238 return newp;
239 p = (AssignmentExpression) newp;
240 }
241 }
242
243 OJClass type = getType(p);
244 if (type != getSelfType()) {
245 Expression newp =
246 type.expandAssignmentExpression(getEnvironment(), p);
247 if (!(newp instanceof AssignmentExpression))
248 return newp;
249 p = (AssignmentExpression) newp;
250 type = getType(p);
251 }
252 if (type != getSelfType()) {
253 Expression newp = type.expandExpression(getEnvironment(), p);
254 if (!(newp instanceof AssignmentExpression))
255 return newp;
256 p = (AssignmentExpression) newp;
257 }
258 return super.evaluateUp(p);
259 }
260
261 /**
262 * Includes expandExpression().
263 */
264 public Expression evaluateUp(BinaryExpression p)
265 throws ParseTreeException {
266 OJClass type = getType(p);
267 Expression newp;
268 newp = type.expandExpression(getEnvironment(), p);
269 if (newp != p)
270 return newp;
271 return super.evaluateUp(p);
272 }
273
274 /**
275 * Includes expandCastExpression(), expandCastedExpression() and
276 * expandExpression().
277 */
278 public Expression evaluateUp(CastExpression p) throws ParseTreeException {
279 OJClass type = getType(p);
280 OJClass orgType = getType(p.getExpression());
281 Expression newp;
282 newp = orgType.expandCastedExpression(getEnvironment(), p);
283 if (newp != p)
284 return newp;
285 newp = type.expandCastExpression(getEnvironment(), p);
286 if (newp != p)
287 return newp;
288 newp = type.expandExpression(getEnvironment(), p);
289 if (newp != p)
290 return newp;
291 return super.evaluateUp(p);
292 }
293
294 /**
295 * Includes expandExpression().
296 */
297 public Expression evaluateUp(ClassLiteral p) throws ParseTreeException {
298 OJClass type = getType(p);
299 Expression newp;
300 newp = type.expandExpression(getEnvironment(), p);
301 if (newp != p)
302 return newp;
303 return super.evaluateUp(p);
304 }
305
306 /**
307 * Includes expandExpression().
308 */
309 public Expression evaluateUp(ConditionalExpression p)
310 throws ParseTreeException {
311 OJClass type = getType(p);
312 Expression newp;
313 newp = type.expandExpression(getEnvironment(), p);
314 if (newp != p)
315 return newp;
316 return super.evaluateUp(p);
317 }
318
319 /**
320 * Includes expandFieldRead() and expandExpression().
321 * Not to be applied for itself.
322 */
323 public Expression evaluateUp(FieldAccess p) throws ParseTreeException {
324 {
325 OJClass reftype =
326 computeRefType(p.getReferenceType(), p.getReferenceExpr());
327 if (reftype != getSelfType()) {
328 Expression newp = reftype.expandFieldRead(getEnvironment(), p);
329 if (newp != p)
330 return newp;
331 }
332 }
333 {
334 OJClass type = getType(p);
335 Expression newp = type.expandExpression(getEnvironment(), p);
336 if (!(newp instanceof FieldAccess))
337 return newp;
338 p = (FieldAccess) newp;
339 }
340 return super.evaluateUp(p);
341 }
342
343 /**
344 * Includes expandExpression().
345 */
346 public Expression evaluateUp(InstanceofExpression p)
347 throws ParseTreeException {
348 OJClass type = getType(p);
349 Expression newp;
350 newp = type.expandExpression(getEnvironment(), p);
351 if (newp != p)
352 return newp;
353 return super.evaluateUp(p);
354 }
355
356 /**
357 * Includes expandExpression().
358 */
359 public Expression evaluateUp(Literal p) throws ParseTreeException {
360 OJClass type = getType(p);
361 Expression newp;
362 newp = type.expandExpression(getEnvironment(), p);
363 if (newp != p)
364 return newp;
365 return super.evaluateUp(p);
366 }
367
368 /**
369 * Includes expandMethodCall() and expandExpression().
370 */
371 public Expression evaluateUp(MethodCall p) throws ParseTreeException {
372 {
373 OJClass reftype =
374 computeRefType(p.getReferenceType(), p.getReferenceExpr());
375 if (reftype != getSelfType()) {
376 Expression newp = reftype.expandMethodCall(getEnvironment(), p);
377 if (newp != p)
378 return newp;
379 }
380 }
381 {
382 OJClass type = getType(p);
383 Expression newp = type.expandExpression(getEnvironment(), p);
384 if (!(newp instanceof MethodCall))
385 return newp;
386 p = (MethodCall) newp;
387 }
388 return super.evaluateUp(p);
389 }
390
391 /**
392 * Includes expandExpression().
393 */
394 public Expression evaluateUp(SelfAccess p) throws ParseTreeException {
395 OJClass type = getType(p);
396 Expression newp;
397 newp = type.expandExpression(getEnvironment(), p);
398 if (newp != p)
399 return newp;
400 return super.evaluateUp(p);
401 }
402
403 /**
404 * Includes expandTypeName().
405 */
406 public TypeName evaluateUp(TypeName p) throws ParseTreeException {
407 OJClass type = getType(p);
408 TypeName newp;
409 newp = type.expandTypeName(getEnvironment(), p);
410 if (newp != p)
411 return newp;
412 return super.evaluateUp(p);
413 }
414
415 /**
416 * Includes expandExpression().
417 */
418 public Expression evaluateUp(UnaryExpression p) throws ParseTreeException {
419 OJClass type = getType(p);
420 Expression newp;
421 newp = type.expandExpression(getEnvironment(), p);
422 if (newp != p)
423 return newp;
424 return super.evaluateUp(p);
425 }
426
427 /**
428 * Includes expandExpression().
429 */
430 public Expression evaluateUp(Variable p) throws ParseTreeException {
431 OJClass type = getType(p);
432
433 /* special ignorance for variable ? */
434 if (type == null)
435 return p;
436
437 Expression newp;
438 newp = type.expandExpression(getEnvironment(), p);
439 if (newp != p)
440 return newp;
441 return super.evaluateUp(p);
442 }
443
444 /**
445 * Includes expandVariableDeclaration().
446 */
447 public Statement evaluateUp(VariableDeclaration p)
448 throws ParseTreeException {
449 OJClass type = getType(p.getTypeSpecifier());
450 Statement newp;
451 newp = type.expandVariableDeclaration(getEnvironment(), p);
452 if (newp != p)
453 return newp;
454 return super.evaluateUp(p);
455 }
456
457 }