1 package spoon.jdiet; 2 3 import java.util.ArrayList ; 4 import java.util.Arrays ; 5 import java.util.Collection ; 6 import java.util.Hashtable ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 import java.util.Map ; 10 import java.util.Set ; 11 import java.util.Vector ; 12 13 import spoon.jdiet.rt.Helper; 14 import spoon.processing.AbstractProcessor; 15 import spoon.processing.TraversalStrategy; 16 import spoon.reflect.code.CtExpression; 17 import spoon.reflect.code.CtInvocation; 18 import spoon.reflect.code.CtNewClass; 19 import spoon.reflect.declaration.CtElement; 20 import spoon.reflect.factory.CodeFactory; 21 import spoon.reflect.factory.ExecutableFactory; 22 import spoon.reflect.factory.TypeFactory; 23 import spoon.reflect.reference.CtExecutableReference; 24 import spoon.reflect.reference.CtTypeReference; 25 26 32 public class InvocationProcessor extends AbstractProcessor<CtInvocation> { 33 34 public TraversalStrategy getTraversalStrategy() { 35 return TraversalStrategy.POST_ORDER; 37 } 38 39 private List <Transformer<CtInvocation>> mits = 40 new ArrayList <Transformer<CtInvocation>>(); 41 42 public InvocationProcessor() { 43 44 Class objarraycl = new Object [0].getClass(); 45 46 49 mits.add( new HelperClassCtInvTransformer(Arrays .class,"asList",Vector .class,"asList",new Object [0].getClass()) ); 50 mits.add( new HelperClassCtInvTransformer(Collection .class,"toArray",objarraycl,"toArray",Vector .class,new Object [0].getClass()) ); 51 mits.add( new HelperClassCtInvTransformer(List .class,"add",Boolean .class,"addList",Vector .class,Object .class) ); 52 mits.add( new HelperClassCtInvTransformer(List .class,"addAll",Boolean .class,"addAllList",Vector .class,Vector .class) ); 53 mits.add( new HelperClassCtInvTransformer(Map .class,"values",Vector .class,"values",Hashtable .class) ); 54 mits.add( new HelperClassCtInvTransformer(Map .class,"entrySet",Vector .class,"entrySet",Hashtable .class) ); 55 mits.add( new HelperClassCtInvTransformer(Map .class,"keySet",Vector .class,"keySet",Hashtable .class) ); 56 mits.add( new HelperClassCtInvTransformer(Set .class,"add",Boolean .class,"addSet",Vector .class,Object .class) ); 57 mits.add( new HelperClassCtInvTransformer(Set .class,"addAll",Boolean .class,"addAllSet",Vector .class,Vector .class) ); 58 59 62 mits.add( new SimpleCtInvTransformer(Collection .class,"iterator","elements") ); 63 mits.add( new SimpleCtInvTransformer(Collection .class,"remove","removeElement") ); 64 mits.add( new SimpleCtInvTransformer(Iterator .class,"hasNext","hasMoreElements") ); 65 mits.add( new SimpleCtInvTransformer(Iterator .class,"next","nextElement") ); 66 mits.add( new SimpleCtInvTransformer(List .class,"get","elementAt") ); 67 } 68 69 public void process(CtInvocation inv) { 70 for (Transformer<CtInvocation> t : mits) { 72 if( t.match(inv) ) { 73 t.transform(inv); 74 } 75 } 76 } 77 } 78 79 80 interface Transformer<T extends CtElement> { 81 boolean match( T element ); 82 void transform( T element ); 83 } 84 85 92 abstract class AbstractCtInvTransformer implements Transformer<CtInvocation> { 93 94 private Class srcType; 95 private String methName; 96 97 protected Class replMethType; 98 protected String replMethName; 99 protected Class [] replMethParameterTypes; 100 101 public AbstractCtInvTransformer( 102 Class srcType, String methName, 103 Class replMethType, String replMethName, 104 Class ... replMethParameterTypes ) { 105 106 this.srcType = srcType; 107 this.methName = methName; 108 this.replMethType = replMethType; 109 this.replMethName = replMethName; 110 this.replMethParameterTypes = replMethParameterTypes; 111 } 112 113 public boolean match( CtInvocation inv ) { 114 115 TypeFactory tf = inv.getFactory().Type(); 116 CtTypeReference srcTypeRef = tf.createReference(srcType); 117 CtTypeReference invokedType = getTargetType(inv); 118 119 if( invokedType.getQualifiedName().length() == 0 ) { 120 getTargetType(inv); 121 } 122 123 if( invokedType.isSubtypeOf(srcTypeRef) ) { 124 CtExecutableReference cer = inv.getExecutable(); 125 String invokedMethodName = cer.getSimpleName(); 126 return invokedMethodName.equals(methName); 127 } 128 129 return false; 130 } 131 132 abstract public void transform( CtInvocation inv ); 133 134 protected CtTypeReference getTargetType( CtInvocation inv ) { 135 CtExpression target = inv.getTarget(); 136 if( target == null ) { 137 CtTypeReference ctr = inv.getExecutable().getDeclaringType(); 139 return ctr; 140 } 141 else { 142 if( target instanceof CtNewClass ) { 143 CtNewClass nc = (CtNewClass) target; 146 CtTypeReference ctr = NewClassProcessor.getType(nc); 147 return ctr; 148 } 149 else { 150 CtTypeReference ctr = target.getType(); 152 return ctr; 153 } 154 } 155 } 156 } 157 158 164 class SimpleCtInvTransformer extends AbstractCtInvTransformer { 165 166 public SimpleCtInvTransformer( 167 Class targetType, String methName, String replMethName ) { 168 169 super( targetType, methName, null, replMethName, (Class []) null ); 170 } 171 172 public void transform( CtInvocation inv ) { 173 CtExecutableReference cer = inv.getExecutable(); 174 cer.setSimpleName(replMethName); 175 } 176 } 177 178 185 class HelperClassCtInvTransformer extends AbstractCtInvTransformer { 186 187 public HelperClassCtInvTransformer( 188 Class targetType, String methName, 189 Class replMethType, String replMethName, 190 Class ... replMethParameterTypes ) { 191 192 super( 193 targetType, methName, 194 replMethType, replMethName, replMethParameterTypes ); 195 } 196 197 public void transform( CtInvocation inv ) { 198 199 CodeFactory cf = inv.getFactory().Code(); 200 ExecutableFactory ef = inv.getFactory().Executable(); 201 TypeFactory tf = inv.getFactory().Type(); 202 203 CtTypeReference[] trs = new CtTypeReference[replMethParameterTypes.length]; 205 for (int i = 0; i < replMethParameterTypes.length; i++) { 206 trs[i] = tf.createReference(replMethParameterTypes[i]); 207 } 208 209 CtExecutableReference replmeth = 211 ef.createReference( 212 tf.createReference(Helper.class),true,replMethName,trs ); 213 replmeth.setType( tf.createReference(replMethType) ); 214 215 List <CtExpression<?>> l = inv.getArguments(); 217 CtExpression target = inv.getTarget(); 218 if( target != null ) { 219 l.add(0,target); 222 } 223 224 CtInvocation repl = cf.createInvocation( null, replmeth, l ); 226 repl.setType( tf.createReference(replMethType) ); 227 repl.setTypeCasts(inv.getTypeCasts()); 228 229 inv.replace(repl); 231 } 232 } 233 | Popular Tags |