1 6 7 package fr.emn.info.eaop.instrumentation; 8 9 import fr.emn.info.eaop.IO; 10 import fr.emn.info.eaop.recoderaux.AuxListKit; 11 12 import recoder.*; 13 import recoder.abstraction.*; 14 import recoder.bytecode.*; 15 import recoder.list.*; 16 import recoder.kit.*; 17 import recoder.java.*; 18 import recoder.java.declaration.*; 19 import recoder.java.reference.*; 20 21 22 32 public class WrapConstructors extends Instrumentation { 33 34 boolean superTransformed; 35 36 public WrapConstructors(CrossReferenceServiceConfiguration sc, 37 TypeDeclaration td, 38 boolean superTransformed) { 39 super(sc, null, td); 40 this.superTransformed = superTransformed; 41 } 42 43 48 public ProblemReport execute() { 49 SelectiveInstrumentation instrument = IO.getInstrumentationContext(); 50 boolean sthInstrumented = false; 51 52 if (instrument.checkClass(td)) { 53 ConstructorMutableList cl = 54 (ConstructorMutableList) td.getConstructors(); 55 56 for (int i = 0, s = cl.size(); i < s; i += 1) { 57 Constructor c = cl.getConstructor(i); 58 if (c instanceof DefaultConstructor) continue; 59 ConstructorDeclaration cd = (ConstructorDeclaration) c; 60 61 62 if (!instrument.checkMethodOrConstructor(cd)) continue; 63 else sthInstrumented = true; 64 65 attach(buildDelegatee(cd), td, td.getMembers().size()); 66 67 if (!td.replaceChild(cd, buildDelegator(cd))) { 68 IO.fail("[execute] Constructor replacement"); 69 }; 70 } 71 72 if (sthInstrumented) createDummyArgConstructor(); 73 } 74 75 return Transformation.NO_PROBLEM; 76 } 77 78 82 void createDummyArgConstructor() { 83 ConstructorDeclaration cd = null; 84 85 String cStr = td.getName() + "(" + constructorDummyTypeStr + " o) {\n" 86 + " super();\n}"; 87 try { 88 cd = (ConstructorDeclaration) pf.parseMemberDeclaration(cStr); 89 } catch (ParserException e) { 90 IO.fail("[createDummyConstructor] parsing of dummy constructor\n" 91 + e.toString()); 92 } 93 94 attach(cd, td, td.getMembers().size()); 95 } 96 97 103 ConstructorDeclaration buildDelegator(ConstructorDeclaration cd) { 104 ConstructorDeclaration newCd = (ConstructorDeclaration) cd.deepClone(); 105 106 Identifier id = new Identifier(cd.getName() + origStr); 107 ExpressionMutableList el = MethodKit.createArguments(cd); 108 109 Statement s = null; 110 if (superTransformed) { 111 Expression dummy = null; 112 113 try { 114 dummy = pf.parseExpression( 115 "(" + constructorDummyTypeStr + ") " + null); 116 } catch (ParserException e) { 117 IO.fail("[buildDelegator] Parsing of dummy expression \n" 118 + e.toString()); 119 } 120 121 s = new SuperConstructorReference(new ExpressionArrayList(dummy)); 122 } else { 123 s = new SuperConstructorReference(); 124 } 125 126 StatementArrayList sl = new StatementArrayList(s); 127 sl.add(new MethodReference(id, el)); 128 129 StatementBlock sb = new StatementBlock(sl); 130 131 if (!newCd.replaceChild(newCd.getBody(), sb)) { 132 IO.fail("[buildDelegator] Body replacement"); 133 }; 134 135 return newCd; 136 } 137 138 141 boolean isTransformed(ClassTypeList cl) { 142 ClassType ct = cl.getClassType(0); 143 144 if (cl.size() == 0 || 145 !((ct instanceof TypeDeclaration) || (ct instanceof ClassFile))) { 146 IO.fail("[isTransformed] Super class"); 147 } 148 return ct.getName() != "Object"; 149 } 150 151 156 MethodDeclaration buildDelegatee(ConstructorDeclaration cd) { 157 Statement newFirst = null; 158 boolean firstStatTransformed = false; 159 160 StatementBlock sb = cd.getBody(); 161 if (sb.getStatementCount() > 0) { 162 Statement s = sb.getStatementAt(0); 163 if (s instanceof ThisConstructorReference) { 164 newFirst = 165 new MethodReference( 166 new Identifier(cd.getName() + origStr), 167 ((ThisConstructorReference) s).getArguments()); 168 firstStatTransformed = true; 169 } 170 if (s instanceof SuperConstructorReference) { 171 newFirst = 172 new MethodReference( 173 new Identifier(td.getSupertypes().getClassType(0) 174 .getName() + origStr), 175 ((SuperConstructorReference) s).getArguments()); 176 firstStatTransformed = true; 177 } 178 if (firstStatTransformed) 179 if (!sb.replaceChild(s, newFirst)) { 180 IO.fail("[buildDelegatee] Replacement of first statement"); 181 }; 182 } 183 184 return new MethodDeclaration( 185 new ModifierArrayList(), 186 new TypeReference(new Identifier("void")), 187 new Identifier(cd.getIdentifier().getText() + origStr), 188 cd.getParameters(), 189 cd.getThrown(), 190 sb 191 ); 192 } 193 } 194 195 | Popular Tags |