Preliminary cleanup for removing Blaze-specific code from the environment

The goal is to remove parse and eval functions from Environment, as well as
isSkylark boolean.

--
MOS_MIGRATED_REVID=129202204
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 3d324b2..dffd635 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
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.syntax;
 
+import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.hash.HashCode;
 import com.google.devtools.build.lib.events.Event;
@@ -238,6 +239,21 @@
         HashCode.fromBytes(file.getMD5Digest()).toString());
   }
 
+  public static BuildFileAST parseBuildString(EventHandler eventHandler, String... content) {
+    String str = Joiner.on("\n").join(content);
+    ParserInputSource input = ParserInputSource.create(str, null);
+    Parser.ParseResult result = Parser.parseFile(input, eventHandler, false);
+    return new BuildFileAST(ImmutableList.<Statement>of(), result, null);
+  }
+
+  // TODO(laurentlb): Merge parseSkylarkString and parseBuildString.
+  public static BuildFileAST parseSkylarkString(EventHandler eventHandler, String... content) {
+    String str = Joiner.on("\n").join(content);
+    ParserInputSource input = ParserInputSource.create(str, null);
+    Parser.ParseResult result = Parser.parseFileForSkylark(input, eventHandler, null);
+    return new BuildFileAST(ImmutableList.<Statement>of(), result, null);
+  }
+
   /**
    * Parse the specified build file, without building the AST.
    *
@@ -249,6 +265,23 @@
   }
 
   /**
+   * Evaluates the code and return the value of the last statement if it's an
+   * Expression or else null.
+   */
+  @Nullable public Object eval(Environment env) throws EvalException, InterruptedException {
+    Object last = null;
+    for (Statement statement : stmts) {
+      if (statement instanceof ExpressionStatement) {
+        last = ((ExpressionStatement) statement).getExpression().eval(env);
+      } else {
+        statement.exec(env);
+        last = null;
+      }
+    }
+    return last;
+  }
+
+  /**
    * Returns a hash code calculated from the string content of the source file of this AST.
    */
   @Nullable public String getContentHashCode() {
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 a2db357..4418167 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
@@ -321,12 +321,14 @@
 
   /**
    * Is this Environment being executed in Skylark context?
+   * TODO(laurentlb): Remove from Environment
    */
   private boolean isSkylark;
 
   /**
    * Is this Environment being executed during the loading phase?
    * Many builtin functions are only enabled during the loading phase, and check this flag.
+   * TODO(laurentlb): Remove from Environment
    */
   private Phase phase;
 
@@ -355,6 +357,7 @@
 
   /**
    * The path to the tools repository.
+   * TODO(laurentlb): Remove from Environment
    */
   private final String toolsRepository;
 
@@ -935,42 +938,35 @@
     };
 
   /**
-   * Parses some String input without a supporting file, returning statements and comments.
+   * Parses some String inputLines without a supporting file, returning statements only.
+   * TODO(laurentlb): Remove from Environment
    * @param inputLines a list of lines of code
    */
   @VisibleForTesting
-  Parser.ParseResult parseFileWithComments(String... inputLines) {
+  public List<Statement> parseFile(String... inputLines) {
     ParserInputSource input = ParserInputSource.create(Joiner.on("\n").join(inputLines), null);
-    return isSkylark
+    Parser.ParseResult result = isSkylark
         ? Parser.parseFileForSkylark(input, eventHandler, new ValidationEnvironment(this))
         : Parser.parseFile(input, eventHandler, /*parsePython=*/false);
-  }
-
-  /**
-   * Parses some String input without a supporting file, returning statements only.
-   * @param input a list of lines of code
-   */
-  @VisibleForTesting
-  public List<Statement> parseFile(String... input) {
-    return parseFileWithComments(input).statements;
+    return result.statements;
   }
 
   /**
    * Evaluates code some String input without a supporting file.
+   * TODO(laurentlb): Remove from Environment
    * @param input a list of lines of code to evaluate
    * @return the value of the last statement if it's an Expression or else null
    */
   @Nullable public Object eval(String... input) throws EvalException, InterruptedException {
-    Object last = null;
-    for (Statement statement : parseFile(input)) {
-      if (statement instanceof ExpressionStatement) {
-        last = ((ExpressionStatement) statement).getExpression().eval(this);
-      } else {
-        statement.exec(this);
-        last = null;
-      }
+    BuildFileAST ast;
+    if (isSkylark) {
+      ast = BuildFileAST.parseSkylarkString(eventHandler, input);
+      ValidationEnvironment valid = new ValidationEnvironment(this);
+      valid.validateAst(ast.getStatements(), eventHandler);
+    } else {
+      ast = BuildFileAST.parseBuildString(eventHandler, input);
     }
-    return last;
+    return ast.eval(this);
   }
 
   public String getToolsRepository() {
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 dbc16cd..641f7d9 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
@@ -240,18 +240,10 @@
     Lexer lexer = new Lexer(input, eventHandler, false);
     Parser parser = new Parser(lexer, eventHandler, SKYLARK);
     List<Statement> statements = parser.parseFileInput();
-    boolean hasSemanticalErrors = false;
-    try {
-      if (validationEnvironment != null) {
-        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()) {
-        eventHandler.handle(Event.error(e.getLocation(), e.getMessage()));
-      }
-      hasSemanticalErrors = true;
-    }
+    // TODO(laurentlb): Remove validation from parser
+    boolean hasSemanticalErrors = validationEnvironment == null
+        ? false
+        : !validationEnvironment.validateAst(statements, eventHandler);
     return new ParseResult(statements, parser.comments, locationFromStatements(lexer, statements),
         parser.errorsCount > 0 || lexer.containsErrors() || hasSemanticalErrors);
   }
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 8c625d8..991b106 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
@@ -14,6 +14,8 @@
 
 package com.google.devtools.build.lib.syntax;
 
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.util.Preconditions;
 
@@ -157,6 +159,18 @@
     }
   }
 
+  public boolean validateAst(List<Statement> statements, EventHandler eventHandler) {
+    try {
+      validateAst(statements);
+      return true;
+    } catch (EvalException e) {
+      if (!e.isDueToIncompleteAST()) {
+        eventHandler.handle(Event.error(e.getLocation(), e.getMessage()));
+      }
+      return false;
+    }
+  }
+
   /**
    * Returns whether the current statement is inside a for loop (either in this environment or one
    * of its parents)