diff options
author | 2016-06-14 10:28:31 +0000 | |
---|---|---|
committer | 2016-06-14 11:03:49 +0000 | |
commit | 014388cec904f391ce8e54d323c9e9ce527ca0eb (patch) | |
tree | 82b78efc9ae2aea2eab48d72e70c5352e77a2b25 /src | |
parent | 3dd7f269bbfd463435bfc6af3424626f15f8850c (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')
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()) ? "…" : defaultValue); + String name = param.name(); + if (defaultValue == null || !defaultValue.isEmpty()) { + return String.format("%s=%s", name, defaultValue == null ? "…" : 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.<attribute_name></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; |