1 24 25 package org.aspectj.compiler.base; 26 27 import org.aspectj.compiler.base.ast.*; 28 29 30 import java.util.*; 31 32 33 public class CanThrowWalker extends Walker { 34 Stack canThrow = null; 35 36 public static void checkThrows(CodeDec codeDec) { 37 if (codeDec.isSoftThrowable()) return ; 38 39 CanThrowWalker walker = new CanThrowWalker(codeDec); 40 walker.canThrow.push(makeThrowableSet(codeDec.getThrows())); 41 42 if (codeDec instanceof InitializerDec && !codeDec.isStatic()) { 43 TypeDec inTypeDec = codeDec.getBytecodeTypeDec(); 44 if (inTypeDec.isAnonymous()) { 45 Set set = new HashSet(); 46 walker.collectBadThrows(set); 47 walker.process(codeDec); 48 inTypeDec.getSoleConstructorDec().addThrows(set); 50 } else { 51 Set set = null; 52 for (Iterator i = inTypeDec.getNameType().getConstructors().iterator(); i.hasNext(); ) { 53 Constructor c = (Constructor)i.next(); 54 if (set == null) { 55 set = makeThrowableSet(c.getThrows()); 56 } else { 57 set = Type.intersect(set, makeThrowableSet(c.getThrows())); 58 } 59 } 60 codeDec.addThrows(set); 62 walker.canThrow.push(makeThrowableSet(codeDec.getThrows())); 63 walker.process(codeDec); 64 } 65 } else { 66 walker.process(codeDec); 67 } 68 } 69 70 71 private Set badThrows = null; 72 73 private CanThrowWalker(CodeDec codeDec) { 74 super(codeDec.getCompiler()); 75 canThrow = new Stack(); 76 } 77 78 void collectBadThrows(Set set) { 79 badThrows = set; 80 } 81 82 83 static Set makeThrowableSet(TypeDs _throws) { 84 if (_throws == null) return Collections.EMPTY_SET; 85 86 Set ret = new HashSet(); 87 88 final int N = _throws.size(); 89 for(int i=0; i<N; i++) { 90 Type exceptionType = _throws.get(i).getType(); 91 ret.add(exceptionType); 92 } 93 return ret; 94 } 95 96 Collection makeThrowableSet(CatchClauses catchClauses) { 97 if (catchClauses == null) return Collections.EMPTY_SET; 98 99 Collection ret = new HashSet(); 100 101 final int N = catchClauses.size(); 102 for(int i=0; i<N; i++) { 103 Type exceptionType = catchClauses.get(i).getFormal().getType(); 104 ret.add(exceptionType); 105 } 106 return ret; 107 } 108 109 110 boolean checkLegalThrow(ASTObject where, Type throwType) { 111 if (throwType.isUncheckedThrowable()) return true; 112 113 for (Iterator i = canThrow.iterator(); i.hasNext(); ) { 114 if (Type.hasMatchingType((Collection)i.next(), throwType)) { 115 return true; 116 } 117 } 118 119 if (badThrows != null) { 120 badThrows.add(throwType); 121 return true; 122 } else { 123 where.showError("unreported exception " + throwType.getString() + 124 "; must be caught or declared to be thrown"); 125 return false; 126 } 127 } 128 129 130 void checkLegalThrows(ASTObject where, TypeDs throwTypeDs) { 131 if (throwTypeDs == null) return; 132 133 for (int i = 0; i < throwTypeDs.size(); i++) { 134 if (!checkLegalThrow(where, throwTypeDs.get(i).getType())) return; 135 } 136 } 137 138 public ASTObject process(ASTObject node) { 139 if (node instanceof TryCatchStmt) { 140 TryCatchStmt tryStmt = (TryCatchStmt)node; 141 canThrow.push(makeThrowableSet(tryStmt.getCatches())); 142 super.process(tryStmt.getBody()); 143 canThrow.pop(); 144 super.process(tryStmt.getCatches()); 145 return node; 146 } 147 148 if (node instanceof ThrowStmt) { 149 ThrowStmt throwStmt = (ThrowStmt)node; 150 checkLegalThrow(throwStmt, throwStmt.getExpr().getType()); 151 } else if (node instanceof CallExpr) { 152 CallExpr callExpr = (CallExpr)node; 153 if (callExpr.isSoftThrowable()) return super.process(node); 154 if (callExpr.getId().equals("aspectOf")) { 155 return super.process(node); 156 } 157 158 Method method = callExpr.getMethod(); 159 160 if (method == null) { 161 return super.process(node); 163 } 164 checkLegalThrows(callExpr, method.getThrows()); 165 } else if (node instanceof NewInstanceExpr) { 166 NewInstanceExpr newExpr = (NewInstanceExpr)node; 167 if (newExpr.isSoftThrowable()) return super.process(node); 168 169 Constructor init = newExpr.getConstructor(); 170 checkLegalThrows(newExpr, init.getThrows()); 171 } else if (node instanceof ConstructorCallExpr) { 172 ConstructorCallExpr newExpr = (ConstructorCallExpr)node; 173 175 Constructor init = newExpr.getConstructor(); 176 checkLegalThrows(newExpr, init.getThrows()); 177 178 } 179 if (node instanceof TypeDec) return node; 180 return super.process(node); 181 } 182 } 183 184 | Popular Tags |