Add Skylark support for string_list_dict
Convert to Skylark values when destructuring a sequence or map.
--
MOS_MIGRATED_REVID=106591523
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
index b633ea6..5d87753 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
@@ -708,6 +708,42 @@
};
@SkylarkSignature(
+ name = "string_list_dict",
+ doc =
+ "Creates an attribute of type dictionary, mapping from string to list of string. "
+ + "Its default value is dict().",
+ objectType = SkylarkAttr.class,
+ returnType = Attribute.Builder.class,
+ optionalNamedOnly = {
+ @Param(name = DEFAULT_ARG, type = Map.class, defaultValue = "{}", doc = DEFAULT_DOC),
+ @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ ),
+ @Param(name = NON_EMPTY_ARG, type = Boolean.class, defaultValue = "False", doc = NON_EMPTY_DOC
+ )
+ },
+ useAst = true,
+ useEnvironment = true
+ )
+ private static BuiltinFunction stringListDict =
+ new BuiltinFunction("string_list_dict") {
+ public Attribute.Builder<?> invoke(
+ Map<?, ?> defaultO,
+ Boolean mandatory,
+ Boolean nonEmpty,
+ FuncallExpression ast,
+ Environment env)
+ throws EvalException {
+ env.checkLoadingPhase("attr.string_list_dict", ast.getLocation());
+ return createAttribute(
+ EvalUtils.optionMap(
+ DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory, NON_EMPTY_ARG, nonEmpty),
+ Type.STRING_LIST_DICT,
+ ast,
+ env);
+ }
+ };
+
+ @SkylarkSignature(
name = "license",
doc = "Creates an attribute of type license. Its default value is NO_LICENSE.",
// TODO(bazel-team): Implement proper license support for Skylark.
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index e14fbad..3cc7789 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -888,14 +888,14 @@
mandatoryPositionals = {
@Param(name = "self", type = Map.class, doc = "This object."),
@Param(name = "key", type = Object.class, doc = "The index or key to access.")},
- useLocation = true)
+ useLocation = true, useEnvironment = true)
private static BuiltinFunction dictIndexOperator = new BuiltinFunction("$index") {
public Object invoke(Map<?, ?> self, Object key,
- Location loc) throws EvalException, ConversionException {
+ Location loc, Environment env) throws EvalException, ConversionException {
if (!self.containsKey(key)) {
throw new EvalException(loc, Printer.format("Key %r not found in dictionary", key));
}
- return self.get(key);
+ return SkylarkType.convertToSkylark(self.get(key), env);
}
};
@@ -905,15 +905,15 @@
mandatoryPositionals = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
@Param(name = "key", type = Object.class, doc = "The index or key to access.")},
- useLocation = true)
+ useLocation = true, useEnvironment = true)
private static BuiltinFunction listIndexOperator = new BuiltinFunction("$index") {
public Object invoke(MutableList self, Object key,
- Location loc) throws EvalException, ConversionException {
+ Location loc, Environment env) throws EvalException, ConversionException {
if (self.isEmpty()) {
throw new EvalException(loc, "List is empty");
}
int index = getListIndex(key, self.size(), loc);
- return self.getList().get(index);
+ return SkylarkType.convertToSkylark(self.getList().get(index), env);
}
};
@@ -923,15 +923,15 @@
mandatoryPositionals = {
@Param(name = "self", type = Tuple.class, doc = "This tuple."),
@Param(name = "key", type = Object.class, doc = "The index or key to access.")},
- useLocation = true)
+ useLocation = true, useEnvironment = true)
private static BuiltinFunction tupleIndexOperator = new BuiltinFunction("$index") {
public Object invoke(Tuple self, Object key,
- Location loc) throws EvalException, ConversionException {
+ Location loc, Environment env) throws EvalException, ConversionException {
if (self.isEmpty()) {
throw new EvalException(loc, "tuple is empty");
}
int index = getListIndex(key, self.size(), loc);
- return self.getList().get(index);
+ return SkylarkType.convertToSkylark(self.getList().get(index), env);
}
};
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
index 67b7db6..74a3eae 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
@@ -227,7 +227,7 @@
* @param contents the contents of the list
* @return a Skylark list containing the specified arguments as elements.
*/
- public static MutableList of(Environment env, Object... contents) {
+ public static MutableList of(@Nullable Environment env, Object... contents) {
return new MutableList(ImmutableList.copyOf(contents), env);
}
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
index 1c57974..23458c7 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
@@ -132,6 +132,13 @@
}
@Test
+ public void testStringListDictAttr() throws Exception {
+ Object result = evalRuleClassCode("attr.string_list_dict(default = {'a': ['b', 'c']})");
+ Attribute attr = ((Attribute.Builder<?>) result).build("a1");
+ assertEquals(Type.STRING_LIST_DICT, attr.getType());
+ }
+
+ @Test
public void testAttrAllowedFileTypesAnyFile() throws Exception {
Object result = evalRuleClassCode("attr.label_list(allow_files = True)");
Attribute attr = ((Attribute.Builder<?>) result).build("a1");