Prevented catching/wrapping of InterruptedExceptions, especially in BaseFunction.

--
MOS_MIGRATED_REVID=102988766
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ASTNode.java b/src/main/java/com/google/devtools/build/lib/syntax/ASTNode.java
index 754035e..0ec6a98 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ASTNode.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ASTNode.java
@@ -41,16 +41,16 @@
   protected final EvalException handleException(Exception original) {
     // If there is already a non-empty stack trace, we only add this node iff it describes a
     // new scope (e.g. FuncallExpression).
-    if (original instanceof EvalExceptionWithStackTrace && isNewScope()) {
+    if (original instanceof EvalExceptionWithStackTrace) {
       EvalExceptionWithStackTrace real = (EvalExceptionWithStackTrace) original;
-      real.registerNode(this);
+      if (isNewScope()) {
+        real.registerNode(this);
+      }
       return real;
     }
 
-    // If the exception is an instance of a subclass of EvalException (such as
-    // ReturnStatement.ReturnException and FlowStatement.FlowException), we just return it
-    // unchanged.
-    if (original instanceof EvalException && !original.getClass().equals(EvalException.class)) {
+    // Returns the original exception if it cannot be attached to a stack trace.
+    if (original instanceof EvalException && !((EvalException) original).canBeAddedToStackTrace()) {
       return (EvalException) original;
     }
 
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
index 450791d..8ca1d1a 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
@@ -410,7 +410,7 @@
    * @param ast the expression for this function's definition
    * @param env the Environment in the function is called
    * @return the value resulting from evaluating the function with the given arguments
-   * @throws construction of EvalException-s containing source information.
+   * @throws EvalException-s containing source information.
    */
   public Object call(List<Object> args,
       @Nullable Map<String, Object> kwargs,
@@ -435,6 +435,7 @@
    * @param args an array of argument values sorted as per the signature.
    * @param ast the source code for the function if user-defined
    * @param env the lexical environment of the function call
+   * @throws InterruptedException may be thrown in the function implementations.
    */
   // Don't make it abstract, so that subclasses may be defined that @Override the outer call() only.
   protected Object call(Object[] args,
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalException.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalException.java
index 186153e..aec9f2b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalException.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalException.java
@@ -159,6 +159,14 @@
   }
 
   /**
+   * Returns whether this exception can be added to a stack trace created by {@link
+   * EvalExceptionWithStackTrace}.
+   */
+  public boolean canBeAddedToStackTrace() {
+    return true;
+  }
+
+  /**
    * A class to support a special case of EvalException when the cause of the error is an
    * Exception during a direct Java call. Allow the throwing code to provide context in a message.
    */
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalExceptionWithStackTrace.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalExceptionWithStackTrace.java
index 7300e4b..9ec6860 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalExceptionWithStackTrace.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalExceptionWithStackTrace.java
@@ -34,6 +34,13 @@
     registerNode(culprit);
   }
 
+  @Override
+  public boolean canBeAddedToStackTrace() {
+    // Doesn't make any sense to add this exception to another instance of
+    // EvalExceptionWithStackTrace.
+    return false;
+  }
+
   /**
    * Returns the appropriate location for this exception.
    *
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
index 1af7bfa..32b61c9 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
@@ -82,5 +82,10 @@
     public boolean mustTerminateLoop() {
       return terminateLoop;
     }
+
+    @Override
+    public boolean canBeAddedToStackTrace() {
+      return false;
+    }
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index b1ca1f6..04adc5e 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -1082,7 +1082,7 @@
   private static BuiltinFunction struct = new BuiltinFunction("struct") {
       @SuppressWarnings("unchecked")
     public SkylarkClassObject invoke(Map<String, Object> kwargs, Location loc)
-        throws EvalException, InterruptedException {
+        throws EvalException {
       return new SkylarkClassObject(kwargs, loc);
     }
   };
@@ -1183,7 +1183,7 @@
       useEnvironment = true)
   private static BuiltinFunction enumerate = new BuiltinFunction("enumerate") {
     public Object invoke(Object input, Location loc, Environment env)
-        throws EvalException, ConversionException, InterruptedException {
+        throws EvalException, ConversionException {
       int count = 0;
       List<SkylarkList> result = Lists.newArrayList();
       for (Object obj : Type.OBJECT_LIST.convert(input, "input")) {
@@ -1217,7 +1217,7 @@
   private static final BuiltinFunction range = new BuiltinFunction("range") {
       public Object invoke(Integer startOrStop, Object stopOrNone, Integer step, Location loc,
           Environment env)
-        throws EvalException, ConversionException, InterruptedException {
+        throws EvalException, ConversionException {
       int start;
       int stop;
       if (stopOrNone == Runtime.NONE) {
@@ -1255,7 +1255,7 @@
       mandatoryPositionals = {
         @Param(name = "x", type = Map.class, doc = "The parameter to convert.")})
   private static final BuiltinFunction select = new BuiltinFunction("select") {
-    public Object invoke(Map<?, ?> dict) throws EvalException, InterruptedException {
+    public Object invoke(Map<?, ?> dict) throws EvalException {
       return SelectorList.of(new SelectorValue(dict));
     }
   };
@@ -1412,7 +1412,7 @@
       returnType = SkylarkList.class, useLocation = true)
   private static final BuiltinFunction zip = new BuiltinFunction("zip") {
     public SkylarkList invoke(SkylarkList args, Location loc)
-        throws EvalException, InterruptedException {
+        throws EvalException {
       Iterator<?>[] iterators = new Iterator<?>[args.size()];
       for (int i = 0; i < args.size(); i++) {
         iterators[i] = EvalUtils.toIterable(args.get(i), loc).iterator();
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
index 0e377eb..d9302b6 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
@@ -34,6 +34,11 @@
     public Object getValue() {
       return value;
     }
+
+    @Override
+    public boolean canBeAddedToStackTrace() {
+      return false;
+    }
   }
 
   private final Expression returnExpression;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
index 6140acb..b22c45a 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
@@ -31,7 +31,8 @@
     this.funcallEnv = funcallEnv;
   }
 
-  public Object call(ClassObject ctx, Object... arguments) throws EvalException {
+  public Object call(ClassObject ctx, Object... arguments)
+      throws EvalException, InterruptedException {
     try (Mutability mutability = Mutability.create("callback %s", callback)) {
       Environment env = Environment.builder(mutability)
           .setSkylark()
@@ -40,7 +41,7 @@
           .build();
       return callback.call(
           ImmutableList.<Object>builder().add(ctx).add(arguments).build(), null, ast, env);
-    } catch (InterruptedException | ClassCastException | IllegalArgumentException e) {
+    } catch (ClassCastException | IllegalArgumentException e) {
       throw new EvalException(ast.getLocation(), e.getMessage());
     }
   }