aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2016-06-14 10:28:31 +0000
committerGravatar Yue Gan <yueg@google.com>2016-06-14 11:03:49 +0000
commit014388cec904f391ce8e54d323c9e9ce527ca0eb (patch)
tree82b78efc9ae2aea2eab48d72e70c5352e77a2b25 /src
parent3dd7f269bbfd463435bfc6af3424626f15f8850c (diff)
Use only one list of parameters for SkylarkSignature
Optional and named parameters are now specified using `defaultValue` and `named` (and `positional`). The new structure allow for parameters that are both named and positional (which was forbidden before). This new structure will be used to give the @SkylarkCallable annotation the possibility to provide named and default arguments. It should be a functional no-op for Bazel users. -- MOS_MIGRATED_REVID=124821455
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/docgen/skylark/SkylarkBuiltinMethodDoc.java5
-rw-r--r--src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java15
-rw-r--r--src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryModule.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java33
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java31
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java223
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java91
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java17
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkSignature.java29
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java229
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java41
-rw-r--r--src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java10
17 files changed, 475 insertions, 342 deletions
diff --git a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkBuiltinMethodDoc.java b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkBuiltinMethodDoc.java
index 94802041f3..eaa1828857 100644
--- a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkBuiltinMethodDoc.java
+++ b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkBuiltinMethodDoc.java
@@ -81,10 +81,7 @@ public final class SkylarkBuiltinMethodDoc extends SkylarkMethodDoc {
}
private void processParams() {
- processParams(adjustedMandatoryPositionals(annotation));
- processParams(annotation.optionalPositionals());
- processParams(annotation.optionalNamedOnly());
- processParams(annotation.mandatoryNamedOnly());
+ processParams(adjustedParameters(annotation));
if (!annotation.extraPositionals().name().isEmpty()) {
this.params.add(new SkylarkParamDoc(this, annotation.extraPositionals()));
}
diff --git a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
index 691c521d2b..3f4f5ae143 100644
--- a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
+++ b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
@@ -72,16 +72,19 @@ abstract class SkylarkDoc {
}
}
- // Elide self parameter from mandatoryPositionals in class methods.
- protected static Param[] adjustedMandatoryPositionals(SkylarkSignature annotation) {
- Param[] mandatoryPos = annotation.mandatoryPositionals();
- if (mandatoryPos.length > 0
+ // Elide self parameter from parameters in class methods.
+ protected static Param[] adjustedParameters(SkylarkSignature annotation) {
+ Param[] params = annotation.parameters();
+ if (params.length > 0
+ && !params[0].named()
+ && (params[0].defaultValue() != null && params[0].defaultValue().isEmpty())
+ && params[0].positional()
&& annotation.objectType() != Object.class
&& !FuncallExpression.isNamespace(annotation.objectType())) {
// Skip the self parameter, which is the first mandatory positional parameter.
- return Arrays.copyOfRange(mandatoryPos, 1, mandatoryPos.length);
+ return Arrays.copyOfRange(params, 1, params.length);
} else {
- return mandatoryPos;
+ return params;
}
}
}
diff --git a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java
index 6356a56267..870a10d43a 100644
--- a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java
+++ b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java
@@ -76,25 +76,22 @@ abstract class SkylarkMethodDoc extends SkylarkDoc {
protected String getSignature(String objectName, SkylarkSignature method) {
List<String> argList = new ArrayList<>();
- for (Param param : adjustedMandatoryPositionals(method)) {
- argList.add(param.name());
+ boolean named = false;
+ for (Param param : adjustedParameters(method)) {
+ if (param.named() && !param.positional() && !named) {
+ named = true;
+ if (!method.extraPositionals().name().isEmpty()) {
+ argList.add("*" + method.extraPositionals().name());
+ }
+ if (!argList.isEmpty()) {
+ argList.add("*");
+ }
+ }
+ argList.add(formatParameter(param));
}
- for (Param param : method.optionalPositionals()) {
- argList.add(formatOptionalParameter(param));
- }
- if (!method.extraPositionals().name().isEmpty()) {
+ if (!named && !method.extraPositionals().name().isEmpty()) {
argList.add("*" + method.extraPositionals().name());
}
- if (!argList.isEmpty() && method.extraPositionals().name().isEmpty()
- && (method.optionalNamedOnly().length > 0 || method.mandatoryNamedOnly().length > 0)) {
- argList.add("*");
- }
- for (Param param : method.mandatoryNamedOnly()) {
- argList.add(param.name());
- }
- for (Param param : method.optionalNamedOnly()) {
- argList.add(formatOptionalParameter(param));
- }
if (!method.extraKeywords().name().isEmpty()) {
argList.add("**" + method.extraKeywords().name());
}
@@ -108,9 +105,13 @@ abstract class SkylarkMethodDoc extends SkylarkDoc {
}
}
- private String formatOptionalParameter(Param param) {
+ private String formatParameter(Param param) {
String defaultValue = param.defaultValue();
- return String.format("%s=%s", param.name(),
- (defaultValue == null || defaultValue.isEmpty()) ? "&hellip;" : defaultValue);
+ String name = param.name();
+ if (defaultValue == null || !defaultValue.isEmpty()) {
+ return String.format("%s=%s", name, defaultValue == null ? "&hellip;" : defaultValue);
+ } else {
+ return name;
+ }
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryModule.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryModule.java
index 72124a5300..5104b02d10 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryModule.java
@@ -54,7 +54,7 @@ public class SkylarkRepositoryModule {
"Creates a new repository rule. Store it in a global value, so that it can be loaded and "
+ "called from the WORKSPACE file.",
returnType = BaseFunction.class,
- mandatoryPositionals = {
+ parameters = {
@Param(
name = "implementation",
type = BaseFunction.class,
@@ -62,9 +62,7 @@ public class SkylarkRepositoryModule {
"the function implementing this rule, has to have exactly one parameter: "
+ "<code><a href=\"repository_ctx.html\">repository_ctx</a></code>. The function "
+ "is called during loading phase for each instance of the rule."
- )
- },
- optionalNamedOnly = {
+ ),
@Param(
name = "attrs",
type = SkylarkDict.class,
@@ -76,7 +74,9 @@ public class SkylarkRepositoryModule {
+ "module). Attributes starting with <code>_</code> are private, and can be "
+ "used to add an implicit dependency on a label to a file (a repository "
+ "rule cannot depend on a generated artifact). The attribute "
- + "<code>name</code> is implicitly added and must not be specified."
+ + "<code>name</code> is implicitly added and must not be specified.",
+ named = true,
+ positional = false
),
@Param(
name = "local",
@@ -84,7 +84,9 @@ public class SkylarkRepositoryModule {
defaultValue = "False",
doc =
"Indicate that this rule fetches everything from the local system and should be "
- + "reevaluated at every fetch."
+ + "reevaluated at every fetch.",
+ named = true,
+ positional = false
)
},
useAst = true,
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index c53b5f8f1c..972f7486bf 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -488,10 +488,9 @@ public final class PackageFactory {
*/
@SkylarkSignature(name = "glob", objectType = Object.class, returnType = SkylarkList.class,
doc = "Returns a list of files that match glob search pattern",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "include", type = SkylarkList.class, generic1 = String.class,
- doc = "a list of strings specifying patterns of files to include.")},
- optionalPositionals = {
+ doc = "a list of strings specifying patterns of files to include."),
@Param(name = "exclude", type = SkylarkList.class, generic1 = String.class,
defaultValue = "[]",
doc = "a list of strings specifying patterns of files to exclude."),
@@ -581,7 +580,7 @@ public final class PackageFactory {
*/
@SkylarkSignature(name = "mocksubinclude", returnType = Runtime.NoneType.class,
doc = "implement the mocksubinclude function emitted by the PythonPreprocessor",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "label", type = Object.class,
doc = "a label designator."),
@Param(name = "path", type = String.class,
@@ -630,13 +629,15 @@ public final class PackageFactory {
@SkylarkSignature(name = "environment_group", returnType = Runtime.NoneType.class,
doc = "Defines a set of related environments that can be tagged onto rules to prevent"
+ "incompatible rules from depending on each other.",
- mandatoryNamedOnly = {
- @Param(name = "name", type = String.class,
+ parameters = {
+ @Param(name = "name", type = String.class, positional = false, named = true,
doc = "The name of the rule."),
// Both parameter below are lists of label designators
@Param(name = "environments", type = SkylarkList.class, generic1 = Object.class,
+ positional = false, named = true,
doc = "A list of Labels for the environments to be grouped, from the same package."),
@Param(name = "defaults", type = SkylarkList.class, generic1 = Object.class,
+ positional = false, named = true,
doc = "A list of Labels.")}, // TODO(bazel-team): document what that is
documented = false, useLocation = true)
private static final BuiltinFunction.Factory newEnvironmentGroupFunction =
@@ -672,10 +673,9 @@ public final class PackageFactory {
*/
@SkylarkSignature(name = "exports_files", returnType = Runtime.NoneType.class,
doc = "Declare a set of files as exported",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "srcs", type = SkylarkList.class, generic1 = String.class,
- doc = "A list of strings, the names of the files to export.")},
- optionalPositionals = {
+ doc = "A list of strings, the names of the files to export."),
// TODO(blaze-team): make it possible to express a list of label designators,
// i.e. a java List or Skylark list of Label or String.
@Param(name = "visibility", type = SkylarkList.class, noneable = true,
@@ -774,7 +774,7 @@ public final class PackageFactory {
+ "require a notice.</dd>"
+ "<dt><code>unencumbered</code></dt><dd>Public domain, free for any use.</dd>"
+ "</dl>",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "license_strings", type = SkylarkList.class, generic1 = String.class,
doc = "A list of strings, the names of the licenses used.")},
documented = false, useLocation = true)
@@ -806,7 +806,7 @@ public final class PackageFactory {
// and share the functions with the native package... which requires unifying the List types.
@SkylarkSignature(name = "distribs", returnType = Runtime.NoneType.class,
doc = "Declare the distribution(s) for the code in the current package.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "distribution_strings", type = Object.class,
doc = "The distributions.")},
documented = false, useLocation = true)
@@ -831,16 +831,19 @@ public final class PackageFactory {
@SkylarkSignature(name = "package_group", returnType = Runtime.NoneType.class,
doc = "Declare a set of files as exported",
- mandatoryNamedOnly = {
- @Param(name = "name", type = String.class,
- doc = "The name of the rule.")},
- optionalNamedOnly = {
+ parameters = {
+ @Param(name = "name", type = String.class, named = true, positional = false,
+ doc = "The name of the rule."),
@Param(name = "packages", type = SkylarkList.class, generic1 = String.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = "A list of Strings specifying the packages grouped."),
// java list or list of label designators: Label or String
@Param(name = "includes", type = SkylarkList.class, generic1 = Object.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = "A list of Label specifiers for the files to include.")},
documented = false, useAst = true, useEnvironment = true)
private static final BuiltinFunction.Factory newPackageGroupFunction =
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
index 19fc62ab3a..31208ba212 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
@@ -51,16 +51,14 @@ public class SkylarkNativeModule {
+ "(default <code>[]</code>).</li></ul>\n"
+ "If the <code>exclude_directories</code> argument is enabled (set to <code>1</code>),"
+ " files of type directory will be omitted from the results (default <code>1</code>).",
- mandatoryPositionals = {
+ parameters = {
@Param(
name = "include",
type = SkylarkList.class,
generic1 = String.class,
defaultValue = "[]",
doc = "The list of glob patterns to include."
- )
- },
- optionalPositionals = {
+ ),
@Param(
name = "exclude",
type = SkylarkList.class,
@@ -101,7 +99,7 @@ public class SkylarkNativeModule {
doc =
"Returns a dictionary representing the attributes of a previously defined rule, "
+ "or None if the rule does not exist.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "name", type = String.class, doc = "The name of the rule.")
},
useAst = true,
@@ -133,7 +131,7 @@ public class SkylarkNativeModule {
"Returns a dict containing all the rules instantiated so far. "
+ "The map key is the name of the rule. The map value is equivalent to the "
+ "existing_rule output for that rule.",
- mandatoryPositionals = {},
+ parameters = {},
useAst = true,
useEnvironment = true
)
@@ -151,15 +149,14 @@ public class SkylarkNativeModule {
returnType = Runtime.NoneType.class,
doc = "This function defines a set of packages and assigns a label to the group. "
+ "The label can be referenced in <code>visibility</code> attributes.",
- mandatoryNamedOnly = {
- @Param(name = "name", type = String.class,
- doc = "The unique name for this rule.")},
- optionalNamedOnly = {
+ parameters = {
+ @Param(name = "name", type = String.class, named = true, positional = false,
+ doc = "The unique name for this rule."),
@Param(name = "packages", type = SkylarkList.class, generic1 = String.class,
- defaultValue = "[]",
+ defaultValue = "[]", named = true, positional = false,
doc = "A complete enumeration of packages in this group."),
@Param(name = "includes", type = SkylarkList.class, generic1 = String.class,
- defaultValue = "[]",
+ defaultValue = "[]", named = true, positional = false,
doc = "Other package groups that are included in this one.")},
useAst = true, useEnvironment = true)
private static final BuiltinFunction packageGroup = new BuiltinFunction("package_group") {
@@ -174,18 +171,16 @@ public class SkylarkNativeModule {
returnType = Runtime.NoneType.class,
doc = "Specifies a list of files belonging to this package that are exported to other "
+ "packages but not otherwise mentioned.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "srcs", type = SkylarkList.class, generic1 = String.class,
- doc = "The list of files to export.")},
- optionalPositionals = {
+ doc = "The list of files to export."),
// TODO(bazel-team): make it possible to express the precise type ListOf(LabelDesignator)
- @Param(name = "visibility", type = SkylarkList.class,
- noneable = true,
+ @Param(name = "visibility", type = SkylarkList.class, defaultValue = "None", noneable = true,
doc = "A visibility declaration can to be specified. The files will be visible to the "
+ "targets specified. If no visibility is specified, the files will be visible to "
+ "every package."),
@Param(name = "licenses", type = SkylarkList.class, generic1 = String.class, noneable = true,
- doc = "Licenses to be specified.")},
+ defaultValue = "None", doc = "Licenses to be specified.")},
useAst = true, useEnvironment = true)
private static final BuiltinFunction exportsFiles = new BuiltinFunction("exports_files") {
public Runtime.NoneType invoke(SkylarkList srcs, Object visibility, Object licenses,
diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
index ec039c88d1..95222c68ce 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
@@ -287,7 +287,7 @@ public class WorkspaceFactory {
+ "description of the project, using underscores as separators, e.g., "
+ "github.com/bazelbuild/bazel should use com_github_bazelbuild_bazel. Names must "
+ "start with a letter and can only contain letters, numbers, and underscores.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "name", type = String.class, doc = "the name of the workspace.")
},
documented = true,
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 feb73e7043..7038b43424 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
@@ -290,21 +290,31 @@ public final class SkylarkAttr {
doc = "Creates an attribute of type int.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
+ parameters = {
@Param(
name = DEFAULT_ARG,
type = Integer.class,
defaultValue = "0",
- doc = DEFAULT_DOC
+ doc = DEFAULT_DOC,
+ named = true,
+ positional = false
),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ doc = MANDATORY_DOC,
+ named = true,
+ positional = false
),
@Param(
name = VALUES_ARG,
type = SkylarkList.class,
generic1 = Integer.class,
defaultValue = "[]",
- doc = VALUES_DOC
+ doc = VALUES_DOC,
+ named = true,
+ positional = false
)
},
useAst = true,
@@ -335,21 +345,31 @@ public final class SkylarkAttr {
doc = "Creates an attribute of type <a href=\"string.html\">string</a>.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
+ parameters = {
@Param(
name = DEFAULT_ARG,
type = String.class,
defaultValue = "''",
- doc = DEFAULT_DOC
+ doc = DEFAULT_DOC,
+ named = true,
+ positional = false
),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ doc = MANDATORY_DOC,
+ named = true,
+ positional = false
),
@Param(
name = VALUES_ARG,
type = SkylarkList.class,
generic1 = String.class,
defaultValue = "[]",
- doc = VALUES_DOC
+ doc = VALUES_DOC,
+ named = true,
+ positional = false
)
},
useAst = true,
@@ -384,13 +404,15 @@ public final class SkylarkAttr {
+ "<a href=\"../rules.html#private-attributes\">make the attribute private</a>.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
+ parameters = {
@Param(
name = DEFAULT_ARG,
type = Label.class,
callbackEnabled = true,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc =
DEFAULT_DOC
+ " Use the <a href=\"globals.html#Label\"><code>Label</code></a> function to "
@@ -401,15 +423,31 @@ public final class SkylarkAttr {
name = EXECUTABLE_ARG,
type = Boolean.class,
defaultValue = "False",
+ named = true,
+ positional = false,
doc = EXECUTABLE_DOC
),
- @Param(name = ALLOW_FILES_ARG, defaultValue = "False", doc = ALLOW_FILES_DOC),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ @Param(
+ name = ALLOW_FILES_ARG,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = ALLOW_FILES_DOC
+ ),
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = MANDATORY_DOC
),
@Param(
name = PROVIDERS_ARG,
type = SkylarkList.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = PROVIDERS_DOC
),
@Param(
@@ -418,12 +456,16 @@ public final class SkylarkAttr {
generic1 = String.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc = ALLOW_RULES_DOC
),
@Param(
name = SINGLE_FILE_ARG,
type = Boolean.class,
defaultValue = "False",
+ named = true,
+ positional = false,
doc =
"if True, the label must correspond to a single <a href=\"file.html\">File</a>. "
+ "Access it through <code>ctx.file.&lt;attribute_name&gt;</code>."
@@ -433,6 +475,8 @@ public final class SkylarkAttr {
type = ConfigurationTransition.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc = CONFIGURATION_DOC
)
},
@@ -485,7 +529,7 @@ public final class SkylarkAttr {
+ "<a href=\"string.html\">strings</a>.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalPositionals = {
+ parameters = {
@Param(
name = DEFAULT_ARG,
type = SkylarkList.class,
@@ -531,7 +575,7 @@ public final class SkylarkAttr {
doc = "Creates an attribute which is a <a href=\"list.html\">list</a> of ints",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalPositionals = {
+ parameters = {
@Param(
name = DEFAULT_ARG,
type = SkylarkList.class,
@@ -580,13 +624,15 @@ public final class SkylarkAttr {
+ "See <a href=\"attr.html#label\">label</a> for more information.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
+ parameters = {
@Param(
name = DEFAULT_ARG,
type = SkylarkList.class,
generic1 = Label.class,
callbackEnabled = true,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc =
DEFAULT_DOC
+ " Use the <a href=\"globals.html#Label\"><code>Label</code></a> function to "
@@ -596,6 +642,8 @@ public final class SkylarkAttr {
@Param(
name = ALLOW_FILES_ARG, // bool or FileType filter
defaultValue = "False",
+ named = true,
+ positional = false,
doc = ALLOW_FILES_DOC
),
@Param(
@@ -604,12 +652,16 @@ public final class SkylarkAttr {
generic1 = String.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc = ALLOW_RULES_DOC
),
@Param(
name = PROVIDERS_ARG,
type = SkylarkList.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = PROVIDERS_DOC
),
@Param(
@@ -617,17 +669,31 @@ public final class SkylarkAttr {
type = SkylarkList.class,
generic1 = String.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = FLAGS_DOC
),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ @Param(name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = MANDATORY_DOC
),
- @Param(name = NON_EMPTY_ARG, type = Boolean.class, defaultValue = "False", doc = NON_EMPTY_DOC
+ @Param(name = NON_EMPTY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = NON_EMPTY_DOC
),
@Param(
name = CONFIGURATION_ARG,
type = ConfigurationTransition.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc = CONFIGURATION_DOC
),
@Param(
@@ -635,6 +701,8 @@ public final class SkylarkAttr {
type = SkylarkList.class,
generic1 = SkylarkAspect.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = ASPECT_ARG_DOC
)
},
@@ -692,9 +760,22 @@ public final class SkylarkAttr {
doc = "Creates an attribute of type bool.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
- @Param(name = DEFAULT_ARG, type = Boolean.class, defaultValue = "False", doc = DEFAULT_DOC),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ parameters = {
+ @Param(
+ name = DEFAULT_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = DEFAULT_DOC
+ ),
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = MANDATORY_DOC
)
},
useAst = true,
@@ -723,15 +804,23 @@ public final class SkylarkAttr {
+ "generates the file.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
+ parameters = {
@Param(
name = DEFAULT_ARG,
type = Label.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc = DEFAULT_DOC
),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = MANDATORY_DOC
)
},
useAst = true,
@@ -759,17 +848,31 @@ public final class SkylarkAttr {
+ "See <a href=\"attr.html#output\">output</a> for more information.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
+ parameters = {
@Param(
name = DEFAULT_ARG,
type = SkylarkList.class,
generic1 = Label.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = DEFAULT_DOC
),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = MANDATORY_DOC
),
- @Param(name = NON_EMPTY_ARG, type = Boolean.class, defaultValue = "False", doc = NON_EMPTY_DOC
+ @Param(
+ name = NON_EMPTY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = NON_EMPTY_DOC
)
},
useAst = true,
@@ -806,11 +909,30 @@ public final class SkylarkAttr {
+ "<a href=\"string.html\">string</a> to <a href=\"string.html\">string</a>.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
- @Param(name = DEFAULT_ARG, type = SkylarkDict.class, defaultValue = "{}", doc = DEFAULT_DOC),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ parameters = {
+ @Param(
+ name = DEFAULT_ARG,
+ type = SkylarkDict.class,
+ named = true,
+ positional = false,
+ defaultValue = "{}",
+ doc = DEFAULT_DOC
),
- @Param(name = NON_EMPTY_ARG, type = Boolean.class, defaultValue = "False", doc = NON_EMPTY_DOC
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ named = true,
+ positional = false,
+ defaultValue = "False",
+ doc = MANDATORY_DOC
+ ),
+ @Param(
+ name = NON_EMPTY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = NON_EMPTY_DOC
)
},
useAst = true,
@@ -842,11 +964,30 @@ public final class SkylarkAttr {
+ "<a href=\"string.html\">string</a>.",
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
- @Param(name = DEFAULT_ARG, type = SkylarkDict.class, defaultValue = "{}", doc = DEFAULT_DOC),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ parameters = {
+ @Param(
+ name = DEFAULT_ARG,
+ type = SkylarkDict.class,
+ defaultValue = "{}",
+ named = true,
+ positional = false,
+ doc = DEFAULT_DOC
),
- @Param(name = NON_EMPTY_ARG, type = Boolean.class, defaultValue = "False", doc = NON_EMPTY_DOC
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = MANDATORY_DOC
+ ),
+ @Param(
+ name = NON_EMPTY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = NON_EMPTY_DOC
)
},
useAst = true,
@@ -877,10 +1018,22 @@ public final class SkylarkAttr {
// TODO(bazel-team): Implement proper license support for Skylark.
objectType = SkylarkAttr.class,
returnType = Descriptor.class,
- optionalNamedOnly = {
+ parameters = {
// TODO(bazel-team): ensure this is the correct default value
- @Param(name = DEFAULT_ARG, defaultValue = "None", noneable = true, doc = DEFAULT_DOC),
- @Param(name = MANDATORY_ARG, type = Boolean.class, defaultValue = "False", doc = MANDATORY_DOC
+ @Param(
+ name = DEFAULT_ARG,
+ defaultValue = "None",
+ noneable = true,
+ named = true,
+ positional = false,
+ doc = DEFAULT_DOC),
+ @Param(
+ name = MANDATORY_ARG,
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = MANDATORY_DOC
)
},
useAst = true,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java
index f2b6ef08b4..8e107b93a3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java
@@ -38,7 +38,7 @@ public class SkylarkCommandLine {
returnType = String.class,
doc = "Creates a single command line argument joining the paths of a set "
+ "of files on the separator string.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "separator", type = String.class, doc = "the separator string to join on"),
@Param(name = "files", type = SkylarkNestedSet.class, generic1 = Artifact.class,
doc = "the files to concatenate")})
@@ -55,7 +55,7 @@ public class SkylarkCommandLine {
doc = "Transforms a set of files to a list of strings using the template string.",
objectType = SkylarkCommandLine.class,
returnType = MutableList.class,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "items", type = SkylarkNestedSet.class, generic1 = Artifact.class,
doc = "The set of structs to transform."),
@Param(name = "template", type = String.class,
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 62b1f35c86..6a8710189f 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
@@ -234,14 +234,12 @@ public class SkylarkRuleClassFunctions {
"Creates a new rule. Store it in a global value, so that it can be loaded and called "
+ "from BUILD files.",
returnType = BaseFunction.class,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "implementation", type = BaseFunction.class,
doc = "the function implementing this rule, must have exactly one parameter: "
+ "<a href=\"ctx.html\">ctx</a>. The function is called during the analysis phase "
+ "for each instance of the rule. It can access the attributes provided by the user. "
- + "It must create actions to generate all the declared outputs.")
- },
- optionalPositionals = {
+ + "It must create actions to generate all the declared outputs."),
@Param(name = "test", type = Boolean.class, defaultValue = "False",
doc = "Whether this rule is a test rule. "
+ "If True, the rule must end with <code>_test</code> (otherwise it must not), "
@@ -368,7 +366,7 @@ public class SkylarkRuleClassFunctions {
@SkylarkSignature(name = "aspect", doc =
"Creates a new aspect. The result of this function must be stored in a global value.",
returnType = SkylarkAspect.class,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "implementation", type = BaseFunction.class,
doc = "the function implementing this aspect. Must have two parameters: "
+ "<a href=\"Target.html\">Target</a> (the target to which the aspect is applied) and "
@@ -376,8 +374,6 @@ public class SkylarkRuleClassFunctions {
+ " field. The function is called during the analysis phase for each application of "
+ "an aspect to a target."
),
- },
- optionalPositionals = {
@Param(name = "attr_aspects", type = SkylarkList.class, generic1 = String.class,
defaultValue = "[]",
doc = "List of attribute names. The aspect propagates along dependencies specified by "
@@ -645,12 +641,14 @@ public class SkylarkRuleClassFunctions {
+ "The argument must refer to an absolute label. "
+ "Example: <br><pre class=language-python>Label(\"//tools:default\")</pre>",
returnType = Label.class,
- mandatoryPositionals = {@Param(name = "label_string", type = String.class,
- doc = "the label string")},
- optionalNamedOnly = {@Param(
+ parameters = {@Param(name = "label_string", type = String.class,
+ doc = "the label string"),
+ @Param(
name = "relative_to_caller_repository",
type = Boolean.class,
defaultValue = "False",
+ named = true,
+ positional = false,
doc = "whether the label should be resolved relative to the label of the file this "
+ "function is called from.")},
useLocation = true,
@@ -684,7 +682,7 @@ public class SkylarkRuleClassFunctions {
+ "files ending with .cc or .cpp, use: "
+ "<pre class=language-python>FileType([\".cc\", \".cpp\"])</pre>",
returnType = SkylarkFileType.class,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "types", type = SkylarkList.class, generic1 = String.class, defaultValue = "[]",
doc = "a list of the accepted file extensions")})
private static final BuiltinFunction fileType = new BuiltinFunction("FileType") {
@@ -709,7 +707,7 @@ public class SkylarkRuleClassFunctions {
+ "struct(key=struct(inner_key=struct(inner_inner_key='text'))).to_proto()\n"
+ "# key {\n# inner_key {\n# inner_inner_key: \"text\"\n# }\n# }\n</pre>",
objectType = SkylarkClassObject.class, returnType = String.class,
- mandatoryPositionals = {
+ parameters = {
// TODO(bazel-team): shouldn't we accept any ClassObject?
@Param(name = "self", type = SkylarkClassObject.class,
doc = "this struct")},
@@ -793,7 +791,7 @@ public class SkylarkRuleClassFunctions {
+ "struct(key=struct(inner_key=struct(inner_inner_key='text'))).to_json()\n"
+ "# {\"key\":{\"inner_key\":{\"inner_inner_key\":\"text\"}}}\n</pre>",
objectType = SkylarkClassObject.class, returnType = String.class,
- mandatoryPositionals = {
+ parameters = {
// TODO(bazel-team): shouldn't we accept any ClassObject?
@Param(name = "self", type = SkylarkClassObject.class,
doc = "this struct")},
@@ -858,7 +856,7 @@ public class SkylarkRuleClassFunctions {
documented = false, // TODO(dslomov): document.
objectType = TransitiveInfoCollection.class,
returnType = SkylarkNestedSet.class,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = TransitiveInfoCollection.class, doc =
"this target"
),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
index 18515ffa27..ac2ae4e300 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
@@ -98,29 +98,31 @@ public class SkylarkRuleImplementationFunctions {
+ "variable expansion.",
objectType = SkylarkRuleContext.class,
returnType = Runtime.NoneType.class,
- mandatoryPositionals = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This RuleContext.")
- },
- mandatoryNamedOnly = {
+ parameters = {
+ @Param(name = "self", type = SkylarkRuleContext.class, doc = "This RuleContext."),
@Param(
name = "outputs",
type = SkylarkList.class,
generic1 = Artifact.class,
+ named = true,
+ positional = false,
doc = "list of the output files of the action"
- )
- },
- optionalNamedOnly = {
+ ),
@Param(
name = "inputs",
type = SkylarkList.class,
generic1 = Artifact.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = "list of the input files of the action"
),
@Param(
name = "executable",
type = Object.class, // File or PathFragment or None
defaultValue = "None",
+ named = true,
+ positional = false,
doc = "the executable file to be called by the action"
),
@Param(
@@ -128,6 +130,8 @@ public class SkylarkRuleImplementationFunctions {
type = SkylarkList.class,
generic1 = String.class,
defaultValue = "[]",
+ named = true,
+ positional = false,
doc = "command line arguments of the action"
),
@Param(
@@ -135,12 +139,16 @@ public class SkylarkRuleImplementationFunctions {
type = String.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc = "a one-word description of the action, e.g. CppCompile or GoLink"
),
@Param(
name = "command",
type = Object.class, // string or ListOf(string) or NoneType
defaultValue = "None",
+ named = true,
+ positional = false,
doc =
"shell command to execute. It is usually preferable to "
+ "use <code>executable</code> instead. "
@@ -151,6 +159,8 @@ public class SkylarkRuleImplementationFunctions {
type = String.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc =
"progress message to show to the user during the build, "
+ "e.g. \"Compiling foo.cc to create foo.o\""
@@ -159,6 +169,8 @@ public class SkylarkRuleImplementationFunctions {
name = "use_default_shell_env",
type = Boolean.class,
defaultValue = "False",
+ named = true,
+ positional = false,
doc = "whether the action should use the built in shell environment or not"
),
@Param(
@@ -166,6 +178,8 @@ public class SkylarkRuleImplementationFunctions {
type = SkylarkDict.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc = "sets the dictionary of environment variables"
),
@Param(
@@ -173,6 +187,8 @@ public class SkylarkRuleImplementationFunctions {
type = SkylarkDict.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc =
"information for scheduling the action."
+ " See [tags](/docs/be/common-definitions.html#common.tags) for useful keys."
@@ -182,6 +198,8 @@ public class SkylarkRuleImplementationFunctions {
type = SkylarkDict.class,
noneable = true,
defaultValue = "None",
+ named = true,
+ positional = false,
doc =
"sets the map of input manifests files; "
+ "they are typically generated by resolve_command"
@@ -335,11 +353,9 @@ public class SkylarkRuleImplementationFunctions {
+ "of their target file(s). Currently, the algorithm uses output, srcs, deps, "
+ "tools and data attributes for looking up mappings from label to locations.",
objectType = SkylarkRuleContext.class, returnType = String.class,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkRuleContext.class, doc = "this context"),
@Param(name = "input", type = String.class, doc = "string to be expanded"),
- },
- optionalPositionals = {
@Param(name = "targets", type = SkylarkList.class,
generic1 = AbstractConfiguredTarget.class, defaultValue = "[]",
doc = "list of targets for additional lookup information"),
@@ -382,11 +398,10 @@ public class SkylarkRuleImplementationFunctions {
doc = "Creates a file write action.",
objectType = SkylarkRuleContext.class,
returnType = Runtime.NoneType.class,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkRuleContext.class, doc = "this context"),
@Param(name = "output", type = Artifact.class, doc = "the output file"),
- @Param(name = "content", type = String.class, doc = "the contents of the file")},
- optionalPositionals = {
+ @Param(name = "content", type = String.class, doc = "the contents of the file"),
@Param(name = "executable", type = Boolean.class, defaultValue = "False",
doc = "whether the output file should be executable (default is False)")})
private static final BuiltinFunction createFileWriteAction =
@@ -406,15 +421,12 @@ public class SkylarkRuleImplementationFunctions {
"Creates an empty action that neither executes a command nor produces any "
+ "output, but that is useful for inserting 'extra actions'.",
objectType = SkylarkRuleContext.class, returnType = Runtime.NoneType.class,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkRuleContext.class, doc = "this context"),
- },
- mandatoryNamedOnly = {
- @Param(name = "mnemonic", type = String.class, defaultValue = "None",
+ @Param(name = "mnemonic", type = String.class, named = true, positional = false,
doc = "a one-word description of the action, e.g. CppCompile or GoLink"),
- },
- optionalNamedOnly = {
@Param(name = "inputs", type = SkylarkList.class, generic1 = Artifact.class,
+ named = true, positional = false,
defaultValue = "[]", doc = "list of the input files of the action"),
})
private static final BuiltinFunction createEmptyAction = new BuiltinFunction("empty_action") {
@@ -454,17 +466,19 @@ public class SkylarkRuleImplementationFunctions {
doc = "Creates a template expansion action.",
objectType = SkylarkRuleContext.class,
returnType = TemplateExpansionAction.class,
- mandatoryPositionals = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "this context")},
- mandatoryNamedOnly = {
+ parameters = {
+ @Param(name = "self", type = SkylarkRuleContext.class, doc = "this context"),
@Param(name = "template", type = Artifact.class,
+ named = true, positional = false,
doc = "the template file"),
@Param(name = "output", type = Artifact.class,
+ named = true, positional = false,
doc = "the output file"),
@Param(name = "substitutions", type = SkylarkDict.class,
- doc = "substitutions to make when expanding the template")},
- optionalNamedOnly = {
- @Param(name = "executable", type = Boolean.class,
+ named = true, positional = false,
+ doc = "substitutions to make when expanding the template"),
+ @Param(name = "executable", type = Boolean.class, defaultValue = "False",
+ named = true, positional = false,
doc = "whether the output file should be executable (default is False)")})
private static final BuiltinFunction createTemplateAction =
new BuiltinFunction("template_action", Arrays.<Object>asList(false)) {
@@ -506,9 +520,8 @@ public class SkylarkRuleImplementationFunctions {
doc = "Creates a runfiles object.",
objectType = SkylarkRuleContext.class,
returnType = Runfiles.class,
- mandatoryPositionals = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context.")},
- optionalPositionals = {
+ parameters = {
+ @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
@Param(name = "files", type = SkylarkList.class, generic1 = Artifact.class,
defaultValue = "[]", doc = "The list of files to be added to the runfiles."),
// TODO(bazel-team): If we have a memory efficient support for lazy list containing
@@ -611,32 +624,40 @@ public class SkylarkRuleImplementationFunctions {
+ "all of them suitable for passing as the same-named arguments of the ctx.action method.",
objectType = SkylarkRuleContext.class,
returnType = Tuple.class,
- mandatoryPositionals = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "this RuleContext")
- },
- optionalNamedOnly = {
+ parameters = {
+ @Param(name = "self", type = SkylarkRuleContext.class, doc = "this RuleContext"),
@Param(
name = "command",
type = String.class, // string
defaultValue = "''",
+ named = true,
+ positional = false,
doc = "command to resolve"
),
@Param(
name = "attribute",
type = String.class, // string
+ defaultValue = "None",
noneable = true,
+ named = true,
+ positional = false,
doc = "name of the associated attribute for which to issue an error, or None"
),
@Param(
name = "expand_locations",
type = Boolean.class,
defaultValue = "False",
+ named = true,
+ positional = false,
doc = "shall we expand $(location) variables?"
),
@Param(
name = "make_variables",
type = SkylarkDict.class, // dict(string, string)
noneable = true,
+ defaultValue = "None",
+ named = true,
+ positional = false,
doc = "make variables to expand, or None"
),
@Param(
@@ -644,12 +665,16 @@ public class SkylarkRuleImplementationFunctions {
defaultValue = "[]",
type = SkylarkList.class,
generic1 = TransitiveInfoCollection.class,
+ named = true,
+ positional = false,
doc = "list of tools (list of targets)"
),
@Param(
name = "label_dict",
type = SkylarkDict.class,
defaultValue = "{}",
+ named = true,
+ positional = false,
doc =
"dictionary of resolved labels and the corresponding list of Files "
+ "(a dict of Label : list of Files)"
@@ -658,6 +683,8 @@ public class SkylarkRuleImplementationFunctions {
name = "execution_requirements",
type = SkylarkDict.class,
defaultValue = "{}",
+ named = true,
+ positional = false,
doc =
"information for scheduling the action to resolve this command."
+ " See [tags](/docs/be/common-definitions.html#common.tags) for useful keys."
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
index 434010b6fe..3405fc4131 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
@@ -68,14 +68,14 @@ public class AppleSkylarkCommon {
objectType = AppleSkylarkCommon.class,
returnType = ObjcProvider.class,
doc = "Creates a new ObjcProvider instance.",
- mandatoryPositionals = {
- @Param(name = "self", type = AppleSkylarkCommon.class, doc = "The apple_common instance.")
- },
- optionalNamedOnly = {
+ parameters = {
+ @Param(name = "self", type = AppleSkylarkCommon.class, doc = "The apple_common instance."),
@Param(
name = "uses_swift",
type = Boolean.class,
defaultValue = "False",
+ named = true,
+ positional = false,
doc = "Whether this provider should enable Swift support."
)
},
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java
index 845cb27963..4bbf10ad5d 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java
@@ -67,6 +67,23 @@ public @interface Param {
*/
boolean noneable() default false;
+ /**
+ * If true, the parameter may be specified as a named parameter. For example for an integer named
+ * parameter {@code foo} of a method {@code bar}, then the method call will look like
+ * {@code foo(bar=1)}.
+ */
+ boolean named() default false;
+
+ /**
+ * If true, the parameter may be specified as a positional parameter. For example for an integer
+ * positional parameter {@code foo} of a method {@code bar}, then the method call will look like
+ * {@code foo(1)}. If {@link #named()} is {@code false}, then this will be the only way to call
+ * {@code foo}.
+ *
+ * <p>Positional arguments should comes first.
+ */
+ boolean positional() default true;
+
// TODO(bazel-team): parse the type from a single field in Skylark syntax,
// and allow a Union as "ThisType or ThatType or NoneType":
// String type() default "Object";
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkSignature.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkSignature.java
index 4fc8ad1a4f..5a12ec038f 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkSignature.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkSignature.java
@@ -23,10 +23,8 @@ import java.lang.annotation.Target;
*
* <p>Use this annotation around a {@link com.google.devtools.build.lib.syntax.BuiltinFunction} or
* a {@link com.google.devtools.build.lib.syntax.BuiltinFunction.Factory}. The annotated function
- * should expect the arguments described by {@link #parameters()},
- * {@link #optionalPositionals()}, {@link #extraPositionals()}, {@link #mandatoryNamedOnly()},
- * {@link #optionalNamedOnly()} and {@link #extraKeywords()}. It should also expect the following
- * extraneous arguments:
+ * should expect the arguments described by {@link #parameters()}, {@link #extraPositionals()},
+ * and {@link #extraKeywords()}. It should also expect the following extraneous arguments:
*
* <ul>
* <li>
@@ -60,28 +58,9 @@ public @interface SkylarkSignature {
String doc() default "";
/**
- * List of mandatory positional parameters for calling this method. These parameters have
- * to be placed first in the list of arguments when calling that method.
+ * List of parameters for calling this method. Named only parameters are expected to be last.
*/
- Param[] mandatoryPositionals() default {};
-
- /**
- * List of optional positional parameters for calling this method. These parameters have
- * to be placed before any named parameters when calling the method.
- */
- Param[] optionalPositionals() default {};
-
- /**
- * List of optional named parameters for calling this method. These parameters can be specified
- * in the list of arguments using the <code>key=value</code> format in calling the method.
- */
- Param[] optionalNamedOnly() default {};
-
- /**
- * List of mandatory named parameters for calling this method. These parameters must be specified
- * in the list of arguments using the <code>key=value</code> format in calling the method.
- */
- Param[] mandatoryNamedOnly() default {};
+ Param[] parameters() default {};
/**
* Defines a catch all positional parameters. By default, it is an error to define more
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 be0bf43ade..577755e6b4 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
@@ -101,7 +101,7 @@ public class MethodLibrary {
doc = "Returns a string in which the string elements of the argument have been "
+ "joined by this string as a separator. Example:<br>"
+ "<pre class=\"language-python\">\"|\".join([\"a\", \"b\", \"c\"]) == \"a|b|c\"</pre>",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string, a separator."),
@Param(name = "elements", type = SkylarkList.class, doc = "The objects to join.")})
private static final BuiltinFunction join = new BuiltinFunction("join") {
@@ -112,7 +112,7 @@ public class MethodLibrary {
@SkylarkSignature(name = "lower", objectType = StringModule.class, returnType = String.class,
doc = "Returns the lower case version of this string.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string, to convert to lower case.")})
private static final BuiltinFunction lower = new BuiltinFunction("lower") {
public String invoke(String self) {
@@ -122,7 +122,7 @@ public class MethodLibrary {
@SkylarkSignature(name = "upper", objectType = StringModule.class, returnType = String.class,
doc = "Returns the upper case version of this string.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string, to convert to upper case.")})
private static final BuiltinFunction upper = new BuiltinFunction("upper") {
public String invoke(String self) {
@@ -160,10 +160,8 @@ public class MethodLibrary {
+ "<pre class=\"language-python\">"
+ "\"abcba\".lstrip(\"ba\") == \"cba\""
+ "</pre",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string"),
- },
- optionalPositionals = {
@Param(
name = "chars",
type = String.class,
@@ -189,10 +187,8 @@ public class MethodLibrary {
+ "<pre class=\"language-python\">"
+ "\"abcba\".rstrip(\"ba\") == \"abc\""
+ "</pre",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string"),
- },
- optionalPositionals = {
@Param(
name = "chars",
type = String.class,
@@ -218,10 +214,8 @@ public class MethodLibrary {
+ "<pre class=\"language-python\">"
+ "\"abcba\".strip(\"ba\") == \"abc\""
+ "</pre",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string"),
- },
- optionalPositionals = {
@Param(
name = "chars",
type = String.class,
@@ -241,11 +235,10 @@ public class MethodLibrary {
doc = "Returns a copy of the string in which the occurrences "
+ "of <code>old</code> have been replaced with <code>new</code>, optionally restricting "
+ "the number of replacements to <code>maxsplit</code>.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
@Param(name = "old", type = String.class, doc = "The string to be replaced."),
- @Param(name = "new", type = String.class, doc = "The string to replace with.")},
- optionalPositionals = {
+ @Param(name = "new", type = String.class, doc = "The string to replace with."),
@Param(name = "maxsplit", type = Integer.class, noneable = true, defaultValue = "None",
doc = "The maximum number of replacements.")},
useLocation = true)
@@ -272,10 +265,9 @@ public class MethodLibrary {
returnType = MutableList.class,
doc = "Returns a list of all the words in the string, using <code>sep</code> "
+ "as the separator, optionally limiting the number of splits to <code>maxsplit</code>.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sep", type = String.class, doc = "The string to split on.")},
- optionalPositionals = {
+ @Param(name = "sep", type = String.class, doc = "The string to split on."),
@Param(name = "maxsplit", type = Integer.class, noneable = true, defaultValue = "None",
doc = "The maximum number of splits.")},
useEnvironment = true,
@@ -296,10 +288,9 @@ public class MethodLibrary {
doc = "Returns a list of all the words in the string, using <code>sep</code> "
+ "as the separator, optionally limiting the number of splits to <code>maxsplit</code>. "
+ "Except for splitting from the right, this method behaves like split().",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sep", type = String.class, doc = "The string to split on.")},
- optionalPositionals = {
+ @Param(name = "sep", type = String.class, doc = "The string to split on."),
@Param(name = "maxsplit", type = Integer.class, noneable = true,
defaultValue = "None", doc = "The maximum number of splits.")},
useEnvironment = true,
@@ -372,9 +363,8 @@ public class MethodLibrary {
doc = "Splits the input string at the first occurrence of the separator "
+ "<code>sep</code> and returns the resulting partition as a three-element "
+ "list of the form [substring_before, separator, substring_after].",
- mandatoryPositionals = {
- @Param(name = "self", type = String.class, doc = "This string.")},
- optionalPositionals = {
+ parameters = {
+ @Param(name = "self", type = String.class, doc = "This string."),
@Param(name = "sep", type = String.class,
defaultValue = "' '", doc = "The string to split on, default is space (\" \").")},
useEnvironment = true,
@@ -392,9 +382,8 @@ public class MethodLibrary {
doc = "Splits the input string at the last occurrence of the separator "
+ "<code>sep</code> and returns the resulting partition as a three-element "
+ "list of the form [substring_before, separator, substring_after].",
- mandatoryPositionals = {
- @Param(name = "self", type = String.class, doc = "This string.")},
- optionalPositionals = {
+ parameters = {
+ @Param(name = "self", type = String.class, doc = "This string."),
@Param(name = "sep", type = String.class,
defaultValue = "' '", doc = "The string to split on, default is space (\" \").")},
useEnvironment = true,
@@ -488,7 +477,7 @@ public class MethodLibrary {
doc =
"Returns a copy of the string with its first character capitalized and the rest "
+ "lowercased. This method does not support non-ascii characters.",
- mandatoryPositionals = {@Param(name = "self", type = String.class, doc = "This string.")}
+ parameters = {@Param(name = "self", type = String.class, doc = "This string.")}
)
private static final BuiltinFunction capitalize =
new BuiltinFunction("capitalize") {
@@ -508,7 +497,7 @@ public class MethodLibrary {
+ "uppercase letter while the remaining letters are lowercase. In this "
+ "context, a word means strictly a sequence of letters. This method does "
+ "not support supplementary Unicode characters.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string.")})
private static final BuiltinFunction title = new BuiltinFunction("title") {
@SuppressWarnings("unused")
@@ -552,10 +541,9 @@ public class MethodLibrary {
+ "or -1 if no such index exists, optionally restricting to "
+ "[<code>start</code>:<code>end</code>], "
+ "<code>start</code> being inclusive and <code>end</code> being exclusive.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sub", type = String.class, doc = "The substring to find.")},
- optionalPositionals = {
+ @Param(name = "sub", type = String.class, doc = "The substring to find."),
@Param(name = "start", type = Integer.class, defaultValue = "0",
doc = "Restrict to search from this position."),
@Param(name = "end", type = Integer.class, noneable = true, defaultValue = "None",
@@ -572,10 +560,9 @@ public class MethodLibrary {
+ "or -1 if no such index exists, optionally restricting to "
+ "[<code>start</code>:<code>end]</code>, "
+ "<code>start</code> being inclusive and <code>end</code> being exclusive.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sub", type = String.class, doc = "The substring to find.")},
- optionalPositionals = {
+ @Param(name = "sub", type = String.class, doc = "The substring to find."),
@Param(name = "start", type = Integer.class, defaultValue = "0",
doc = "Restrict to search from this position."),
@Param(name = "end", type = Integer.class, noneable = true, defaultValue = "None",
@@ -592,10 +579,9 @@ public class MethodLibrary {
+ "or raises an error if no such index exists, optionally restricting to "
+ "[<code>start</code>:<code>end</code>], "
+ "<code>start</code> being inclusive and <code>end</code> being exclusive.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sub", type = String.class, doc = "The substring to find.")},
- optionalPositionals = {
+ @Param(name = "sub", type = String.class, doc = "The substring to find."),
@Param(name = "start", type = Integer.class, defaultValue = "0",
doc = "Restrict to search from this position."),
@Param(name = "end", type = Integer.class, noneable = true, defaultValue = "None",
@@ -617,13 +603,12 @@ public class MethodLibrary {
+ "or raises an error if no such index exists, optionally restricting to "
+ "[<code>start</code>:<code>end]</code>, "
+ "<code>start</code> being inclusive and <code>end</code> being exclusive.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sub", type = String.class, doc = "The substring to find.")},
- optionalPositionals = {
+ @Param(name = "sub", type = String.class, doc = "The substring to find."),
@Param(name = "start", type = Integer.class, defaultValue = "0",
doc = "Restrict to search from this position."),
- @Param(name = "end", type = Integer.class, noneable = true,
+ @Param(name = "end", type = Integer.class, noneable = true, defaultValue = "None",
doc = "optional position before which to restrict to search.")},
useLocation = true)
private static final BuiltinFunction index = new BuiltinFunction("index") {
@@ -642,9 +627,8 @@ public class MethodLibrary {
doc =
"Splits the string at line boundaries ('\\n', '\\r\\n', '\\r') "
+ "and returns the result as a list.",
- mandatoryPositionals = {
- @Param(name = "self", type = String.class, doc = "This string.")},
- optionalPositionals = {
+ parameters = {
+ @Param(name = "self", type = String.class, doc = "This string."),
@Param(name = "keepends", type = Boolean.class, defaultValue = "False",
doc = "Whether the line breaks should be included in the resulting list.")})
private static final BuiltinFunction splitLines = new BuiltinFunction("splitlines") {
@@ -675,7 +659,7 @@ public class MethodLibrary {
@SkylarkSignature(name = "isalpha", objectType = StringModule.class, returnType = Boolean.class,
doc = "Returns True if all characters in the string are alphabetic ([a-zA-Z]) and there is "
+ "at least one character.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string.")})
private static final BuiltinFunction isalpha = new BuiltinFunction("isalpha") {
@SuppressWarnings("unused") // Called via Reflection
@@ -688,7 +672,7 @@ public class MethodLibrary {
doc =
"Returns True if all characters in the string are alphanumeric ([a-zA-Z0-9]) and there is "
+ "at least one character.",
- mandatoryPositionals = {@Param(name = "self", type = String.class, doc = "This string.")})
+ parameters = {@Param(name = "self", type = String.class, doc = "This string.")})
private static final BuiltinFunction isAlnum = new BuiltinFunction("isalnum") {
@SuppressWarnings("unused") // Called via Reflection
public Boolean invoke(String self) throws EvalException {
@@ -700,7 +684,7 @@ public class MethodLibrary {
doc =
"Returns True if all characters in the string are digits ([0-9]) and there is "
+ "at least one character.",
- mandatoryPositionals = {@Param(name = "self", type = String.class, doc = "This string.")})
+ parameters = {@Param(name = "self", type = String.class, doc = "This string.")})
private static final BuiltinFunction isDigit = new BuiltinFunction("isdigit") {
@SuppressWarnings("unused") // Called via Reflection
public Boolean invoke(String self) throws EvalException {
@@ -712,7 +696,7 @@ public class MethodLibrary {
doc =
"Returns True if all characters are white space characters and the string "
+ "contains at least one character.",
- mandatoryPositionals = {@Param(name = "self", type = String.class, doc = "This string.")})
+ parameters = {@Param(name = "self", type = String.class, doc = "This string.")})
private static final BuiltinFunction isSpace = new BuiltinFunction("isspace") {
@SuppressWarnings("unused") // Called via Reflection
public Boolean invoke(String self) throws EvalException {
@@ -724,7 +708,7 @@ public class MethodLibrary {
doc =
"Returns True if all cased characters in the string are lowercase and there is "
+ "at least one character.",
- mandatoryPositionals = {@Param(name = "self", type = String.class, doc = "This string.")})
+ parameters = {@Param(name = "self", type = String.class, doc = "This string.")})
private static final BuiltinFunction isLower = new BuiltinFunction("islower") {
@SuppressWarnings("unused") // Called via Reflection
public Boolean invoke(String self) throws EvalException {
@@ -737,7 +721,7 @@ public class MethodLibrary {
doc =
"Returns True if all cased characters in the string are uppercase and there is "
+ "at least one character.",
- mandatoryPositionals = {@Param(name = "self", type = String.class, doc = "This string.")})
+ parameters = {@Param(name = "self", type = String.class, doc = "This string.")})
private static final BuiltinFunction isUpper = new BuiltinFunction("isupper") {
@SuppressWarnings("unused") // Called via Reflection
public Boolean invoke(String self) throws EvalException {
@@ -751,7 +735,7 @@ public class MethodLibrary {
"Returns True if the string is in title case and it contains at least one character. "
+ "This means that every uppercase character must follow an uncased one (e.g. whitespace) "
+ "and every lowercase character must follow a cased one (e.g. uppercase or lowercase).",
- mandatoryPositionals = {@Param(name = "self", type = String.class, doc = "This string.")})
+ parameters = {@Param(name = "self", type = String.class, doc = "This string.")})
private static final BuiltinFunction isTitle = new BuiltinFunction("istitle") {
@SuppressWarnings("unused") // Called via Reflection
public Boolean invoke(String self) throws EvalException {
@@ -818,10 +802,9 @@ public class MethodLibrary {
doc = "Returns the number of (non-overlapping) occurrences of substring <code>sub</code> in "
+ "string, optionally restricting to [<code>start</code>:<code>end</code>], "
+ "<code>start</code> being inclusive and <code>end</code> being exclusive.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sub", type = String.class, doc = "The substring to count.")},
- optionalPositionals = {
+ @Param(name = "sub", type = String.class, doc = "The substring to count."),
@Param(name = "start", type = Integer.class, defaultValue = "0",
doc = "Restrict to search from this position."),
@Param(name = "end", type = Integer.class, noneable = true, defaultValue = "None",
@@ -847,10 +830,9 @@ public class MethodLibrary {
doc = "Returns True if the string ends with <code>sub</code>, "
+ "otherwise False, optionally restricting to [<code>start</code>:<code>end</code>], "
+ "<code>start</code> being inclusive and <code>end</code> being exclusive.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sub", type = String.class, doc = "The substring to check.")},
- optionalPositionals = {
+ @Param(name = "sub", type = String.class, doc = "The substring to check."),
@Param(name = "start", type = Integer.class, defaultValue = "0",
doc = "Test beginning at this position."),
@Param(name = "end", type = Integer.class, noneable = true, defaultValue = "None",
@@ -880,7 +862,7 @@ public class MethodLibrary {
+ "\"{1}, {0}\".format(2, 1) == \"1, 2\"\n"
+ "# Access by name:\n"
+ "\"x{key}x\".format(key = 2) == \"x2x\"</pre>\n",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
},
extraPositionals =
@@ -904,10 +886,9 @@ public class MethodLibrary {
doc = "Returns True if the string starts with <code>sub</code>, "
+ "otherwise False, optionally restricting to [<code>start</code>:<code>end</code>], "
+ "<code>start</code> being inclusive and <code>end</code> being exclusive.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
- @Param(name = "sub", type = String.class, doc = "The substring to check.")},
- optionalPositionals = {
+ @Param(name = "sub", type = String.class, doc = "The substring to check."),
@Param(name = "start", type = Integer.class, defaultValue = "0",
doc = "Test beginning at this position."),
@Param(name = "end", type = Integer.class, noneable = true, defaultValue = "None",
@@ -924,12 +905,10 @@ public class MethodLibrary {
name = "$slice",
objectType = String.class,
documented = false,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
@Param(name = "start", type = Object.class, doc = "start position of the slice."),
- @Param(name = "end", type = Object.class, doc = "end position of the slice.")
- },
- optionalPositionals = {
+ @Param(name = "end", type = Object.class, doc = "end position of the slice."),
@Param(name = "step", type = Integer.class, defaultValue = "1", doc = "step value.")
},
doc =
@@ -959,12 +938,10 @@ public class MethodLibrary {
objectType = MutableList.class,
returnType = MutableList.class,
documented = false,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
@Param(name = "start", type = Object.class, doc = "start position of the slice."),
- @Param(name = "end", type = Object.class, doc = "end position of the slice.")
- },
- optionalPositionals = {
+ @Param(name = "end", type = Object.class, doc = "end position of the slice."),
@Param(name = "step", type = Integer.class, defaultValue = "1", doc = "step value.")
},
doc =
@@ -989,12 +966,10 @@ public class MethodLibrary {
objectType = Tuple.class,
returnType = Tuple.class,
documented = false,
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = Tuple.class, doc = "This tuple."),
@Param(name = "start", type = Object.class, doc = "start position of the slice."),
- @Param(name = "end", type = Object.class, doc = "end position of the slice.")
- },
- optionalPositionals = {
+ @Param(name = "end", type = Object.class, doc = "end position of the slice."),
@Param(name = "step", type = Integer.class, defaultValue = "1", doc = "step value.")
},
doc =
@@ -1139,7 +1114,7 @@ public class MethodLibrary {
name = "all",
returnType = Boolean.class,
doc = "Returns true if all elements evaluate to True or if the collection is empty.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "elements", type = Object.class, doc = "A string or a collection of elements.")
},
useLocation = true
@@ -1156,7 +1131,7 @@ public class MethodLibrary {
name = "any",
returnType = Boolean.class,
doc = "Returns true if at least one element evaluates to True.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "elements", type = Object.class, doc = "A string or a collection of elements.")
},
useLocation = true
@@ -1187,7 +1162,7 @@ public class MethodLibrary {
doc =
"Sort a collection. Elements are sorted first by their type, "
+ "then by their value (in ascending order).",
- mandatoryPositionals = {@Param(name = "self", type = Object.class, doc = "This collection.")},
+ parameters = {@Param(name = "self", type = Object.class, doc = "This collection.")},
useLocation = true,
useEnvironment = true
)
@@ -1209,7 +1184,7 @@ public class MethodLibrary {
name = "reversed",
returnType = MutableList.class,
doc = "Returns a list that contains the elements of the original sequence in reversed order.",
- mandatoryPositionals = {
+ parameters = {
@Param(
name = "sequence",
type = Object.class,
@@ -1244,7 +1219,7 @@ public class MethodLibrary {
objectType = MutableList.class,
returnType = Runtime.NoneType.class,
doc = "Adds an item to the end of the list.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
@Param(name = "item", type = Object.class, doc = "Item to add at the end.")
},
@@ -1264,7 +1239,7 @@ public class MethodLibrary {
objectType = MutableList.class,
returnType = Runtime.NoneType.class,
doc = "Inserts an item at a given position.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
@Param(name = "index", type = Integer.class, doc = "The index of the given position."),
@Param(name = "item", type = Object.class, doc = "The item.")
@@ -1287,7 +1262,7 @@ public class MethodLibrary {
objectType = MutableList.class,
returnType = Runtime.NoneType.class,
doc = "Adds all items to the end of the list.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
@Param(name = "items", type = SkylarkList.class, doc = "Items to add at the end.")
},
@@ -1311,7 +1286,7 @@ public class MethodLibrary {
doc =
"Returns the index in the list of the first item whose value is x. "
+ "It is an error if there is no such item.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
@Param(name = "x", type = Object.class, doc = "The object to search.")
},
@@ -1338,7 +1313,7 @@ public class MethodLibrary {
doc =
"Removes the first item from the list whose value is x. "
+ "It is an error if there is no such item.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
@Param(name = "x", type = Object.class, doc = "The object to remove.")
},
@@ -1367,10 +1342,8 @@ public class MethodLibrary {
"Removes the item at the given position in the list, and returns it. "
+ "If no <code>index</code> is specified, "
+ "it removes and returns the last item in the list.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
- },
- optionalPositionals = {
@Param(
name = "i",
type = Integer.class,
@@ -1402,11 +1375,9 @@ public class MethodLibrary {
"Removes a <code>key</code> from the dict, and returns the associated value. "
+ "If entry with that key was found, return the specified <code>default</code> value;"
+ "if no default value was specified, fail instead.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict."),
@Param(name = "key", type = Object.class, doc = "The key."),
- },
- optionalPositionals = {
@Param(name = "default", type = Object.class, defaultValue = "unbound",
doc = "a default value if the key is absent."),
},
@@ -1445,7 +1416,7 @@ public class MethodLibrary {
+ "according to the builtin total order. "
+ "Thus if keys are numbers, the smallest key is returned first; "
+ "if they are lists or strings, they are compared lexicographically, etc.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")
},
useLocation = true,
@@ -1471,7 +1442,7 @@ public class MethodLibrary {
objectType = SkylarkDict.class,
returnType = Runtime.NoneType.class,
doc = "Remove all items from the dictionary.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")
},
useLocation = true,
@@ -1496,11 +1467,9 @@ public class MethodLibrary {
+ "If not, insert key with a value of <code>default</code> "
+ "and return <code>default</code>. "
+ "<code>default</code> defaults to <code>None</code>.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict."),
@Param(name = "key", type = Object.class, doc = "The key."),
- },
- optionalPositionals = {
@Param(
name = "default",
type = Object.class,
@@ -1534,7 +1503,7 @@ public class MethodLibrary {
objectType = SkylarkDict.class,
returnType = Runtime.NoneType.class,
doc = "Update the dictionary with the key/value pairs from other, overwriting existing keys.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict."),
@Param(name = "other", type = SkylarkDict.class, doc = "The values to add."),
},
@@ -1557,7 +1526,7 @@ public class MethodLibrary {
// dictionary access operator
@SkylarkSignature(name = "$index", documented = false, objectType = SkylarkDict.class,
doc = "Looks up a value in a dictionary.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict."),
@Param(name = "key", type = Object.class, doc = "The index or key to access.")},
useLocation = true, useEnvironment = true)
@@ -1577,7 +1546,7 @@ public class MethodLibrary {
documented = false,
objectType = MutableList.class,
doc = "Returns the nth element of a list.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = MutableList.class, doc = "This list."),
@Param(name = "key", type = Integer.class, doc = "The index or key to access.")
},
@@ -1602,7 +1571,7 @@ public class MethodLibrary {
documented = false,
objectType = Tuple.class,
doc = "Returns the nth element of a tuple.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = Tuple.class, doc = "This tuple."),
@Param(name = "key", type = Integer.class, doc = "The index or key to access.")
},
@@ -1626,7 +1595,7 @@ public class MethodLibrary {
documented = false,
objectType = String.class,
doc = "Returns the nth element of a string.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = String.class, doc = "This string."),
@Param(name = "key", type = Integer.class, doc = "The index or key to access.")
},
@@ -1646,7 +1615,7 @@ public class MethodLibrary {
doc = "Returns the list of values. Dictionaries are always sorted by their keys:"
+ "<pre class=\"language-python\">"
+ "{2: \"a\", 4: \"b\", 1: \"c\"}.values() == [\"c\", \"a\", \"b\"]</pre>\n",
- mandatoryPositionals = {@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
+ parameters = {@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
useEnvironment = true)
private static final BuiltinFunction values = new BuiltinFunction("values") {
public MutableList<?> invoke(SkylarkDict<?, ?> self,
@@ -1661,7 +1630,7 @@ public class MethodLibrary {
+ "<pre class=\"language-python\">"
+ "{2: \"a\", 4: \"b\", 1: \"c\"}.items() == [(1, \"c\"), (2, \"a\"), (4, \"b\")]"
+ "</pre>\n",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
useEnvironment = true)
private static final BuiltinFunction items = new BuiltinFunction("items") {
@@ -1680,7 +1649,7 @@ public class MethodLibrary {
doc = "Returns the list of keys. Dictionaries are always sorted by their keys:"
+ "<pre class=\"language-python\">{2: \"a\", 4: \"b\", 1: \"c\"}.keys() == [1, 2, 4]"
+ "</pre>\n",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
useEnvironment = true)
private static final BuiltinFunction keys = new BuiltinFunction("keys") {
@@ -1699,10 +1668,9 @@ public class MethodLibrary {
doc = "Returns the value for <code>key</code> if <code>key</code> is in the dictionary, "
+ "else <code>default</code>. If <code>default</code> is not given, it defaults to "
+ "<code>None</code>, so that this method never throws an error.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "self", doc = "This dict."),
- @Param(name = "key", doc = "The key to look for.")},
- optionalPositionals = {
+ @Param(name = "key", doc = "The key to look for."),
@Param(name = "default", defaultValue = "None",
doc = "The default value to use (instead of None) if the key is not found.")})
private static final BuiltinFunction get = new BuiltinFunction("get") {
@@ -1720,7 +1688,7 @@ public class MethodLibrary {
returnType = Integer.class,
documented = false,
doc = "Unary minus operator.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "num", type = Integer.class, doc = "The number to negate.")
}
)
@@ -1736,7 +1704,7 @@ public class MethodLibrary {
+ "<pre class=\"language-python\">list([1, 2]) == [1, 2]\n"
+ "list(set([2, 3, 2])) == [2, 3]\n"
+ "list({5: \"a\", 2: \"b\", 4: \"c\"}) == [2, 4, 5]</pre>",
- mandatoryPositionals = {@Param(name = "x", doc = "The object to convert.")},
+ parameters = {@Param(name = "x", doc = "The object to convert.")},
useLocation = true, useEnvironment = true)
private static final BuiltinFunction list = new BuiltinFunction("list") {
public MutableList<?> invoke(Object x, Location loc, Environment env) throws EvalException {
@@ -1748,7 +1716,7 @@ public class MethodLibrary {
name = "len",
returnType = Integer.class,
doc = "Returns the length of a string, list, tuple, set, or dictionary.",
- mandatoryPositionals = {@Param(name = "x", doc = "The object to check length of.")},
+ parameters = {@Param(name = "x", doc = "The object to check length of.")},
useLocation = true
)
private static final BuiltinFunction len =
@@ -1765,7 +1733,7 @@ public class MethodLibrary {
@SkylarkSignature(name = "str", returnType = String.class, doc =
"Converts any object to string. This is useful for debugging."
+ "<pre class=\"language-python\">str(\"ab\") == \"ab\"</pre>",
- mandatoryPositionals = {@Param(name = "x", doc = "The object to convert.")})
+ parameters = {@Param(name = "x", doc = "The object to convert.")})
private static final BuiltinFunction str = new BuiltinFunction("str") {
public String invoke(Object x) {
return Printer.str(x);
@@ -1775,7 +1743,7 @@ public class MethodLibrary {
@SkylarkSignature(name = "repr", returnType = String.class, doc =
"Converts any object to a string representation. This is useful for debugging.<br>"
+ "<pre class=\"language-python\">str(\"ab\") == \\\"ab\\\"</pre>",
- mandatoryPositionals = {@Param(name = "x", doc = "The object to convert.")})
+ parameters = {@Param(name = "x", doc = "The object to convert.")})
private static final BuiltinFunction repr = new BuiltinFunction("repr") {
public String invoke(Object x) {
return Printer.repr(x);
@@ -1786,7 +1754,7 @@ public class MethodLibrary {
doc = "Constructor for the bool type. "
+ "It returns False if the object is None, False, an empty string, the number 0, or an "
+ "empty collection. Otherwise, it returns True.",
- mandatoryPositionals = {@Param(name = "x", doc = "The variable to convert.")})
+ parameters = {@Param(name = "x", doc = "The variable to convert.")})
private static final BuiltinFunction bool = new BuiltinFunction("bool") {
public Boolean invoke(Object x) throws EvalException {
return EvalUtils.toBoolean(x);
@@ -1798,7 +1766,7 @@ public class MethodLibrary {
+ "conversion fails. If the argument is a bool, it returns 0 (False) or 1 (True). "
+ "If the argument is an int, it is simply returned."
+ "<pre class=\"language-python\">int(\"123\") == 123</pre>",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "x", type = Object.class, doc = "The string to convert.")},
useLocation = true)
private static final BuiltinFunction int_ = new BuiltinFunction("int") {
@@ -1844,7 +1812,7 @@ public class MethodLibrary {
+ "A desired <a href=\"set.html\">iteration order</a> can also be specified.<br>"
+ "Examples:<br><pre class=\"language-python\">set([\"a\", \"b\"])\n"
+ "set([1, 2, 3], order=\"compile\")</pre>",
- optionalPositionals = {
+ parameters = {
@Param(name = "items", type = Object.class, defaultValue = "[]",
doc = "The items to initialize the set with. May contain both standalone items "
+ "and other sets."),
@@ -1873,7 +1841,7 @@ public class MethodLibrary {
+ "argument and an optional set of keyword arguments. Values from the keyword argument "
+ "will overwrite values from the positional argument if a key appears multiple times. "
+ "Dictionaries are always sorted by their keys",
- optionalPositionals = {
+ parameters = {
@Param(
name = "args",
type = Object.class,
@@ -1936,7 +1904,7 @@ public class MethodLibrary {
returnType = SkylarkNestedSet.class,
doc = "Creates a new <a href=\"set.html\">set</a> that contains both "
+ "the input set as well as all additional elements.",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "input", type = SkylarkNestedSet.class, doc = "The input set"),
@Param(name = "new_elements", type = Iterable.class, doc = "The elements to be added")},
useLocation = true)
@@ -1952,7 +1920,7 @@ public class MethodLibrary {
doc = "Returns a list of pairs (two-element tuples), with the index (int) and the item from"
+ " the input list.\n<pre class=\"language-python\">"
+ "enumerate([24, 21, 84]) == [(0, 24), (1, 21), (2, 84)]</pre>\n",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "list", type = SkylarkList.class, doc = "input list")
},
useEnvironment = true)
@@ -1976,12 +1944,10 @@ public class MethodLibrary {
+ "<pre class=\"language-python\">range(4) == [0, 1, 2, 3]\n"
+ "range(3, 9, 2) == [3, 5, 7]\n"
+ "range(3, 0, -1) == [3, 2, 1]</pre>",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "start_or_stop", type = Integer.class,
doc = "Value of the start element if stop is provided, "
+ "otherwise value of stop and the actual start is 0"),
- },
- optionalPositionals = {
@Param(name = "stop_or_none", type = Integer.class, noneable = true, defaultValue = "None",
doc = "optional index of the first item <i>not</i> to be included in the "
+ "resulting list; generation of the list stops before <code>stop</code> is reached."),
@@ -2027,9 +1993,8 @@ public class MethodLibrary {
*/
@SkylarkSignature(name = "select",
doc = "Creates a SelectorValue from the dict parameter.",
- mandatoryPositionals = {
- @Param(name = "x", type = SkylarkDict.class, doc = "The parameter to convert.")},
- optionalNamedOnly = {
+ parameters = {
+ @Param(name = "x", type = SkylarkDict.class, doc = "The parameter to convert."),
@Param(name = "no_match_error", type = String.class, defaultValue = "''",
doc = "Optional custom error to report if no condition matches.")})
private static final BuiltinFunction select = new BuiltinFunction("select") {
@@ -2046,7 +2011,7 @@ public class MethodLibrary {
doc = "Returns True if the object <code>x</code> has an attribute or method of the given "
+ "<code>name</code>, otherwise False. Example:<br>"
+ "<pre class=\"language-python\">hasattr(ctx.attr, \"myattr\")</pre>",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "x", doc = "The object to check."),
@Param(name = "name", type = String.class, doc = "The name of the attribute.")},
useLocation = true, useEnvironment = true)
@@ -2069,10 +2034,9 @@ public class MethodLibrary {
+ "<code>x.foobar</code>."
+ "<pre class=\"language-python\">getattr(ctx.attr, \"myattr\")\n"
+ "getattr(ctx.attr, \"myattr\", \"mydefault\")</pre>",
- mandatoryPositionals = {
+ parameters = {
@Param(name = "x", doc = "The struct whose attribute is accessed."),
- @Param(name = "name", doc = "The name of the struct attribute.")},
- optionalPositionals = {
+ @Param(name = "name", doc = "The name of the struct attribute."),
@Param(name = "default", defaultValue = "None",
doc = "The default value to return in case the struct "
+ "doesn't have an attribute of the given name.")},
@@ -2116,7 +2080,7 @@ public class MethodLibrary {
@SkylarkSignature(name = "dir", returnType = MutableList.class,
doc = "Returns a list strings: the names of the attributes and "
+ "methods of the parameter object.",
- mandatoryPositionals = {@Param(name = "x", doc = "The object to check.")},
+ parameters = {@Param(name = "x", doc = "The object to check.")},
useLocation = true, useEnvironment = true)
private static final BuiltinFunction dir = new BuiltinFunction("dir") {
public MutableList<?> invoke(Object object,
@@ -2139,7 +2103,7 @@ public class MethodLibrary {
@SkylarkSignature(name = "type", returnType = String.class,
doc = "Returns the type name of its argument.",
- mandatoryPositionals = {@Param(name = "x", doc = "The object to check type of.")})
+ parameters = {@Param(name = "x", doc = "The object to check type of.")})
private static final BuiltinFunction type = new BuiltinFunction("type") {
public String invoke(Object object) {
// There is no 'type' type in Skylark, so we return a string with the type name.
@@ -2153,14 +2117,12 @@ public class MethodLibrary {
"Raises an error that cannot be intercepted. It can be used anywhere, "
+ "both in the loading phase and in the analysis phase.",
returnType = Runtime.NoneType.class,
- mandatoryPositionals = {
+ parameters = {
@Param(
name = "msg",
type = Object.class,
doc = "Error to display for the user. The object is converted to a string."
- )
- },
- optionalPositionals = {
+ ),
@Param(
name = "attr",
type = String.class,
@@ -2189,8 +2151,9 @@ public class MethodLibrary {
doc = "Prints <code>args</code> as a warning. It can be used for debugging or "
+ "for transition (before changing to an error). In other cases, warnings are "
+ "discouraged.",
- optionalNamedOnly = {
+ parameters = {
@Param(name = "sep", type = String.class, defaultValue = "' '",
+ named = true, positional = false,
doc = "The separator string between the objects, default is space (\" \").")},
// NB: as compared to Python3, we're missing optional named-only arguments 'end' and 'file'
extraPositionals = @Param(name = "args", doc = "The objects to print."),
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
index 3a1e007c45..76572e96a5 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
@@ -63,33 +63,26 @@ public class SkylarkSignatureProcessor {
Iterator<Object> defaultValuesIterator = defaultValues == null
? null : defaultValues.iterator();
try {
- for (Param param : annotation.mandatoryPositionals()) {
- paramList.add(getParameter(name, param, enforcedTypes, doc, documented,
- /*mandatory=*/true, /*star=*/false, /*starStar=*/false, /*defaultValue=*/null));
- }
- for (Param param : annotation.optionalPositionals()) {
- paramList.add(getParameter(name, param, enforcedTypes, doc, documented,
- /*mandatory=*/false, /*star=*/false, /*starStar=*/false,
- /*defaultValue=*/getDefaultValue(param, defaultValuesIterator)));
- }
- if (!annotation.extraPositionals().name().isEmpty()
- || annotation.optionalNamedOnly().length > 0
- || annotation.mandatoryNamedOnly().length > 0) {
- @Nullable Param starParam = null;
- if (!annotation.extraPositionals().name().isEmpty()) {
- starParam = annotation.extraPositionals();
- }
- paramList.add(getParameter(name, starParam, enforcedTypes, doc, documented,
+ boolean named = false;
+ for (Param param : annotation.parameters()) {
+ boolean mandatory = param.defaultValue() != null && param.defaultValue().isEmpty();
+ Object defaultValue = mandatory ? null : getDefaultValue(param, defaultValuesIterator);
+ if (param.named() && !param.positional() && !named) {
+ named = true;
+ @Nullable Param starParam = null;
+ if (!annotation.extraPositionals().name().isEmpty()) {
+ starParam = annotation.extraPositionals();
+ }
+ paramList.add(getParameter(name, starParam, enforcedTypes, doc, documented,
/*mandatory=*/false, /*star=*/true, /*starStar=*/false, /*defaultValue=*/null));
- }
- for (Param param : annotation.mandatoryNamedOnly()) {
+ }
paramList.add(getParameter(name, param, enforcedTypes, doc, documented,
- /*mandatory=*/true, /*star=*/false, /*starStar=*/false, /*defaultValue=*/null));
+ mandatory, /*star=*/false, /*starStar=*/false, defaultValue));
}
- for (Param param : annotation.optionalNamedOnly()) {
- paramList.add(getParameter(name, param, enforcedTypes, doc, documented,
- /*mandatory=*/false, /*star=*/false, /*starStar=*/false,
- /*defaultValue=*/getDefaultValue(param, defaultValuesIterator)));
+ if (!annotation.extraPositionals().name().isEmpty() && !named) {
+ paramList.add(getParameter(name, annotation.extraPositionals(), enforcedTypes, doc,
+ documented, /*mandatory=*/false, /*star=*/true, /*starStar=*/false,
+ /*defaultValue=*/null));
}
if (!annotation.extraKeywords().name().isEmpty()) {
paramList.add(
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
index 9d58f885be..e41b90c134 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
@@ -67,10 +67,12 @@ public class SkylarkRuleImplementationFunctionsTest extends SkylarkTestCase {
@SkylarkSignature(
name = "mock",
documented = false,
- mandatoryPositionals = {@Param(name = "mandatory", doc = "")},
- optionalPositionals = {@Param(name = "optional", doc = "")},
- mandatoryNamedOnly = {@Param(name = "mandatory_key", doc = "")},
- optionalNamedOnly = {@Param(name = "optional_key", doc = "", defaultValue = "'x'")},
+ parameters = {
+ @Param(name = "mandatory", doc = ""),
+ @Param(name = "optional", doc = "", defaultValue = "None"),
+ @Param(name = "mandatory_key", doc = "", positional = false, named = true),
+ @Param(name = "optional_key", doc = "", defaultValue = "'x'",
+ positional = false, named = true)},
useEnvironment = true
)
private BuiltinFunction mockFunc;