Fixed Skylark stack trace:
- Moved registration mechanism from BaseFunction into ASTNode / Statement / Expression
- Added more details about statements/expressions to the output trace (including if's)
- Fixed wrong locations
--
MOS_MIGRATED_REVID=102841164
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 2fa492e..754035e 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
@@ -28,6 +28,35 @@
protected ASTNode() {}
+ /**
+ * Returns whether this node represents a new scope, e.g. a function call.
+ */
+ protected boolean isNewScope() {
+ return false;
+ }
+
+ /**
+ * Returns an exception which should be thrown instead of the original one.
+ */
+ 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()) {
+ EvalExceptionWithStackTrace real = (EvalExceptionWithStackTrace) original;
+ 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)) {
+ return (EvalException) original;
+ }
+
+ return new EvalExceptionWithStackTrace(original, this);
+ }
+
@VisibleForTesting // productionVisibility = Visibility.PACKAGE_PRIVATE
public void setLocation(Location location) {
this.location = location;