aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java126
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java25
-rw-r--r--src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java74
3 files changed, 217 insertions, 8 deletions
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 a6609d4666..6793119eaf 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
@@ -87,7 +87,7 @@ public final class SkylarkAttr implements SkylarkValue {
private static final String ALLOW_RULES_ARG = "allow_rules";
private static final String ALLOW_RULES_DOC =
"which rule targets (name of the classes) are allowed. This is deprecated (kept only for "
- + "compatiblity), use providers instead.";
+ + "compatibility), use providers instead.";
private static final String ASPECTS_ARG = "aspects";
private static final String ASPECTS_ARG_DOC =
@@ -102,6 +102,10 @@ public final class SkylarkAttr implements SkylarkValue {
private static final String DEFAULT_ARG = "default";
private static final String DEFAULT_DOC = "the default value of the attribute.";
+ private static final String DOC_ARG = "doc";
+ private static final String DOC_DOC =
+ "a description of the attribute that can be extracted by documentation generating tools.";
+
private static final String EXECUTABLE_ARG = "executable";
private static final String EXECUTABLE_DOC =
"True if the labels have to be executable. This means the label must refer to an "
@@ -462,6 +466,14 @@ public final class SkylarkAttr implements SkylarkValue {
positional = false
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -486,6 +498,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("int") {
public Descriptor invoke(
Integer defaultInt,
+ String doc,
Boolean mandatory,
SkylarkList<?> values,
FuncallExpression ast,
@@ -518,6 +531,14 @@ public final class SkylarkAttr implements SkylarkValue {
positional = false
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -542,6 +563,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("string") {
public Descriptor invoke(
String defaultString,
+ String doc,
Boolean mandatory,
SkylarkList<?> values,
FuncallExpression ast,
@@ -587,6 +609,14 @@ public final class SkylarkAttr implements SkylarkValue {
+ "<code>attr.label(default = \"//a:b\")</code>"
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = EXECUTABLE_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -674,6 +704,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("label") {
public Descriptor invoke(
Object defaultO,
+ String doc,
Boolean executable,
Object allowFiles,
Object allowSingleFile,
@@ -739,6 +770,14 @@ public final class SkylarkAttr implements SkylarkValue {
doc = DEFAULT_DOC
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -764,6 +803,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("string_list") {
public Descriptor invoke(
SkylarkList<?> defaultList,
+ String doc,
Boolean mandatory,
Boolean nonEmpty,
Boolean allowEmpty,
@@ -803,6 +843,14 @@ public final class SkylarkAttr implements SkylarkValue {
doc = DEFAULT_DOC
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -828,6 +876,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("int_list") {
public Descriptor invoke(
SkylarkList<?> defaultList,
+ String doc,
Boolean mandatory,
Boolean nonEmpty,
Boolean allowEmpty,
@@ -877,6 +926,14 @@ public final class SkylarkAttr implements SkylarkValue {
+ "<code>attr.label_list(default = [\"//a:b\", \"//a:c\"])</code>"
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = ALLOW_FILES_ARG, // bool or FileType filter
defaultValue = "None",
named = true,
@@ -958,6 +1015,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("label_list") {
public Descriptor invoke(
Object defaultList,
+ String doc,
Object allowFiles,
Object allowRules,
SkylarkList<?> providers,
@@ -1029,6 +1087,14 @@ public final class SkylarkAttr implements SkylarkValue {
+ "{\"//a:b\": \"value\", \"//a:c\": \"string\"})</code>"
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = ALLOW_FILES_ARG, // bool or FileType filter
defaultValue = "None",
named = true,
@@ -1110,6 +1176,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("label_keyed_string_dict") {
public Descriptor invoke(
Object defaultList,
+ String doc,
Object allowFiles,
Object allowRules,
SkylarkList<?> providers,
@@ -1172,6 +1239,14 @@ public final class SkylarkAttr implements SkylarkValue {
doc = DEFAULT_DOC
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -1186,7 +1261,7 @@ public final class SkylarkAttr implements SkylarkValue {
private static BuiltinFunction bool =
new BuiltinFunction("bool") {
public Descriptor invoke(
- Boolean defaultO, Boolean mandatory, FuncallExpression ast, Environment env)
+ Boolean defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
throws EvalException {
env.checkLoadingOrWorkspacePhase("attr.bool", ast.getLocation());
return createAttrDescriptor(
@@ -1218,6 +1293,14 @@ public final class SkylarkAttr implements SkylarkValue {
doc = DEFAULT_DOC
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -1232,7 +1315,7 @@ public final class SkylarkAttr implements SkylarkValue {
private static BuiltinFunction output =
new BuiltinFunction("output") {
public Descriptor invoke(
- Object defaultO, Boolean mandatory, FuncallExpression ast, Environment env)
+ Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
throws EvalException {
env.checkLoadingOrWorkspacePhase("attr.output", ast.getLocation());
return createNonconfigurableAttrDescriptor(
@@ -1263,6 +1346,14 @@ public final class SkylarkAttr implements SkylarkValue {
doc = DEFAULT_DOC
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -1292,6 +1383,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("output_list") {
public Descriptor invoke(
SkylarkList defaultList,
+ String doc,
Boolean mandatory,
Boolean nonEmpty,
Boolean allowEmpty,
@@ -1334,6 +1426,14 @@ public final class SkylarkAttr implements SkylarkValue {
doc = DEFAULT_DOC
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
named = true,
@@ -1363,6 +1463,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("string_dict") {
public Descriptor invoke(
SkylarkDict<?, ?> defaultO,
+ String doc,
Boolean mandatory,
Boolean nonEmpty,
Boolean allowEmpty,
@@ -1406,6 +1507,14 @@ public final class SkylarkAttr implements SkylarkValue {
doc = DEFAULT_DOC
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -1435,6 +1544,7 @@ public final class SkylarkAttr implements SkylarkValue {
new BuiltinFunction("string_list_dict") {
public Descriptor invoke(
SkylarkDict<?, ?> defaultO,
+ String doc,
Boolean mandatory,
Boolean nonEmpty,
Boolean allowEmpty,
@@ -1477,6 +1587,14 @@ public final class SkylarkAttr implements SkylarkValue {
doc = DEFAULT_DOC
),
@Param(
+ name = DOC_ARG,
+ type = String.class,
+ defaultValue = "''",
+ doc = DOC_DOC,
+ named = true,
+ positional = false
+ ),
+ @Param(
name = MANDATORY_ARG,
type = Boolean.class,
defaultValue = "False",
@@ -1491,7 +1609,7 @@ public final class SkylarkAttr implements SkylarkValue {
private static BuiltinFunction license =
new BuiltinFunction("license") {
public Descriptor invoke(
- Object defaultO, Boolean mandatory, FuncallExpression ast, Environment env)
+ Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
throws EvalException {
env.checkLoadingOrWorkspacePhase("attr.license", ast.getLocation());
return createNonconfigurableAttrDescriptor(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
index ecc46a4268..a2cfcb29a7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
@@ -258,11 +258,20 @@ public class SkylarkRuleClassFunctions {
+ "<pre class=\"language-python\">data = provider()\n"
+ "d = data(x = 2, y = 3)\n"
+ "print(d.x + d.y) # prints 5</pre>",
+ parameters = {
+ @Param(
+ name = "doc",
+ type = String.class,
+ defaultValue = "''",
+ doc =
+ "A description of the provider that can be extracted by documentation generating tools."
+ )
+ },
useLocation = true
)
private static final BuiltinFunction provider =
new BuiltinFunction("provider") {
- public ClassObjectConstructor invoke(Location location) {
+ public ClassObjectConstructor invoke(String doc, Location location) {
return new SkylarkClassObjectConstructor(
"<no name>", // name is set on export.
location);
@@ -391,6 +400,12 @@ public class SkylarkRuleClassFunctions {
+ "If set, the set of toolchains this rule requires. Toolchains will be "
+ "found by checking the current platform, and provided to the rule "
+ "implementation via <code>ctx.toolchain</code>."
+ ),
+ @Param(
+ name = "doc",
+ type = String.class,
+ defaultValue = "''",
+ doc = "A description of the rule that can be extracted by documentation generating tools."
)
},
useAst = true,
@@ -411,6 +426,7 @@ public class SkylarkRuleClassFunctions {
SkylarkList hostFragments,
Boolean skylarkTestable,
SkylarkList<String> toolchains,
+ String doc,
FuncallExpression ast,
Environment funcallEnv)
throws EvalException, ConversionException {
@@ -605,6 +621,12 @@ public class SkylarkRuleClassFunctions {
+ "If set, the set of toolchains this rule requires. Toolchains will be "
+ "found by checking the current platform, and provided to the rule "
+ "implementation via <code>ctx.toolchain</code>."
+ ),
+ @Param(
+ name = "doc",
+ type = String.class,
+ defaultValue = "''",
+ doc = "A description of the aspect that can be extracted by documentation generating tools."
)
},
useEnvironment = true,
@@ -621,6 +643,7 @@ public class SkylarkRuleClassFunctions {
SkylarkList fragments,
SkylarkList hostFragments,
SkylarkList<String> toolchains,
+ String doc,
FuncallExpression ast,
Environment funcallEnv)
throws EvalException {
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 a0f6316c9b..b3d614816d 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
@@ -493,7 +493,7 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase {
public void testAttrDefaultValueBadType() throws Exception {
checkErrorContains(
"argument 'default' has type 'int', but should be 'string'\n"
- + "in call to builtin function attr.string(*, default, mandatory, values)",
+ + "in call to builtin function attr.string(*, default, doc, mandatory, values)",
"attr.string(default = 1)");
}
@@ -559,6 +559,34 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase {
}
@Test
+ public void testAttrDoc() throws Exception {
+ // We don't actually store the doc in the attr definition; right now it's just meant to be
+ // extracted by documentation generating tools. So we don't have anything to assert and we just
+ // verify that no exceptions were thrown from building them.
+ buildAttribute("a1", "attr.bool(doc='foo')");
+ buildAttribute("a2", "attr.int(doc='foo')");
+ buildAttribute("a3", "attr.int_list(doc='foo')");
+ buildAttribute("a4", "attr.label(doc='foo')");
+ buildAttribute("a5", "attr.label_keyed_string_dict(doc='foo')");
+ buildAttribute("a6", "attr.label_list(doc='foo')");
+ buildAttribute("a7", "attr.license(doc='foo')");
+ buildAttribute("a8", "attr.output(doc='foo')");
+ buildAttribute("a9", "attr.output_list(doc='foo')");
+ buildAttribute("a10", "attr.string(doc='foo')");
+ buildAttribute("a11", "attr.string_dict(doc='foo')");
+ buildAttribute("a12", "attr.string_list(doc='foo')");
+ buildAttribute("a13", "attr.string_list_dict(doc='foo')");
+ }
+
+ @Test
+ public void testAttrDocValueBadType() throws Exception {
+ checkErrorContains(
+ "argument 'doc' has type 'int', but should be 'string'\n"
+ + "in call to builtin function attr.string(*, default, doc, mandatory, values)",
+ "attr.string(doc = 1)");
+ }
+
+ @Test
public void testRuleImplementation() throws Exception {
evalAndExport("def impl(ctx): return None", "rule1 = rule(impl)");
RuleClass c = ((RuleFunction) lookup("rule1")).getRuleClass();
@@ -566,10 +594,15 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase {
}
@Test
+ public void testRuleDoc() throws Exception {
+ evalAndExport("def impl(ctx): return None", "rule1 = rule(impl, doc='foo')");
+ }
+
+ @Test
public void testLateBoundAttrWorksWithOnlyLabel() throws Exception {
checkEvalError(
"argument 'default' has type 'function', but should be 'string'\n"
- + "in call to builtin function attr.string(*, default, mandatory, values)",
+ + "in call to builtin function attr.string(*, default, doc, mandatory, values)",
"def attr_value(cfg): return 'a'",
"attr.string(default=attr_value)");
}
@@ -689,6 +722,14 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase {
}
@Test
+ public void testRuleBadTypeForDoc() throws Exception {
+ registerDummyUserDefinedFunction();
+ checkErrorContains(
+ "argument 'doc' has type 'int', but should be 'string'",
+ "rule(impl, doc = 1)");
+ }
+
+ @Test
public void testLabel() throws Exception {
Object result = evalRuleClassCode("Label('//foo/foo:foo')");
assertThat(result).isInstanceOf(Label.class);
@@ -1209,7 +1250,6 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase {
}
@Test
-
public void structsAsDeclaredProvidersTest() throws Exception {
evalAndExport(
"data = struct(x = 1)"
@@ -1222,6 +1262,18 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase {
}
@Test
+ public void declaredProvidersDoc() throws Exception {
+ evalAndExport("data1 = provider(doc='foo')");
+ }
+
+ @Test
+ public void declaredProvidersBadTypeForDoc() throws Exception {
+ checkErrorContains(
+ "argument 'doc' has type 'int', but should be 'string'",
+ "provider(doc = 1)");
+ }
+
+ @Test
public void aspectAllAttrs() throws Exception {
evalAndExport(
"def _impl(target, ctx):",
@@ -1348,6 +1400,22 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase {
+ " Should be list of providers, but got int. ");
}
+ @Test
+ public void aspectDoc() throws Exception {
+ evalAndExport(
+ "def _impl(target, ctx):",
+ " pass",
+ "my_aspect = aspect(_impl, doc='foo')");
+ }
+
+ @Test
+ public void aspectBadTypeForDoc() throws Exception {
+ registerDummyUserDefinedFunction();
+ checkErrorContains(
+ "argument 'doc' has type 'int', but should be 'string'",
+ "aspect(impl, doc = 1)");
+ }
+
@Test