Update from Google.

--
MOE_MIGRATED_REVID=85702957
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
new file mode 100644
index 0000000..619e841
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
@@ -0,0 +1,108 @@
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.syntax;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Syntax node for an assignment statement.
+ */
+public final class AssignmentStatement extends Statement {
+
+  private final Expression lvalue;
+
+  private final Expression expression;
+
+  /**
+   *  Constructs an assignment: "lvalue := value".
+   */
+  AssignmentStatement(Expression lvalue, Expression expression) {
+    this.lvalue = lvalue;
+    this.expression = expression;
+  }
+
+  /**
+   *  Returns the LHS of the assignment.
+   */
+  public Expression getLValue() {
+    return lvalue;
+  }
+
+  /**
+   *  Returns the RHS of the assignment.
+   */
+  public Expression getExpression() {
+    return expression;
+  }
+
+  @Override
+  public String toString() {
+    return lvalue + " = " + expression + '\n';
+  }
+
+  @Override
+  void exec(Environment env) throws EvalException, InterruptedException {
+    if (!(lvalue instanceof Ident)) {
+      throw new EvalException(getLocation(),
+          "can only assign to variables, not to '" + lvalue + "'");
+    }
+
+    Ident ident = (Ident) lvalue;
+    Object result = expression.eval(env);
+    Preconditions.checkNotNull(result, "result of " + expression + " is null");
+
+    if (env.isSkylarkEnabled()) {
+      // The variable may have been referenced successfully if a global variable
+      // with the same name exists. In this case an Exception needs to be thrown.
+      SkylarkEnvironment skylarkEnv = (SkylarkEnvironment) env;
+      if (skylarkEnv.hasBeenReadGlobalVariable(ident.getName())) {
+        throw new EvalException(getLocation(), "Variable '" + ident.getName()
+            + "' is referenced before assignment."
+            + "The variable is defined in the global scope.");
+      }
+      Class<?> variableType = skylarkEnv.getVariableType(ident.getName());
+      Class<?> resultType = EvalUtils.getSkylarkType(result.getClass());
+      if (variableType != null && !variableType.equals(resultType)
+          && !resultType.equals(Environment.NoneType.class)
+          && !variableType.equals(Environment.NoneType.class)) {
+        throw new EvalException(getLocation(), String.format("Incompatible variable types, "
+            + "trying to assign %s (type of %s) to variable %s which is already %s",
+            EvalUtils.prettyPrintValue(result),
+            EvalUtils.getDatatypeName(result),
+            ident.getName(),
+            EvalUtils.getDataTypeNameFromClass(variableType)));
+      }
+    }
+    env.update(ident.getName(), result);
+  }
+
+  @Override
+  public void accept(SyntaxTreeVisitor visitor) {
+    visitor.visit(this);
+  }
+
+  @Override
+  void validate(ValidationEnvironment env) throws EvalException {
+    // TODO(bazel-team): Implement other validations.
+    if (lvalue instanceof Ident) {
+      Ident ident = (Ident) lvalue;
+      SkylarkType resultType = expression.validate(env);
+      env.update(ident.getName(), resultType, getLocation());
+    } else {
+      throw new EvalException(getLocation(),
+          "can only assign to variables, not to '" + lvalue + "'");
+    }
+  }
+}