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());
}
}