1 24 25 package org.aspectj.compiler.base.ast; 26 27 import org.aspectj.compiler.base.*; 28 import java.util.*; 29 30 import org.aspectj.compiler.base.JavaCompiler; 31 import org.aspectj.compiler.base.CodeWriter; 32 33 import org.aspectj.compiler.base.bcg.CodeBuilder; 34 import org.aspectj.compiler.base.bcg.Label; 35 36 import java.util.Iterator ; 37 38 43 public class TryCatchStmt extends TryStmt { 44 45 public void checkSpec() { 46 super.checkSpec(); 47 if (catches.size() == 0) { 48 showError("'try' without 'catch' or 'finally'"); 49 } 50 51 body.requireBlockStmt(); 52 } 53 54 public void unparse(CodeWriter writer) { 55 if (catches.size() == 0) { 56 writer.write(body); 57 return; 58 } 59 60 writer.writeKeyword("try"); 61 writer.optionalSpace(); 62 writer.write(body); 63 64 writer.writeChildren(catches); 65 } 66 67 public ASTObject postFixAST(final ASTFixerPass fixer) { 70 if (! isOptional()) return super.postFixAST(fixer); 71 72 Set exceptions = ExceptionFinder.getPossibleExceptions(getBody(), true); 74 75 78 exceptions.add(getTypeManager().getRuntimeExceptionType()); 79 exceptions.add(getTypeManager().getErrorType()); 80 82 filterCatchClauses(catches, exceptions); 83 setIsOptional(false); 84 return super.postFixAST(fixer); 85 } 86 private void filterCatchClauses(CatchClauses ccs, Set exceptions) { 87 for (int i = 0; i < ccs.size(); i++) { 89 CatchClause cc = ccs.get(i); 90 if (!possibleCatchClause(cc, exceptions)) { 92 ccs.remove(i); 94 i--; 95 } 96 } 97 } 98 private boolean possibleCatchClause(CatchClause cc, Set exceptions) { 99 return canThrow(exceptions, cc.getFormal().getType()); 100 } 101 private boolean canThrow(Set types, Type baseType) { 103 107 for(Iterator iter = types.iterator(); iter.hasNext(); ) { 108 Type checkType = (Type)iter.next(); 109 if (checkType != null && (checkType.isSubtypeOf(baseType) || 110 baseType.isSubtypeOf(checkType))) { 111 return true; 112 } 113 } 114 return false; 115 } 116 117 120 public void walkFlow(FlowCheckerPass w) { 121 FlowCheckerPass.Vars beforeV = w.getVars(); 122 FlowCheckerPass.ESet beforeExns = w.popExns(); 123 w.enterContext(this); 124 w.process(getBody()); 125 w.leaveContext(); 126 boolean bodyLive = w.isLive(); 127 FlowCheckerPass.ESet bodyExns = w.popExns(); 128 129 FlowCheckerPass.Vars v = w.getVars(); FlowCheckerPass.Vars tv = w.getTryVars(this); 132 FlowCheckerPass.Vars cv = 133 FlowCheckerPass.Vars.makeSets(beforeV.getDa(), 134 v.getDua().inter(tv.getDua())); 135 136 FlowCheckerPass.ESet caughtExns = FlowCheckerPass.ESet.getEmpty(); 137 FlowCheckerPass.ESet thrownExns = beforeExns; 138 FlowCheckerPass.Vars cvExit = v; 139 boolean liveSoFar = bodyLive; 140 CatchClauses c = getCatches(); 141 if (c != null) { 142 for (int i = 0, len = c.size(); i < len; i++) { 143 CatchClause cl = c.get(i); 144 NameType exnType = (NameType) cl.getFormal().getType(); 145 if (! bodyExns.containsSuperOrSub(exnType) && 146 ! exnType.isUncheckedThrowable() && 147 exnType != getTypeManager().getExceptionType() && 148 exnType != getTypeManager().getThrowableType()) { 149 cl.showError("exception " + exnType.getId() + 150 " is never thrown in body of corresponding try statement"); 151 continue; 152 } 153 if (caughtExns.containsSuper(exnType)) { 154 cl.showError("exception " + exnType.getId() + " has already been caught"); 155 continue; 156 } 157 w.setLive(true); 158 w.setVars(cv); 159 w.enterContext(this); 166 w.process(cl); 167 w.leaveContext(); 168 liveSoFar = liveSoFar | w.isLive(); 169 cvExit = cvExit.join(w.getVars()); 170 thrownExns = thrownExns.union(w.popExns()); 171 caughtExns = caughtExns.add(exnType); 172 } 173 } 174 w.setExns(bodyExns.diff(caughtExns).union(thrownExns).union(beforeExns)); 175 w.setVars(cvExit); 176 w.releasePendingTransfers(this); 177 w.setLive(liveSoFar); 178 } 179 180 183 public void walkCleanup(ByteCodeCleanupPass w) { 184 w.enterContext(this); 185 setBody((Stmt) w.process(getBody())); 186 w.leaveContext(); 187 boolean bodyLive = w.isLive(); 188 189 boolean liveSoFar = bodyLive; 190 CatchClauses c = getCatches(); 191 for (int i = 0, len = c.size(); i < len; i++) { 192 CatchClause cl = c.get(i); 193 w.setLive(true); 194 w.process(cl); 195 liveSoFar = liveSoFar || w.isLive(); 196 } 197 w.setLive(liveSoFar); 198 } 199 200 public ASTObject postCleanup(ByteCodeCleanupPass walker) { 201 if (getBody() instanceof EmptyStmt) { 202 return getAST().makeEmptyStmt().setSource(this); 203 } else { 204 return this; 205 } 206 } 207 208 211 protected void cgStmt(CodeBuilder cb) { 212 Label startBody = cb.genAnchor(); 213 Label endBody = cb.genAnchor(); 214 Label end = cb.genLabel(); 215 cb.emitLabel(startBody); 216 getBody().cgTop(cb); 217 cb.emitLabel(endBody); 218 if (body.completesNormally()) cb.emitJump(end); 219 for (int i = 0, len = catches.size(); i < len; i++ ) { 220 CatchClause clause = catches.get(i); 221 Label exnStart = cb.genAnchor(); 222 FormalDec clauseFormal = clause.getFormal(); 223 Stmt clauseBody = clause.getBody(); 224 225 cb.enterBlock(); 226 cb.enterVar(clauseFormal); 227 cb.emitLabel(exnStart); 228 cb.pushStack(1); cb.emitASTORE(clauseFormal.getFrameLoc()); clauseBody.cgTop(cb); 231 if (clauseBody.completesNormally()) cb.emitJump(end); 232 cb.addHandler(startBody, endBody, exnStart, (NameType) clauseFormal.getType()); 233 cb.exitBlock(); 234 } 235 cb.emitLabel(end); 236 } 237 238 protected Stmt body; 240 public Stmt getBody() { return body; } 241 public void setBody(Stmt _body) { 242 if (_body != null) _body.setParent(this); 243 body = _body; 244 } 245 246 protected CatchClauses catches; 247 public CatchClauses getCatches() { return catches; } 248 public void setCatches(CatchClauses _catches) { 249 if (_catches != null) _catches.setParent(this); 250 catches = _catches; 251 } 252 253 public TryCatchStmt(SourceLocation location, Stmt _body, CatchClauses _catches) { 254 super(location); 255 setBody(_body); 256 setCatches(_catches); 257 } 258 protected TryCatchStmt(SourceLocation source) { 259 super(source); 260 } 261 262 public ASTObject copyWalk(CopyWalker walker) { 263 TryCatchStmt ret = new TryCatchStmt(getSourceLocation()); 264 ret.preCopy(walker, this); 265 if (body != null) ret.setBody( (Stmt)walker.process(body) ); 266 if (catches != null) ret.setCatches( (CatchClauses)walker.process(catches) ); 267 return ret; 268 } 269 270 public ASTObject getChildAt(int childIndex) { 271 switch(childIndex) { 272 case 0: return body; 273 case 1: return catches; 274 default: return super.getChildAt(childIndex); 275 } 276 } 277 public String getChildNameAt(int childIndex) { 278 switch(childIndex) { 279 case 0: return "body"; 280 case 1: return "catches"; 281 default: return super.getChildNameAt(childIndex); 282 } 283 } 284 public void setChildAt(int childIndex, ASTObject child) { 285 switch(childIndex) { 286 case 0: setBody((Stmt)child); return; 287 case 1: setCatches((CatchClauses)child); return; 288 default: super.setChildAt(childIndex, child); return; 289 } 290 } 291 public int getChildCount() { 292 return 2; 293 } 294 295 public String getDefaultDisplayName() { 296 return "TryCatchStmt()"; 297 } 298 299 } 301 302 303 | Popular Tags |