示例#1
0
 /**
  * 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);
     }
   }
 }
示例#2
0
 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;
 }
示例#3
0
  /**
   * 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;
  }
示例#4
0
 public ExceptionChecker push() {
   ExceptionChecker ec = (ExceptionChecker) this.visitChildren();
   ec.outer = this;
   ec.exceptionPositions = new HashMap();
   return ec;
 }
示例#5
0
 public ExceptionChecker pushCatchAllThrowable() {
   ExceptionChecker ec = this.push();
   ec.throwsSet = new SubtypeSet(ts.CheckedThrowable());
   ec.catchAllThrowable = true;
   return ec;
 }
示例#6
0
 public ExceptionChecker push(Collection<Type> catchableTypes) {
   ExceptionChecker ec = this.push();
   ec.catchable = CollectionFactory.newHashSet(catchableTypes);
   ec.throwsSet = new SubtypeSet(ts.CheckedThrowable());
   return ec;
 }
示例#7
0
 public ExceptionChecker push(Type catchableType) {
   ExceptionChecker ec = this.push();
   ec.catchable = Collections.<Type>singleton(catchableType);
   ec.throwsSet = new SubtypeSet(ts.CheckedThrowable());
   return ec;
 }
示例#8
0
 public ExceptionChecker push(UncaughtReporter reporter) {
   ExceptionChecker ec = this.push();
   ec.reporter = reporter;
   ec.throwsSet = new SubtypeSet(ts.CheckedThrowable());
   return ec;
 }