aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Laurent Le Brun <laurentlb@google.com>2015-03-20 15:10:19 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2015-03-23 11:51:27 +0000
commit741824b36b3c2be82ed551237b8b92b8b86061bf (patch)
tree52301ae7e6c7913f8cf6c3144000f097bab68371 /src/main/java/com/google
parentf02655fec3fdfe9a784d287fff53b886d91bae1c (diff)
Enable support for multiple variable assignments.
This happens in for loops, list comprehensions and simple assigment. e.g. a, b = expr [a for a, b in expr] -- MOS_MIGRATED_REVID=89123977
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/LValue.java50
2 files changed, 47 insertions, 5 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
index c4c3b0822f..9610c80baf 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
@@ -601,6 +601,8 @@ public abstract class EvalUtils {
public static Collection<?> toCollection(Object o, Location loc) throws EvalException {
if (o instanceof Collection) {
return (Collection<Object>) o;
+ } else if (o instanceof SkylarkList) {
+ return ((SkylarkList) o).toList();
} else if (o instanceof Map<?, ?>) {
Map<Comparable<?>, Object> dict = (Map<Comparable<?>, Object>) o;
// For dictionaries we iterate through the keys only
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 271315451d..d2e3925b85 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
@@ -18,6 +18,7 @@ import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.events.Location;
import java.io.Serializable;
+import java.util.Collection;
/**
* Class representing an LValue.
@@ -44,12 +45,41 @@ public class LValue implements Serializable {
*/
public void assign(Environment env, Location loc, Object result)
throws EvalException, InterruptedException {
- if (!(expr instanceof Ident)) {
- throw new EvalException(loc,
- "can only assign to variables, not to '" + expr + "'");
+ assign(env, loc, expr, result);
+ }
+
+ private static void assign(Environment env, Location loc, Expression lvalue, Object result)
+ throws EvalException, InterruptedException {
+ if (lvalue instanceof Ident) {
+ assign(env, loc, (Ident) lvalue, result);
+ return;
+ }
+
+ if (lvalue instanceof ListLiteral) {
+ ListLiteral variables = (ListLiteral) lvalue;
+ Collection<?> rvalue = EvalUtils.toCollection(result, loc);
+ int len = variables.getElements().size();
+ if (len != rvalue.size()) {
+ throw new EvalException(loc, String.format(
+ "lvalue has length %d, but rvalue has has length %d", len, rvalue.size()));
+ }
+ int i = 0;
+ for (Object o : rvalue) {
+ assign(env, loc, variables.getElements().get(i), o);
+ i++;
+ }
+ return;
}
- Ident ident = (Ident) expr;
+ throw new EvalException(loc,
+ "can only assign to variables and tuples, not to '" + lvalue + "'");
+ }
+
+ /**
+ * Assign value to a single variable.
+ */
+ private static void assign(Environment env, Location loc, Ident ident, Object result)
+ throws EvalException, InterruptedException {
Preconditions.checkNotNull(result, "trying to assign null to %s", ident);
if (env.isSkylarkEnabled()) {
@@ -79,12 +109,22 @@ public class LValue implements Serializable {
void validate(ValidationEnvironment env, Location loc, SkylarkType rvalueType)
throws EvalException {
- // TODO(bazel-team): Implement other validations.
+ validate(env, loc, expr, rvalueType);
+ }
+
+ private static void validate(ValidationEnvironment env, Location loc, Expression expr,
+ SkylarkType rvalueType) throws EvalException {
if (expr instanceof Ident) {
Ident ident = (Ident) expr;
env.update(ident.getName(), rvalueType, loc);
return;
}
+ if (expr instanceof ListLiteral) {
+ for (Expression e : ((ListLiteral) expr).getElements()) {
+ validate(env, loc, e, SkylarkType.UNKNOWN);
+ }
+ return;
+ }
throw new EvalException(loc,
"can only assign to variables, not to '" + expr + "'");
}