1 24 25 package org.aspectj.compiler.crosscuts.joinpoints; 26 27 import org.aspectj.compiler.base.ast.*; 28 import org.aspectj.compiler.crosscuts.ast.*; 29 import org.aspectj.util.JavaStrings; 30 31 import org.aspectj.compiler.base.JavaCompiler; 32 33 import java.util.*; 34 35 36 public class InitializationJp extends CodeDecJp { 37 public InitializationJp(ConstructorDec constructorDec) { 38 super(constructorDec); 39 constructorDec.getBytecodeTypeDec().getInitializerExecutionJoinPoints().add(this); 40 } 41 42 public static final Kind KIND = new Kind("initialization", INITIALIZER_EXECUTION); 43 44 public Kind getKind() { return KIND; } 45 46 public TypeDec getEnclosingTypeDec() { return getCodeDec().getBytecodeTypeDec(); } 48 49 public ASTObject getSourceLocation() { return getEnclosingTypeDec().getBody(); } 50 51 public void setStmts(Stmts stmts) { 52 makeInnerAndOuterConstructorDecs(); 53 innerConstructorDec.getBody().setStmts(stmts); 54 } 55 56 public Stmts getStmts() { 57 makeInnerAndOuterConstructorDecs(); 58 return innerConstructorDec.getBody().getStmts(); 59 } 60 61 public boolean needToImplement() { 62 if (!super.needToImplement()) return false; 63 64 return checkNoLocalTypes(); 65 } 66 67 private boolean checkNoLocalTypes() { 68 LocalFinderWalker w = new LocalFinderWalker(getCompiler()); 69 w.process(getStmts()); 70 return !w.foundLocal; 71 } 72 73 private class LocalFinderWalker extends Walker { 74 public boolean foundLocal = false; 75 76 public LocalFinderWalker(JavaCompiler c) { super(c); } 77 78 public boolean preProcess(ASTObject o) { 79 if (foundLocal) return false; 80 81 if (o instanceof TypeDec) { 82 showError(o, "can't handle local classes in initializers with " + 83 "initialization join points (compiler limitation)"); 84 foundLocal = true; 85 return false; 86 } 87 return true; 88 } 89 } 90 91 92 private ConstructorDec innerConstructorDec = null; 93 private ConstructorDec outerConstructorDec = null; 94 95 public void inlineBodies() { 96 ConstructorDec origConstructorDec = (ConstructorDec)getCodeDec(); 97 outerConstructorDec = makeInitializer(origConstructorDec); 98 } 99 100 101 public void finishInline() { 102 ConstructorDec origConstructorDec = (ConstructorDec)getCodeDec(); 103 ConstructorDec topDec = outerConstructorDec; 104 105 origConstructorDec.setBody(topDec.getBody()); 106 if (instanceInitializer != null && instanceInitializer.getBody().getStmts().size() > 0) { 107 Stmt initializerStmt = 108 getAST().makeBlock(instanceInitializer.getBody().getStmts().copy()); 109 innerConstructorDec.getBody().getStmts().add(0, initializerStmt); 110 } 111 112 Formals oldFormals = origConstructorDec.getFormals(); 115 origConstructorDec.setFormals(topDec.getFormals()); 116 MovingWalker mover = new MovingWalker(getCompiler()); 117 for (int i = 0; i<oldFormals.size(); i++) { 118 FormalDec oldFormal = oldFormals.get(i); 119 FormalDec newFormal = innerConstructorDec.getFormals().get(i); 120 mover.addMapping(newFormal, oldFormal); 121 newFormal.replaceWith(oldFormal); 122 } 123 mover.process(innerConstructorDec.getBody()); 124 } 125 126 private InitializerDec instanceInitializer; 127 public void makeInnerAndOuterConstructorDecs() { 128 130 if (outerConstructorDec != null) return; 131 132 instanceInitializer = getEnclosingTypeDec().getSingleInitializerDec(false); 133 134 for (Iterator i = getEnclosingTypeDec().getInitializerExecutionJoinPoints().iterator(); i.hasNext(); ) { 135 InitializationJp point = (InitializationJp)i.next(); 136 point.instanceInitializer = instanceInitializer; 137 point.inlineBodies(); 138 } 139 140 for (Iterator i = getEnclosingTypeDec().getInitializerExecutionJoinPoints().iterator(); i.hasNext(); ) { 141 InitializationJp point = (InitializationJp)i.next(); 142 point.finishInline(); 143 } 144 145 getEnclosingTypeDec().getBody().remove(instanceInitializer); 146 147 } 149 150 151 164 ConstructorDec makeInitializer(ConstructorDec dec) { 165 CopyWalker cw = new CopyWalker(getCompiler()); 168 ConstructorDec ret = 169 new ConstructorDec(dec.getSourceLocation(), 170 (Modifiers)cw.cp(dec.getModifiers()), 171 (Formals)cw.cp(dec.getFormals()), 172 (TypeDs)cw.cp(dec.getThrows()), 173 (CodeBody)cw.cp(dec.getBody())); 174 175 ConstructorBody body = (ConstructorBody)ret.getBody(); 176 ConstructorCallExpr thisCallExpr = body.getConstructorCall(); 177 178 180 if (thisCallExpr.getIsSuper()) { 181 body.setStmts(body.getStmts().removeReturns()); 182 innerConstructorDec = ret; 183 return ret; 184 } 185 186 ConstructorDec innerDec = 187 makeInitializer(thisCallExpr.getConstructor().getConstructorDec()); 188 189 Formals oldFormals = ret.getFormals(); 190 CopyWalker copier = new CopyWalker(getCompiler()); 191 Formals newFormals = (Formals)copier.process(oldFormals); 192 thisCallExpr = (ConstructorCallExpr)copier.process(thisCallExpr); 193 thisCallExpr.getArgs().addAll(0, newFormals.makeExprs()); 194 thisCallExpr.setConstructor(innerDec.getConstructor()); 195 body.setConstructorCall(thisCallExpr); 196 ret.setFormals(newFormals); 197 Stmts stmts = body.getStmts(); 198 body.setStmts(getAST().makeStmts()); 199 inlineStmts(stmts, innerDec.getBody().getStmts()); 200 innerDec.getFormals().addAll(0, oldFormals); 201 202 addUniquelyToBody(dec.getBytecodeTypeDec().getBody(), innerDec, thisCallExpr); 203 204 return ret; 205 } 206 207 void inlineStmts(Stmts addStmts, Stmts baseStmts) { 208 baseStmts.addAll(addStmts.removeReturns()); 209 } 210 211 void addUniquelyToBody(Decs body, ConstructorDec dec, ConstructorCallExpr thisCallExpr) { 212 final AST ast = getAST(); 213 214 body.add(dec); 215 FormalDec cookieFormal = null; 216 while (true) { 217 int i = 0; 218 for (; i < body.size(); i++) { 219 Dec idec = body.get(i); 220 if (! (idec instanceof ConstructorDec) || idec == dec) continue; 221 222 ConstructorDec constructorDec = (ConstructorDec)idec; 223 if (constructorDec.getFormals().matches(dec.getFormals())) break; 224 } 225 if (i >= body.size()) break; 226 227 if (cookieFormal == null) { 228 cookieFormal = 229 ast.makeFormal(getTypeManager().shortType.getArrayType(), "_ajcookie"); 230 dec.getFormals().add(cookieFormal); 231 } else { 232 cookieFormal.setTypeD(cookieFormal.getType().getArrayType().makeTypeD()); 233 } 234 } 235 236 if (cookieFormal != null) { 237 thisCallExpr.getArgs().add(ast.forceCast(cookieFormal.getType(), ast.makeNull())); 238 } 239 } 240 } 241 | Popular Tags |