diff options
Diffstat (limited to 'src')
7 files changed, 39 insertions, 9 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java index 77d82b6622..41556c08bf 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java @@ -29,6 +29,7 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; +import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Runtime; import com.google.devtools.build.lib.syntax.SkylarkList; @@ -175,7 +176,7 @@ class SkylarkAttributesCollection implements SkylarkValue { val == null ? Runtime.NONE // Attribute values should be type safe - : SkylarkType.convertToSkylark(val, null)); + : SkylarkType.convertToSkylark(val, (Environment) null)); return; } if (a.isExecutable()) { @@ -231,7 +232,7 @@ class SkylarkAttributesCollection implements SkylarkValue { for (TransitiveInfoCollection prereq : allPrereq) { builder.put(prereq, original.get(AliasProvider.getDependencyLabel(prereq))); } - attrBuilder.put(skyname, SkylarkType.convertToSkylark(builder.build(), null)); + attrBuilder.put(skyname, SkylarkType.convertToSkylark(builder.build(), (Environment) null)); } else if (type == BuildType.LABEL_DICT_UNARY) { Map<Label, TransitiveInfoCollection> prereqsByLabel = new LinkedHashMap<>(); for (TransitiveInfoCollection target : diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java index c27d1086a8..d445a91567 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java @@ -107,7 +107,8 @@ public class SkylarkRepositoryContext { val == null ? Runtime.NONE // Attribute values should be type safe - : SkylarkType.convertToSkylark(val, null)); + : SkylarkType.convertToSkylark(val, + (com.google.devtools.build.lib.syntax.Environment) null)); } } attrObject = NativeProvider.STRUCT.create(attrBuilder.build(), "No such attribute '%s'"); diff --git a/src/main/java/com/google/devtools/build/lib/packages/Info.java b/src/main/java/com/google/devtools/build/lib/packages/Info.java index 2714379355..50fcb156c3 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/Info.java +++ b/src/main/java/com/google/devtools/build/lib/packages/Info.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import com.google.devtools.build.lib.syntax.ClassObject; +import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Printer; import com.google.devtools.build.lib.syntax.SkylarkType; @@ -81,7 +82,7 @@ public abstract class Info implements ClassObject, SkylarkValue, Serializable { for (Map.Entry<String, Object> e : values.entrySet()) { builder.put( Attribute.getSkylarkName(e.getKey()), - SkylarkType.convertToSkylark(e.getValue(), /*env=*/ null)); + SkylarkType.convertToSkylark(e.getValue(), (Environment) null)); } return builder.build(); } 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 3b693991f8..88be43be0d 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 @@ -70,8 +70,8 @@ public final class EvalUtils { @Override @SuppressWarnings("unchecked") public int compare(Object o1, Object o2) { - o1 = SkylarkType.convertToSkylark(o1, /*env=*/ null); - o2 = SkylarkType.convertToSkylark(o2, /*env=*/ null); + o1 = SkylarkType.convertToSkylark(o1, (Environment) null); + o2 = SkylarkType.convertToSkylark(o2, (Environment) null); if (o1 instanceof SkylarkList && o2 instanceof SkylarkList diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java index 6d9eff5dcd..fc9da3a177 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java @@ -119,9 +119,10 @@ public final class SkylarkDict<K, V> extends MutableMap<K, V> } /** Puts all entries of the given map into the dict, without calling {@link #checkMutable}. */ + @SuppressWarnings("unchecked") private <KK extends K, VV extends V> SkylarkDict<K, V> putAllUnsafe(Map<KK, VV> m) { for (Map.Entry<KK, VV> e : m.entrySet()) { - contents.put(e.getKey(), e.getValue()); + contents.put(e.getKey(), (VV) SkylarkType.convertToSkylark(e.getValue(), mutability)); } return this; } diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java index d452b7d896..303cb50d1c 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java @@ -726,14 +726,21 @@ public abstract class SkylarkType implements Serializable { * Converts an object to a Skylark-compatible type if possible. */ public static Object convertToSkylark(Object object, @Nullable Environment env) { + return convertToSkylark(object, env == null ? null : env.mutability()); + } + + /** + * Converts an object to a Skylark-compatible type if possible. + */ + public static Object convertToSkylark(Object object, @Nullable Mutability mutability) { if (object instanceof List && !(object instanceof SkylarkList)) { - return MutableList.copyOf(env, (List<?>) object); + return MutableList.copyOf(mutability, (List<?>) object); } if (object instanceof SkylarkValue) { return object; } if (object instanceof Map) { - return SkylarkDict.<Object, Object>copyOf(env, (Map<?, ?>) object); + return SkylarkDict.<Object, Object>copyOf(mutability, (Map<?, ?>) object); } // TODO(bazel-team): ensure everything is a SkylarkValue at all times. // Preconditions.checkArgument(EvalUtils.isSkylarkAcceptable( diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java index 34edf9e506..6baa230f79 100644 --- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java +++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java @@ -35,6 +35,8 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import com.google.devtools.build.lib.syntax.SkylarkList.MutableList; import com.google.devtools.build.lib.testutil.TestMode; +import java.util.List; +import java.util.Map; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -119,6 +121,10 @@ public class SkylarkEvaluationTest extends EvaluationTest { public String string() { return "a"; } + @SkylarkCallable(name = "string_list_dict", doc = "") + public Map<String, List<String>> stringListDict() { + return ImmutableMap.of("a", ImmutableList.of("b", "c")); + } @SkylarkCallable( name = "with_params", @@ -751,6 +757,18 @@ public class SkylarkEvaluationTest extends EvaluationTest { "type 'Mock' has no method isEmpty(string str)", "mock.isEmpty(str='abc')"); } + @Test + public void testStringListDictValues() throws Exception { + new SkylarkTest() + .update("mock", new Mock()) + .setUp( + "def func(mock):", + " for i, v in mock.string_list_dict().items():", + " modified_list = v + ['extra_string']", + " return modified_list", + "m = func(mock)") + .testLookup("m", MutableList.of(env, "b", "c", "extra_string")); + } @Test public void testJavaCallWithPositionalAndKwargs() throws Exception { @@ -1328,6 +1346,7 @@ public class SkylarkEvaluationTest extends EvaluationTest { "return_bad", "string", "string_list", + "string_list_dict", "struct_field", "struct_field_callable", "value_of", |