1 24 25 package org.aspectj.compiler.crosscuts.ast; 26 27 import org.aspectj.compiler.base.ast.*; 28 import org.aspectj.compiler.crosscuts.joinpoints.*; 29 import org.aspectj.compiler.base.*; 30 31 import java.util.*; 32 33 37 38 public class AfterThrowingAdviceDec extends AdviceDec { 39 protected String getAdviceKind() { return "afterThrowing"; } 40 41 protected boolean isAfterAdvice() { return true; } 42 43 protected Stmts wrapStmts(Stmts stmts, AdvicePlan plan) { 44 return wrapAfterThrowingCall(plan, stmts); 45 } 46 47 Stmt makeSingleRethrow(VarDec formal, Type excType, boolean needTest) { 48 final AST ast = getAST(); 49 50 Expr castExpr = ast.makeCast(excType, ast.makeVar(formal)); 51 52 Stmt rethrow = ast.makeThrow(castExpr); 53 if (needTest) { 54 return ast.makeIf(ast.makeInstanceof(ast.makeVar(formal), excType), rethrow); 55 } else { 56 return rethrow; 57 } 58 } 59 60 Stmts makeRethrows(VarDec formal, Set exceptions) { 61 Stmts stmts = getAST().makeStmts(); 62 63 exceptions = Type.filterSubTypes(formal.getType(), exceptions); 64 exceptions = Type.filterTopTypes(exceptions); 65 66 if (exceptions.size() == 1) { 67 Type checkType = (Type)exceptions.iterator().next(); 68 stmts.add(makeSingleRethrow(formal, checkType, false)); 69 return stmts; 70 } 71 72 for(Iterator iter = exceptions.iterator(); iter.hasNext(); ) { 73 Type checkType = (Type)iter.next(); 74 stmts.add(makeSingleRethrow(formal, checkType, iter.hasNext())); 75 } 76 return stmts; 77 } 78 79 private static int excIndex = 0; 80 private CatchClause makeCatchClause(Type catchType, AdvicePlan plan, int index, Set exceptions) { 81 final AST ast = getAST(); 82 83 String newName = "ajcexc$" + excIndex++; 84 FormalDec newFormal = ast.makeFormal(catchType, newName); 85 Stmt doCall = plan.makeCall(ast.makeVar(newFormal)); 86 87 Stmts rethrows = makeRethrows(newFormal, exceptions); 88 89 rethrows.add(0, doCall); 90 return ast.makeCatch(newFormal, ast.makeBlock(rethrows)); 91 } 92 93 boolean isUncheckedException(Type baseType) { 94 return baseType.isSubtypeOf(getTypeManager().getRuntimeExceptionType()) 95 || baseType.isSubtypeOf(getTypeManager().getErrorType()); 96 } 97 98 99 boolean canThrow(Set types, Type baseType) { 100 104 for(Iterator iter = types.iterator(); iter.hasNext(); ) { 105 Type checkType = (Type)iter.next(); 106 if (checkType != null && checkType.isSubtypeOf(baseType) || 107 baseType.isSubtypeOf(checkType)) { 108 return true; 109 } 110 } 111 return false; 112 } 113 114 public Stmts wrapAfterThrowingCall(AdvicePlan plan, Stmts baseStmts) { 115 FormalDec formal = ((AfterThrowingAdviceDec)plan.getAdviceDec()).getExtraFormal(); 116 117 Set exceptions = ExceptionFinder.getPossibleExceptions(baseStmts, true); 118 exceptions.add(getTypeManager().getRuntimeExceptionType()); 119 exceptions.add(getTypeManager().getErrorType()); 120 122 Type catchType; 123 if (formal != null) { 124 catchType = formal.getType(); 125 } else { 126 catchType = getTypeManager().getThrowableType(); 127 } 128 129 if (!canThrow(exceptions, catchType)) { 130 return baseStmts; 132 } 133 134 int index = 0; CatchClause catches = makeCatchClause(catchType, plan, index, exceptions); 136 137 final AST ast = getAST(); 138 return ast.makeStmts(ast.makeTryCatch(ast.makeBlock(baseStmts), catches)); 139 } 140 141 144 protected void setupFlowWalker(FlowCheckerPass w) { 145 if (getExtraFormal() != null) 146 w.setVars(w.getVars().addAssigned(getExtraFormal())); 147 super.setupFlowWalker(w); 148 } 149 150 protected FormalDec extraFormal; 152 public FormalDec getExtraFormal() { return extraFormal; } 153 public void setExtraFormal(FormalDec _extraFormal) { 154 if (_extraFormal != null) _extraFormal.setParent(this); 155 extraFormal = _extraFormal; 156 } 157 158 public AfterThrowingAdviceDec(SourceLocation location, Modifiers _modifiers, Formals _formals, FormalDec _extraFormal, TypeDs __throws, Pcd _pcd, CodeBody _body) { 159 super(location, _modifiers, _formals, __throws, _pcd, _body); 160 setExtraFormal(_extraFormal); 161 } 162 protected AfterThrowingAdviceDec(SourceLocation source) { 163 super(source); 164 } 165 166 public ASTObject copyWalk(CopyWalker walker) { 167 AfterThrowingAdviceDec ret = new AfterThrowingAdviceDec(getSourceLocation()); 168 ret.preCopy(walker, this); 169 if (modifiers != null) ret.setModifiers( (Modifiers)walker.process(modifiers) ); 170 if (formals != null) ret.setFormals( (Formals)walker.process(formals) ); 171 if (extraFormal != null) ret.setExtraFormal( (FormalDec)walker.process(extraFormal) ); 172 if (_throws != null) ret.setThrows( (TypeDs)walker.process(_throws) ); 173 if (pcd != null) ret.setPcd( (Pcd)walker.process(pcd) ); 174 if (body != null) ret.setBody( (CodeBody)walker.process(body) ); 175 return ret; 176 } 177 178 public ASTObject getChildAt(int childIndex) { 179 switch(childIndex) { 180 case 0: return modifiers; 181 case 1: return formals; 182 case 2: return extraFormal; 183 case 3: return _throws; 184 case 4: return pcd; 185 case 5: return body; 186 default: return super.getChildAt(childIndex); 187 } 188 } 189 public String getChildNameAt(int childIndex) { 190 switch(childIndex) { 191 case 0: return "modifiers"; 192 case 1: return "formals"; 193 case 2: return "extraFormal"; 194 case 3: return "throws"; 195 case 4: return "pcd"; 196 case 5: return "body"; 197 default: return super.getChildNameAt(childIndex); 198 } 199 } 200 public void setChildAt(int childIndex, ASTObject child) { 201 switch(childIndex) { 202 case 0: setModifiers((Modifiers)child); return; 203 case 1: setFormals((Formals)child); return; 204 case 2: setExtraFormal((FormalDec)child); return; 205 case 3: setThrows((TypeDs)child); return; 206 case 4: setPcd((Pcd)child); return; 207 case 5: setBody((CodeBody)child); return; 208 default: super.setChildAt(childIndex, child); return; 209 } 210 } 211 public int getChildCount() { 212 return 6; 213 } 214 215 public String getDefaultDisplayName() { 216 return "AfterThrowingAdviceDec()"; 217 } 218 219 } 221 | Popular Tags |