KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > spoon > jdiet > NewClassProcessor


1 package spoon.jdiet;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.Collection JavaDoc;
5 import java.util.List JavaDoc;
6 import java.util.Map JavaDoc;
7 import java.util.Set JavaDoc;
8 import java.util.Vector JavaDoc;
9
10 import spoon.jdiet.rt.Helper;
11 import spoon.processing.AbstractProcessor;
12 import spoon.processing.TraversalStrategy;
13 import spoon.reflect.code.CtExpression;
14 import spoon.reflect.code.CtInvocation;
15 import spoon.reflect.code.CtNewClass;
16 import spoon.reflect.declaration.CtClass;
17 import spoon.reflect.factory.CodeFactory;
18 import spoon.reflect.factory.ExecutableFactory;
19 import spoon.reflect.factory.TypeFactory;
20 import spoon.reflect.reference.CtExecutableReference;
21 import spoon.reflect.reference.CtTypeReference;
22
23 /**
24  * This processor replaces class instantiation with a J2ME compliant equivalent
25  * instantiation.
26  *
27  * @author Lionel Seinturier <Lionel.Seinturier@lifl.fr>
28  */

29 public class NewClassProcessor extends AbstractProcessor<CtNewClass> {
30     
31     public TraversalStrategy getTraversalStrategy() {
32         // Let arguments included in the construction be visited first
33
return TraversalStrategy.POST_ORDER;
34     }
35     
36     public void process(CtNewClass nc) {
37         
38         TypeFactory tf = getFactory().Type();
39         ExecutableFactory ef = getFactory().Executable();
40         CodeFactory cf = getFactory().Code();
41
42         CtTypeReference ctr = getType(nc);
43         
44         if( !ctr.isPrimitif() ) {
45             
46             // Transform new ArrayList(Collection) (or a sub-type) into Helper.newList
47
// Do not use List as Vector implements List
48
if( ctr.isSubtypeOf(tf.createReference(ArrayList JavaDoc.class)) ) {
49                 List JavaDoc<CtExpression<?>> args = nc.getArguments();
50                 if( args.size() == 1 ) {
51                     CtExpression<?> arg = args.get(0);
52                     if( arg.getType().isSubtypeOf(tf.createReference(Collection JavaDoc.class)) ) {
53                         CtExecutableReference replmeth =
54                             ef.createReference(
55                                     tf.createReference(Helper.class),
56                                     true,"newList",
57                                     tf.createReference(Vector JavaDoc.class));
58                         CtInvocation repl =
59                             cf.createInvocation(null,replmeth,args);
60                         nc.replace(repl);
61                         return;
62                     }
63                 }
64             }
65             
66             // Transform new Set(Collection) (or a sub-type) into Helper.newSet
67
if( ctr.isSubtypeOf(tf.createReference(Set JavaDoc.class)) ) {
68                 List JavaDoc<CtExpression<?>> args = nc.getArguments();
69                 if( args.size() == 1 ) {
70                     CtExpression<?> arg = args.get(0);
71                     
72                     if( arg.getType().isSubtypeOf(tf.createReference(Collection JavaDoc.class)) ) {
73                         CtExecutableReference replmeth =
74                             ef.createReference(
75                                     tf.createReference(Helper.class),
76                                     true,"newSet",
77                                     tf.createReference(Vector JavaDoc.class));
78                         CtInvocation repl =
79                             cf.createInvocation(null,replmeth,args);
80                         nc.replace(repl);
81                         return;
82                     }
83                 }
84             }
85             
86             /*
87              * No else clause the previous branches may not match all
88              * conditions. In such a case, we may need to enter the next branch
89              * (especially for new Collection(...) where ... is different from
90              * Collection.
91              */

92             
93             // Transform new Collection (or a sub-type) into new Vector
94
if( ctr.isSubtypeOf(tf.createReference(Collection JavaDoc.class)) ) {
95                 ctr.setSimpleName("Vector");
96             }
97             
98             // Transform new Map (or a sub-type) into new Hashtable
99
else if( ctr.isSubtypeOf(tf.createReference(Map JavaDoc.class)) ) {
100                 ctr.setSimpleName("Hashtable");
101             }
102             
103             // Transform new Throwable(Throwable t) into new Throwable(t.getMessage())
104
else if( ctr.isSubtypeOf(tf.createReference(Throwable JavaDoc.class)) ) {
105                 List JavaDoc<CtExpression<?>> args = nc.getArguments();
106                 if( args.size() == 1 ) {
107                     CtExpression<?> arg = args.get(0);
108                     if( arg.getType().isSubtypeOf(tf.createReference(Throwable JavaDoc.class)) ) {
109                         CtExecutableReference getmessage =
110                             ef.createReference(
111                                 tf.createReference(Throwable JavaDoc.class),
112                                 "getMessage" );
113                         CtInvocation repl = cf.createInvocation(arg,getmessage);
114                         arg.replace(repl);
115                     }
116                 }
117             }
118         }
119     }
120     
121     /**
122      * Return the type of a CtNewClass element.
123      * Deals with anonymous class instanciation
124      * e.g. new Thread(){ public void run(){} }
125      * or new Runnable(){ public void run(){} }
126      *
127      * We don't use the CtTypeReference of the anonymous class which is
128      * under-defined with spoon (e.g. simpleName == "") but the CtTypeReference
129      * of the superclass (Thread in the example) or of the superinterface.
130      */

131     static CtTypeReference getType( CtNewClass nc ) {
132         
133         CtClass c = nc.getAnonymousClass();
134         if( c == null ) {
135             // Not a anonymous class
136
return nc.getType();
137         }
138         
139         CtTypeReference ctr = c.getSuperclass();
140         if( ctr != null ) {
141             return ctr;
142         }
143         
144         // No superclass, return the superinterface (only one superinterface)
145
Set JavaDoc<CtTypeReference> sups = c.getSuperinterfaces();
146         ctr = sups.iterator().next();
147         return ctr;
148     }
149
150 }
151
Popular Tags