diff options
author | Laurent Le Brun <laurentlb@google.com> | 2015-03-20 15:10:19 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2015-03-23 11:51:27 +0000 |
commit | 741824b36b3c2be82ed551237b8b92b8b86061bf (patch) | |
tree | 52301ae7e6c7913f8cf6c3144000f097bab68371 /src/main/java/com/google/devtools | |
parent | f02655fec3fdfe9a784d287fff53b886d91bae1c (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/devtools')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java | 2 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/LValue.java | 50 |
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 + "'"); } |