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);
+ }
+ }
}