Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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 }