/** * The ast nodes will use this callback to notify us that they throw an exception of type t. This * method will throw a SemanticException if the type t is not allowed to be thrown at this point; * the exception t will be added to the throwsSet of all exception checkers in the stack, up to * (and not including) the exception checker that catches the exception. * * @param t The type of exception that the node throws. * @throws SemanticException */ public void throwsException(Type t, Position pos) throws SemanticException { if (!t.isUncheckedException()) { // go through the stack of catches and see if the exception // is caught. boolean exceptionCaught = false; ExceptionChecker ec = this; while (!exceptionCaught && ec != null) { if (ec.catchable != null) { for (Iterator<Type> iter = ec.catchable.iterator(); iter.hasNext(); ) { Type catchType = (Type) iter.next(); if (ts.isSubtype(t, catchType, ts.emptyContext())) { exceptionCaught = true; break; } } } if (!exceptionCaught && ec.throwsSet != null) { // add t to ec's throwsSet. ec.throwsSet.add(t); } if (ec.catchAllThrowable) { // stop the propagation exceptionCaught = true; } ec = ec.pop(); } if (!exceptionCaught) { reportUncaughtException(t, pos); } } }
public ExceptionChecker push() { throwsSet(); // force an instantiation of the throwsset. ExceptionChecker ec = (ExceptionChecker) this.shallowCopy(); ec.outer = this; ec.catchable = null; ec.catchAllThrowable = false; return ec; }
/** * Here, we pop the stack frame that we pushed in enter and agregate the exceptions. * * @param old The original state of root of the current subtree. * @param n The current state of the root of the current subtree. * @param v The <code>NodeVisitor</code> object used to visit the children. * @return The final result of the traversal of the tree rooted at <code>n</code>. */ protected Node leaveCall(Node old, Node n, NodeVisitor v) throws SemanticException { ExceptionChecker inner = (ExceptionChecker) v; if (inner.outer != this) throw new InternalCompilerError("oops!"); // gather exceptions from this node. n = n.del().exceptionCheck(inner); // Merge results from the children and free the checker used for the // children. SubtypeSet t = inner.throwsSet(); throwsSet().addAll(t); exceptionPositions.putAll(inner.exceptionPositions); return n; }
public ExceptionChecker push() { ExceptionChecker ec = (ExceptionChecker) this.visitChildren(); ec.outer = this; ec.exceptionPositions = new HashMap(); return ec; }
public ExceptionChecker pushCatchAllThrowable() { ExceptionChecker ec = this.push(); ec.throwsSet = new SubtypeSet(ts.CheckedThrowable()); ec.catchAllThrowable = true; return ec; }
public ExceptionChecker push(Collection<Type> catchableTypes) { ExceptionChecker ec = this.push(); ec.catchable = CollectionFactory.newHashSet(catchableTypes); ec.throwsSet = new SubtypeSet(ts.CheckedThrowable()); return ec; }
public ExceptionChecker push(Type catchableType) { ExceptionChecker ec = this.push(); ec.catchable = Collections.<Type>singleton(catchableType); ec.throwsSet = new SubtypeSet(ts.CheckedThrowable()); return ec; }
public ExceptionChecker push(UncaughtReporter reporter) { ExceptionChecker ec = this.push(); ec.reporter = reporter; ec.throwsSet = new SubtypeSet(ts.CheckedThrowable()); return ec; }