Skylark: Functions don't need to be declared in order. -- MOS_MIGRATED_REVID=93515487
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java index 256abb8..dce9e9c 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java
@@ -106,6 +106,5 @@ for (Statement stmts : statements) { stmts.validate(localEnv); } - env.declare(ident.getName(), getLocation()); } }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java index 5c363a6..6381c15 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -194,9 +194,7 @@ List<Statement> statements = parser.parseFileInput(); boolean hasSemanticalErrors = false; try { - for (Statement statement : statements) { - statement.validate(validationEnvironment); - } + validationEnvironment.validateAst(statements); } catch (EvalException e) { // Do not report errors caused by a previous parsing error, as it has already been reported. if (!e.isDueToIncompleteAST()) {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ValidationEnvironment.java b/src/main/java/com/google/devtools/build/lib/syntax/ValidationEnvironment.java index 5d38ccf..a615d67 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/ValidationEnvironment.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/ValidationEnvironment.java
@@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; @@ -154,4 +155,23 @@ readOnlyVariables.removeAll(futureReadOnlyVariables.peek()); clonable = false; } + + /** + * Validates the AST and runs static checks. + */ + public void validateAst(List<Statement> statements) throws EvalException { + // Add every function in the environment before validating. This is + // necessary because functions may call other functions defined + // later in the file. + for (Statement statement : statements) { + if (statement instanceof FunctionDefStatement) { + FunctionDefStatement fct = (FunctionDefStatement) statement; + declare(fct.getIdent().getName(), fct.getLocation()); + } + } + + for (Statement statement : statements) { + statement.validate(this); + } + } }