diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java index a032b473ec..cc238179d8 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java @@ -42,6 +42,8 @@ public class SkylarkEnvironment extends Environment implements Serializable { */ private final Set<String> readGlobalVariables = new HashSet<>(); + private ImmutableList<BaseFunction> stackTrace; + @Nullable private String fileContentHashCode; /** @@ -51,17 +53,20 @@ public class SkylarkEnvironment extends Environment implements Serializable { public static SkylarkEnvironment createEnvironmentForFunctionCalling( Environment callerEnv, SkylarkEnvironment definitionEnv, UserDefinedFunction function) throws EvalException { - if (callerEnv.stackTraceContains(function)) { + if (callerEnv.getStackTrace().contains(function)) { throw new EvalException( function.getLocation(), "Recursion was detected when calling '" + function.getName() + "' from '" + Iterables.getLast(callerEnv.getStackTrace()).getName() + "'"); } + ImmutableList<BaseFunction> stackTrace = new ImmutableList.Builder<BaseFunction>() + .addAll(callerEnv.getStackTrace()) + .add(function) + .build(); SkylarkEnvironment childEnv = // Always use the caller Environment's EventHandler. We cannot assume that the // definition Environment's EventHandler is still working properly. - new SkylarkEnvironment( - definitionEnv, callerEnv.getCopyOfUpdatedStackTrace(function), callerEnv.eventHandler); + new SkylarkEnvironment(definitionEnv, stackTrace, callerEnv.eventHandler); if (callerEnv.isLoadingPhase()) { childEnv.setLoadingPhase(); } @@ -78,8 +83,9 @@ public class SkylarkEnvironment extends Environment implements Serializable { } private SkylarkEnvironment(SkylarkEnvironment definitionEnv, - ImmutableList<StackTraceElement> stackTrace, EventHandler eventHandler) { - super(definitionEnv.getGlobalEnvironment(), stackTrace); + ImmutableList<BaseFunction> stackTrace, EventHandler eventHandler) { + super(definitionEnv.getGlobalEnvironment()); + this.stackTrace = stackTrace; this.eventHandler = Preconditions.checkNotNull(eventHandler, "EventHandler cannot be null in an Environment which calls into Skylark"); } @@ -87,17 +93,13 @@ public class SkylarkEnvironment extends Environment implements Serializable { /** * Creates a global SkylarkEnvironment. */ - public SkylarkEnvironment(EventHandler eventHandler, String astFileContentHashCode, - ImmutableList<StackTraceElement> stackTrace) { - super(stackTrace); + public SkylarkEnvironment(EventHandler eventHandler, String astFileContentHashCode) { + super(); + stackTrace = ImmutableList.of(); this.eventHandler = eventHandler; this.fileContentHashCode = astFileContentHashCode; } - public SkylarkEnvironment(EventHandler eventHandler, String astFileContentHashCode) { - this(eventHandler, astFileContentHashCode, ImmutableList.<StackTraceElement>of()); - } - @VisibleForTesting public SkylarkEnvironment(EventHandler eventHandler) { this(eventHandler, null); @@ -105,16 +107,21 @@ public class SkylarkEnvironment extends Environment implements Serializable { public SkylarkEnvironment(SkylarkEnvironment globalEnv) { super(globalEnv); + stackTrace = ImmutableList.of(); this.eventHandler = globalEnv.eventHandler; } + @Override + public ImmutableList<BaseFunction> getStackTrace() { + return stackTrace; + } + /** * Clones this Skylark global environment. */ public SkylarkEnvironment cloneEnv(EventHandler eventHandler) { Preconditions.checkArgument(isGlobal()); - SkylarkEnvironment newEnv = - new SkylarkEnvironment(eventHandler, this.fileContentHashCode, getStackTrace()); + SkylarkEnvironment newEnv = new SkylarkEnvironment(eventHandler, this.fileContentHashCode); for (Entry<String, Object> entry : env.entrySet()) { newEnv.env.put(entry.getKey(), entry.getValue()); } |