bazel syntax: make Eval private
Make Eval private. It should never have been public.
Mostly it was used as a hook for the debugger (via subclassing).
Now the debugger installs a hook directly into a global variable
that Eval inspects before executing each statement.
Make all package-visible functions of Eval static.
It should become the sole locus of knowledge about the tree-walking evaluator.
A follow-up change will move all tree-based evaluation logic from
Expressions into this class (Statements are done already).
Environment.evaluate(String) has been split into an expression flavor
(debugEval) and a file flavor (debugExec). If we eliminate the
pointless Debuggable interface these can become static methods in
EvalUtils, in a follow-up.
This is a behavior change to the debugger: entering "x=1; x+1"
will execute x+1 only for its effects; its value, as a statement,
is now None, not 2.
Delete DebugServerUtils.
Combine its install and remove methods as setDebugger, and move it to EvalUtils.
Delete DebugCallable (unused).
Delete DebugAwareEval (obsolete).
PiperOrigin-RevId: 268941210
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
index 6871eac..8d84321 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
@@ -34,7 +34,6 @@
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.SpellChecker;
-import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -1223,42 +1222,44 @@
}
private static final class EvalEventHandler implements EventHandler {
- List<String> messages = new ArrayList<>();
+ List<Event> messages = new ArrayList<>();
@Override
public void handle(Event event) {
if (event.getKind() == EventKind.ERROR) {
- messages.add(event.getMessage());
+ messages.add(event);
}
}
}
- /** Evaluates a Skylark statement in the adapter's environment. (Debugger API) */
- public Object evaluate(String contents) throws EvalException, InterruptedException {
- ParserInputSource input =
- ParserInputSource.create(contents, PathFragment.create("<debug eval>"));
- EvalEventHandler eventHandler = new EvalEventHandler();
- Statement statement = Parser.parseStatement(input, eventHandler);
- if (!eventHandler.messages.isEmpty()) {
- throw new EvalException(statement.getLocation(), eventHandler.messages.get(0));
+ /** Evaluates a Skylark statement in this environment. (Debugger API) */
+ // TODO(adonovan): push this up into the debugger once the eval API is finalized.
+ public Object debugEval(ParserInputSource input) throws EvalException, InterruptedException {
+ EvalEventHandler handler = new EvalEventHandler();
+ Expression expr = Expression.parse(input, handler);
+ if (!handler.messages.isEmpty()) {
+ Event ev = handler.messages.get(0);
+ throw new EvalException(ev.getLocation(), ev.getMessage());
}
- // TODO(bazel-team): move statement handling code to Eval
- // deal with the most common case first
- if (statement.kind() == Statement.Kind.EXPRESSION) {
- return ((ExpressionStatement) statement).getExpression().doEval(this);
+ return expr.eval(this);
+ }
+
+ /** Executes a Skylark file (sequence of statements) in this environment. (Debugger API) */
+ // TODO(adonovan): push this up into the debugger once the exec API is finalized.
+ public void debugExec(ParserInputSource input) throws EvalException, InterruptedException {
+ EvalEventHandler handler = new EvalEventHandler();
+ BuildFileAST file = BuildFileAST.parse(input, handler);
+ if (!handler.messages.isEmpty()) {
+ Event ev = handler.messages.get(0);
+ throw new EvalException(ev.getLocation(), ev.getMessage());
}
- // all other statement types are executed directly
- Eval.fromEnvironment(this).exec(statement);
- switch (statement.kind()) {
- case ASSIGNMENT:
- case AUGMENTED_ASSIGNMENT:
- return ((AssignmentStatement) statement).getLHS().doEval(this);
- case RETURN:
- Expression expr = ((ReturnStatement) statement).getReturnExpression();
- return expr != null ? expr.doEval(this) : Runtime.NONE;
- default:
- return Runtime.NONE;
+ for (Statement stmt : file.getStatements()) {
+ if (stmt instanceof LoadStatement) {
+ throw new EvalException(null, "cannot execute load statements in debugger");
+ }
}
+ ValidationEnvironment.validateFile(file, this, /*isBuildFile=*/ false);
+ Eval.execStatements(this, file.getStatements());
}
/**