diff options
author | Dmitry Lomov <dslomov@google.com> | 2017-03-01 10:09:32 +0000 |
---|---|---|
committer | Yue Gan <yueg@google.com> | 2017-03-01 12:36:29 +0000 |
commit | 01120026dc313ee7ad9ea95069a29252eb19173b (patch) | |
tree | 2121c64fcdd383586d131ba2900f793be5eedceb /src/main/java/com/google/devtools/build/lib/syntax | |
parent | 220b6390fcdb775bafc55793d2a722c44e08d30a (diff) |
Export exportable values as we go instead of at the end of evaluation.
This simplifies implementation of attr.* functions and helps make
declared provider implementation simpler.
--
PiperOrigin-RevId: 148867326
MOS_MIGRATED_REVID=148867326
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/syntax')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java | 67 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/LValue.java | 30 |
2 files changed, 81 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java b/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java index a0f6a33367..b1f079a14b 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java @@ -194,27 +194,52 @@ public class BuildFileAST extends ASTNode { public boolean exec(Environment env, EventHandler eventHandler) throws InterruptedException { boolean ok = true; for (Statement stmt : stmts) { - try { - stmt.exec(env); - } catch (EvalException e) { + if (!execTopLevelStatement(stmt, env, eventHandler)) { ok = false; - // Do not report errors caused by a previous parsing error, as it has already been - // reported. - if (e.isDueToIncompleteAST()) { - continue; - } - // When the exception is raised from another file, report first the location in the - // BUILD file (as it is the most probable cause for the error). - Location exnLoc = e.getLocation(); - Location nodeLoc = stmt.getLocation(); - eventHandler.handle(Event.error( - (exnLoc == null || !nodeLoc.getPath().equals(exnLoc.getPath())) ? nodeLoc : exnLoc, - e.getMessage())); } } return ok; } + /** + * Executes tol-level statement of this build file in a given Environment. + * + * <p>If, for any reason, execution of a statement cannot be completed, an {@link EvalException} + * is thrown by {@link Statement#exec(Environment)}. This exception is caught here and reported + * through reporter. In effect, there is a + * "try/except" block around every top level statement. Such exceptions are not ignored, though: + * they are visible via the return value. Rules declared in a package containing any error + * (including loading-phase semantical errors that cannot be checked here) must also be considered + * "in error". + * + * <p>Note that this method will not affect the value of {@link #containsErrors()}; that refers + * only to lexer/parser errors. + * + * @return true if no error occurred during execution. + */ + + public boolean execTopLevelStatement(Statement stmt, Environment env, + EventHandler eventHandler) throws InterruptedException { + try { + stmt.exec(env); + return true; + } catch (EvalException e) { + // Do not report errors caused by a previous parsing error, as it has already been + // reported. + if (e.isDueToIncompleteAST()) { + return false; + } + // When the exception is raised from another file, report first the location in the + // BUILD file (as it is the most probable cause for the error). + Location exnLoc = e.getLocation(); + Location nodeLoc = stmt.getLocation(); + eventHandler.handle(Event.error( + (exnLoc == null || !nodeLoc.getPath().equals(exnLoc.getPath())) ? nodeLoc : exnLoc, + e.getMessage())); + return false; + } + } + @Override public String toString() { return "BuildFileAST" + getStatements(); @@ -348,10 +373,20 @@ public class BuildFileAST extends ASTNode { @Nullable public static Object eval(Environment env, String... input) throws EvalException, InterruptedException { + BuildFileAST ast = parseAndValidateSkylarkString(env, input); + return ast.eval(env); + } + + /** + * Parses and validates the lines from input and return the the AST + * In case of error during validation, it throws an EvalException. + */ + public static BuildFileAST parseAndValidateSkylarkString(Environment env, String[] input) + throws EvalException { BuildFileAST ast = parseSkylarkString(env.getEventHandler(), input); ValidationEnvironment valid = new ValidationEnvironment(env); valid.validateAst(ast.getStatements()); - return ast.eval(env); + return ast; } /** diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LValue.java b/src/main/java/com/google/devtools/build/lib/syntax/LValue.java index 22d686bf4e..ecc72073fe 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/LValue.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/LValue.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.syntax; +import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.util.Preconditions; import java.io.Serializable; @@ -73,6 +74,35 @@ public class LValue implements Serializable { } } + /** + * Returns all names bound by this LValue. + * + * Examples: + * <ul> + * <li><{@code x = ...} binds x.</li> + * <li><{@code x, [y,z] = ..} binds x, y, z.</li> + * <li><{@code x[5] = ..} does not bind any names.</li> + * </ul> + */ + public ImmutableSet<String> boundNames() { + ImmutableSet.Builder<String> result = ImmutableSet.builder(); + collectBoundNames(expr, result); + return result.build(); + } + + private static void collectBoundNames(Expression lhs, ImmutableSet.Builder<String> result) { + if (lhs instanceof Identifier) { + result.add(((Identifier) lhs).getName()); + return; + } + if (lhs instanceof ListLiteral) { + ListLiteral variables = (ListLiteral) lhs; + for (Expression expression : variables.getElements()) { + collectBoundNames(expression, result); + } + } + } + private static void doAssign( Environment env, Location loc, Expression lhs, Object result) throws EvalException, InterruptedException { |