1 package polyglot.ext.jl.ast; 2 3 import polyglot.ast.*; 4 import polyglot.util.*; 5 import polyglot.types.*; 6 import polyglot.visit.*; 7 import java.util.*; 8 9 13 public class Try_c extends Stmt_c implements Try 14 { 15 protected Block tryBlock; 16 protected List catchBlocks; 17 protected Block finallyBlock; 18 19 public Try_c(Position pos, Block tryBlock, List catchBlocks, Block finallyBlock) { 20 super(pos); 21 this.tryBlock = tryBlock; 22 this.catchBlocks = TypedList.copyAndCheck(catchBlocks, Catch.class, true); 23 this.finallyBlock = finallyBlock; 24 } 25 26 27 public Block tryBlock() { 28 return this.tryBlock; 29 } 30 31 32 public Try tryBlock(Block tryBlock) { 33 Try_c n = (Try_c) copy(); 34 n.tryBlock = tryBlock; 35 return n; 36 } 37 38 39 public List catchBlocks() { 40 return Collections.unmodifiableList(this.catchBlocks); 41 } 42 43 44 public Try catchBlocks(List catchBlocks) { 45 Try_c n = (Try_c) copy(); 46 n.catchBlocks = TypedList.copyAndCheck(catchBlocks, Catch.class, true); 47 return n; 48 } 49 50 51 public Block finallyBlock() { 52 return this.finallyBlock; 53 } 54 55 56 public Try finallyBlock(Block finallyBlock) { 57 Try_c n = (Try_c) copy(); 58 n.finallyBlock = finallyBlock; 59 return n; 60 } 61 62 63 protected Try_c reconstruct(Block tryBlock, List catchBlocks, Block finallyBlock) { 64 if (tryBlock != this.tryBlock || ! CollectionUtil.equals(catchBlocks, this.catchBlocks) || finallyBlock != this.finallyBlock) { 65 Try_c n = (Try_c) copy(); 66 n.tryBlock = tryBlock; 67 n.catchBlocks = TypedList.copyAndCheck(catchBlocks, Catch.class, true); 68 n.finallyBlock = finallyBlock; 69 return n; 70 } 71 72 return this; 73 } 74 75 76 public Node visitChildren(NodeVisitor v) { 77 Block tryBlock = (Block) visitChild(this.tryBlock, v); 78 List catchBlocks = visitList(this.catchBlocks, v); 79 Block finallyBlock = (Block) visitChild(this.finallyBlock, v); 80 return reconstruct(tryBlock, catchBlocks, finallyBlock); 81 } 82 83 88 public NodeVisitor exceptionCheckEnter(ExceptionChecker ec) 89 throws SemanticException 90 { 91 ec = (ExceptionChecker) super.exceptionCheckEnter(ec); 92 return ec.bypassChildren(this); 93 } 94 95 104 public Node exceptionCheck(ExceptionChecker ec) 105 throws SemanticException 106 { 107 TypeSystem ts = ec.typeSystem(); 108 109 ec = ec.push(); 111 Block tryBlock = (Block) visitChild(this.tryBlock, ec); 112 SubtypeSet thrown = ec.throwsSet(); 114 SubtypeSet caught = new SubtypeSet(ts.Throwable()); 115 ec = ec.pop(); 116 117 thrown.addAll(ts.uncheckedExceptions()); 119 120 for (Iterator i = this.catchBlocks.iterator(); i.hasNext(); ) { 123 Catch cb = (Catch) i.next(); 124 Type catchType = cb.catchType(); 125 126 129 boolean match = false; 130 for (Iterator j = thrown.iterator(); j.hasNext(); ) { 131 Type ex = (Type) j.next(); 132 133 if (ts.isSubtype(ex, catchType) || 134 ts.isSubtype(catchType, ex)) { 135 match = true; 136 break; 137 } 138 } 139 140 if (! match) { 141 throw new SemanticException("The exception \"" + 142 catchType + "\" is not thrown in the try block.", 143 cb.position()); 144 } 145 146 if (caught.contains(catchType)) { 148 throw new SemanticException("The exception \"" + 149 catchType + "\" has been caught by an earlier catch block.", 150 cb.position()); 151 } 152 153 caught.add(catchType); 154 } 155 156 thrown.removeAll(caught); 158 159 163 List catchBlocks = new ArrayList(this.catchBlocks.size()); 164 165 for (Iterator i = this.catchBlocks.iterator(); i.hasNext(); ) { 166 Catch cb = (Catch) i.next(); 167 168 ec = ec.push(); 169 170 cb = (Catch) visitChild(cb, ec); 171 catchBlocks.add(cb); 172 173 thrown.addAll(ec.throwsSet()); 174 ec = ec.pop(); 175 } 176 177 Block finallyBlock = null; 178 179 if (this.finallyBlock != null) { 180 ec = ec.push(); 181 182 finallyBlock = (Block) visitChild(this.finallyBlock, ec); 183 184 if (!this.finallyBlock.reachable()) { 193 194 197 if (false) { 198 ec.errorQueue().enqueue(ErrorInfo.WARNING, 200 "The finally block cannot complete normally", 201 finallyBlock.position()); 202 } 203 204 thrown.clear(); 205 } 206 thrown.addAll(ec.throwsSet()); 207 208 ec = ec.pop(); 209 } 210 211 ec.throwsSet().addAll(thrown); 215 216 return reconstruct(tryBlock, catchBlocks, finallyBlock).exceptions(ec.throwsSet()); 217 } 218 219 public String toString() { 220 StringBuffer sb = new StringBuffer (); 221 sb.append("try "); 222 sb.append(tryBlock.toString()); 223 224 int count = 0; 225 226 for (Iterator it = catchBlocks.iterator(); it.hasNext(); ) { 227 Catch cb = (Catch) it.next(); 228 229 if (count++ > 2) { 230 sb.append("..."); 231 break; 232 } 233 234 sb.append(" "); 235 sb.append(cb.toString()); 236 } 237 238 if (finallyBlock != null) { 239 sb.append(" finally "); 240 sb.append(finallyBlock.toString()); 241 } 242 243 return sb.toString(); 244 } 245 246 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 247 w.write("try"); 248 printSubStmt(tryBlock, w, tr); 249 250 for (Iterator it = catchBlocks.iterator(); it.hasNext(); ) { 251 Catch cb = (Catch) it.next(); 252 w.newline(0); 253 printBlock(cb, w, tr); 254 } 255 256 if (finallyBlock != null) { 257 w.newline(0); 258 w.write ("finally"); 259 printSubStmt(finallyBlock, w, tr); 260 } 261 } 262 263 public Term entry() { 264 return tryBlock.entry(); 265 } 266 267 public List acceptCFG(CFGBuilder v, List succs) { 268 TypeSystem ts = v.typeSystem(); 271 272 CFGBuilder v1 = v.push(this, false); 273 CFGBuilder v2 = v.push(this, true); 274 275 for (Iterator i = ts.uncheckedExceptions().iterator(); i.hasNext(); ) { 276 Type type = (Type) i.next(); 277 v1.visitThrow(tryBlock.entry(), type); 278 } 279 280 Term next; 281 282 if (finallyBlock == null) { 285 next = this; 286 } 287 else { 288 next = finallyBlock.entry(); 289 v.visitCFG(finallyBlock, this); 290 } 291 292 v1.visitCFG(tryBlock, next); 293 294 for (Iterator it = catchBlocks.iterator(); it.hasNext(); ) { 295 Catch cb = (Catch) it.next(); 296 v2.visitCFG(cb, next); 297 } 298 299 return succs; 300 } 301 } 302 | Popular Tags |