From a3ac202ec114c092221b296a2695d0aadd50031f Mon Sep 17 00:00:00 2001 From: Francois-Rene Rideau Date: Mon, 20 Apr 2015 18:35:05 +0000 Subject: Migrate SkylarkBuiltin annotations to SkylarkSignature instead. -- MOS_MIGRATED_REVID=91603959 --- .../devtools/build/lib/rules/SkylarkAttr.java | 232 +++++++++++++-------- .../build/lib/rules/SkylarkCommandLine.java | 12 +- .../devtools/build/lib/rules/SkylarkModules.java | 12 +- .../build/lib/rules/SkylarkRuleClassFunctions.java | 90 ++++---- .../rules/SkylarkRuleImplementationFunctions.java | 158 ++++++++------ 5 files changed, 293 insertions(+), 211 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/rules') 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 549e0252af..408c4841b7 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 @@ -26,13 +26,13 @@ import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.FuncallExpression; import com.google.devtools.build.lib.syntax.Label; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin.Param; import com.google.devtools.build.lib.syntax.SkylarkCallbackFunction; import com.google.devtools.build.lib.syntax.SkylarkEnvironment; import com.google.devtools.build.lib.syntax.SkylarkFunction; import com.google.devtools.build.lib.syntax.SkylarkList; import com.google.devtools.build.lib.syntax.SkylarkModule; +import com.google.devtools.build.lib.syntax.SkylarkSignature; +import com.google.devtools.build.lib.syntax.SkylarkSignature.Param; import com.google.devtools.build.lib.syntax.UserDefinedFunction; import com.google.devtools.build.lib.util.FileTypeSet; @@ -153,16 +153,20 @@ public final class SkylarkAttr { } } - @SkylarkBuiltin(name = "int", doc = + @SkylarkSignature(name = "int", doc = "Creates an attribute of type int.", objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", type = Integer.class, - doc = DEFAULT_DOC + " If not specified, default is 0."), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + @Param(name = "default", type = Integer.class, defaultValue = "0", + doc = DEFAULT_DOC + " If not specified, default is 0."), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "mandatory", type = Boolean.class, defaultValue = "False", + doc = MANDATORY_DOC), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction integer = new SkylarkFunction("int") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) @@ -171,16 +175,20 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "string", doc = + @SkylarkSignature(name = "string", doc = "Creates an attribute of type string.", objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", type = String.class, - doc = DEFAULT_DOC + " If not specified, default is \"\"."), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + @Param(name = "default", type = String.class, + defaultValue = "\"\"", doc = DEFAULT_DOC + " If not specified, default is \"\"."), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "mandatory", type = Boolean.class, + defaultValue = "False", doc = MANDATORY_DOC), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction string = new SkylarkFunction("string") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) @@ -189,29 +197,35 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "label", doc = + @SkylarkSignature(name = "label", doc = "Creates an attribute of type Label. " + "It is the only way to specify a dependency to another target. " + "If you need a dependency that the user cannot overwrite, make the attribute " + "private (starts with _).", objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", type = Label.class, callbackEnabled = true, - doc = DEFAULT_DOC + " If not specified, default is None. " - + "Use the Label function to specify a default value."), - @Param(name = "executable", type = Boolean.class, doc = EXECUTABLE_DOC), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "allow_files", doc = ALLOW_FILES_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "providers", type = SkylarkList.class, generic1 = String.class, - doc = "mandatory providers every dependency has to have"), - @Param(name = "allow_rules", type = SkylarkList.class, generic1 = String.class, - doc = ALLOW_RULES_DOC), - @Param(name = "single_file", doc = - "if True, the label must correspond to a single File. " - + "Access it through ctx.file.<attribute_name>."), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + @Param(name = "default", type = Label.class, callbackEnabled = true, noneable = true, + defaultValue = "None", + doc = DEFAULT_DOC + " If not specified, default is None. " + + "Use the Label function to specify a default value."), + @Param(name = "executable", type = Boolean.class, defaultValue = "False", + doc = EXECUTABLE_DOC), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "allow_files", defaultValue = "False", doc = ALLOW_FILES_DOC), + @Param(name = "mandatory", type = Boolean.class, defaultValue = "False", + doc = MANDATORY_DOC), + @Param(name = "providers", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = "mandatory providers every dependency has to have"), + @Param(name = "allow_rules", type = SkylarkList.class, generic1 = String.class, + noneable = true, defaultValue = "None", doc = ALLOW_RULES_DOC), + @Param(name = "single_file", type = Boolean.class, defaultValue = "False", + doc = "if True, the label must correspond to a single File. " + + "Access it through ctx.file.<attribute_name>."), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction label = new SkylarkFunction("label") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) @@ -220,11 +234,11 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "string_list", doc = + @SkylarkSignature(name = "string_list", doc = "Creates an attribute of type list of strings", objectType = SkylarkAttr.class, returnType = Attribute.class, - optionalParams = { + optionalPositionals = { @Param(name = "default", type = SkylarkList.class, generic1 = String.class, doc = DEFAULT_DOC + " If not specified, default is []."), @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), @@ -240,25 +254,31 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "label_list", doc = + @SkylarkSignature(name = "label_list", doc = "Creates an attribute of type list of labels. " + "See label for more information.", objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", type = SkylarkList.class, generic1 = Label.class, - callbackEnabled = true, - doc = DEFAULT_DOC + " If not specified, default is []. " - + "Use the Label function to specify a default value."), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "allow_files", doc = ALLOW_FILES_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "allow_rules", type = SkylarkList.class, generic1 = String.class, - doc = ALLOW_RULES_DOC), - @Param(name = "non_empty", type = Boolean.class, doc = NON_EMPTY_DOC), - @Param(name = "providers", type = SkylarkList.class, generic1 = String.class, - doc = "mandatory providers every dependency has to have"), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + @Param(name = "default", type = SkylarkList.class, generic1 = Label.class, + callbackEnabled = true, defaultValue = "[]", + doc = DEFAULT_DOC + " If not specified, default is []. " + + "Use the Label function to specify a default value."), + @Param(name = "allow_files", // bool or FileType filter + defaultValue = "False", doc = ALLOW_FILES_DOC), + @Param(name = "allow_rules", type = SkylarkList.class, generic1 = String.class, + noneable = true, defaultValue = "None", doc = ALLOW_RULES_DOC), + @Param(name = "providers", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = "mandatory providers every dependency has to have"), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "mandatory", type = Boolean.class, defaultValue = "False", + doc = MANDATORY_DOC), + @Param(name = "non_empty", type = Boolean.class, defaultValue = "False", + doc = NON_EMPTY_DOC), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction labelList = new SkylarkFunction("label_list") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) @@ -267,15 +287,20 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "bool", doc = + @SkylarkSignature(name = "bool", doc = "Creates an attribute of type bool. Its default value is False.", objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", type = Boolean.class, doc = DEFAULT_DOC), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + @Param(name = "default", type = Boolean.class, + defaultValue = "False", doc = DEFAULT_DOC), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "mandatory", type = Boolean.class, defaultValue = "False", + doc = MANDATORY_DOC), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction bool = new SkylarkFunction("bool") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) @@ -284,17 +309,22 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "output", doc = + @SkylarkSignature(name = "output", doc = "Creates an attribute of type output. Its default value is None. " + "The user provides a file name (string) and the rule must create an action that " + "generates the file.", objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", type = Label.class, doc = DEFAULT_DOC), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + @Param(name = "default", type = Label.class, noneable = true, + defaultValue = "None", doc = DEFAULT_DOC), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "mandatory", type = Boolean.class, defaultValue = "False", + doc = MANDATORY_DOC), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction output = new SkylarkFunction("output") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) @@ -303,17 +333,23 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "output_list", doc = + @SkylarkSignature(name = "output_list", doc = "Creates an attribute of type list of outputs. Its default value is []. " + "See output above for more information.", objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", type = SkylarkList.class, generic1 = Label.class, doc = DEFAULT_DOC), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "non_empty", type = Boolean.class, doc = NON_EMPTY_DOC), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + @Param(name = "default", type = SkylarkList.class, generic1 = Label.class, + defaultValue = "[]", doc = DEFAULT_DOC), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "mandatory", type = Boolean.class, + defaultValue = "False", doc = MANDATORY_DOC), + @Param(name = "non_empty", type = Boolean.class, defaultValue = "False", + doc = NON_EMPTY_DOC), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction outputList = new SkylarkFunction("output_list") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) @@ -322,17 +358,23 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "string_dict", doc = + @SkylarkSignature(name = "string_dict", doc = "Creates an attribute of type dictionary, mapping from string to string. " - + "Its default value is {}.", + + "Its default value is dict().", objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", type = Map.class, doc = DEFAULT_DOC), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "non_empty", type = Boolean.class, doc = NON_EMPTY_DOC), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + @Param(name = "default", type = Map.class, + defaultValue = "{}", doc = DEFAULT_DOC), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "mandatory", type = Boolean.class, defaultValue = "False", + doc = MANDATORY_DOC), + @Param(name = "non_empty", type = Boolean.class, defaultValue = "False", + doc = NON_EMPTY_DOC), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction stringDict = new SkylarkFunction("string_dict") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) @@ -341,16 +383,22 @@ public final class SkylarkAttr { } }; - @SkylarkBuiltin(name = "license", doc = + @SkylarkSignature(name = "license", doc = "Creates an attribute of type license. Its default value is NO_LICENSE.", // TODO(bazel-team): Implement proper license support for Skylark. objectType = SkylarkAttr.class, - returnType = Attribute.class, - optionalParams = { - @Param(name = "default", doc = DEFAULT_DOC), - @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, doc = FLAGS_DOC), - @Param(name = "mandatory", type = Boolean.class, doc = MANDATORY_DOC), - @Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)}) + returnType = Attribute.Builder.class, + optionalNamedOnly = { + // TODO(bazel-team): ensure this is the correct default value + @Param(name = "default", defaultValue = "None", noneable = true, + doc = DEFAULT_DOC), + @Param(name = "flags", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = FLAGS_DOC), + @Param(name = "mandatory", type = Boolean.class, defaultValue = "False", + doc = MANDATORY_DOC), + @Param(name = "cfg", type = ConfigurationTransition.class, noneable = true, + defaultValue = "None", doc = CONFIGURATION_DOC)}, + useAst = true, useEnvironment = true) private static SkylarkFunction license = new SkylarkFunction("license") { @Override public Object call(Map kwargs, FuncallExpression ast, Environment env) 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 dbf72184a0..260c7e4a8f 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 @@ -20,12 +20,12 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.syntax.EvalException; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin.Param; import com.google.devtools.build.lib.syntax.SkylarkFunction.SimpleSkylarkFunction; import com.google.devtools.build.lib.syntax.SkylarkList; import com.google.devtools.build.lib.syntax.SkylarkModule; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; +import com.google.devtools.build.lib.syntax.SkylarkSignature; +import com.google.devtools.build.lib.syntax.SkylarkSignature.Param; import java.util.Map; @@ -36,12 +36,12 @@ import java.util.Map; doc = "Module for creating memory efficient command lines.") public class SkylarkCommandLine { - @SkylarkBuiltin(name = "join_paths", + @SkylarkSignature(name = "join_paths", doc = "Creates a single command line argument joining the paths of a set " + "of files on the separator string.", objectType = SkylarkCommandLine.class, returnType = String.class, - mandatoryParams = { + mandatoryPositionals = { @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")}) @@ -59,11 +59,11 @@ public class SkylarkCommandLine { }; // TODO(bazel-team): this method should support sets of objects and substitute all struct fields. - @SkylarkBuiltin(name = "template", + @SkylarkSignature(name = "template", doc = "Transforms a set of files to a list of strings using the template string.", objectType = SkylarkCommandLine.class, returnType = SkylarkList.class, - mandatoryParams = { + mandatoryPositionals = { @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/SkylarkModules.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkModules.java index 7ab0cee813..226ceebee3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkModules.java +++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkModules.java @@ -24,10 +24,10 @@ import com.google.devtools.build.lib.packages.SkylarkNativeModule; import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.EvaluationContext; import com.google.devtools.build.lib.syntax.Function; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin; import com.google.devtools.build.lib.syntax.SkylarkEnvironment; import com.google.devtools.build.lib.syntax.SkylarkFunction; import com.google.devtools.build.lib.syntax.SkylarkModule; +import com.google.devtools.build.lib.syntax.SkylarkSignature; import com.google.devtools.build.lib.syntax.ValidationEnvironment; import java.lang.reflect.Field; @@ -150,11 +150,11 @@ public class SkylarkModules { ImmutableList.Builder functions, ImmutableMap.Builder objects) { try { for (Field field : type.getDeclaredFields()) { - if (field.isAnnotationPresent(SkylarkBuiltin.class)) { + if (field.isAnnotationPresent(SkylarkSignature.class)) { // Fields in Skylark modules are sometimes private. - // Nevertheless they have to be annotated with SkylarkBuiltin. + // Nevertheless they have to be annotated with SkylarkSignature. field.setAccessible(true); - SkylarkBuiltin annotation = field.getAnnotation(SkylarkBuiltin.class); + SkylarkSignature annotation = field.getAnnotation(SkylarkSignature.class); Object value = field.get(null); if (SkylarkFunction.class.isAssignableFrom(field.getType())) { SkylarkFunction function = (SkylarkFunction) value; @@ -179,8 +179,8 @@ public class SkylarkModules { */ private static void collectSkylarkTypesFromFields(Class classObject, Set builtIn) { for (Field field : classObject.getDeclaredFields()) { - if (field.isAnnotationPresent(SkylarkBuiltin.class)) { - SkylarkBuiltin annotation = field.getAnnotation(SkylarkBuiltin.class); + if (field.isAnnotationPresent(SkylarkSignature.class)) { + SkylarkSignature annotation = field.getAnnotation(SkylarkSignature.class); if (SkylarkFunction.class.isAssignableFrom(field.getType())) { // Ignore non-global values. if (annotation.objectType().equals(Object.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 68e9cfe53d..3cb4e28f96 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 @@ -55,6 +55,7 @@ import com.google.devtools.build.lib.packages.TestSize; import com.google.devtools.build.lib.packages.Type; import com.google.devtools.build.lib.packages.Type.ConversionException; import com.google.devtools.build.lib.syntax.AbstractFunction; +import com.google.devtools.build.lib.syntax.BaseFunction; import com.google.devtools.build.lib.syntax.ClassObject; import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject; import com.google.devtools.build.lib.syntax.Environment; @@ -64,13 +65,13 @@ import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.syntax.FuncallExpression; import com.google.devtools.build.lib.syntax.Function; import com.google.devtools.build.lib.syntax.Label; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin.Param; import com.google.devtools.build.lib.syntax.SkylarkCallbackFunction; import com.google.devtools.build.lib.syntax.SkylarkEnvironment; import com.google.devtools.build.lib.syntax.SkylarkFunction; import com.google.devtools.build.lib.syntax.SkylarkFunction.SimpleSkylarkFunction; import com.google.devtools.build.lib.syntax.SkylarkList; +import com.google.devtools.build.lib.syntax.SkylarkSignature; +import com.google.devtools.build.lib.syntax.SkylarkSignature.Param; import com.google.devtools.build.lib.syntax.UserDefinedFunction; import java.util.List; @@ -84,11 +85,11 @@ import java.util.concurrent.ExecutionException; public class SkylarkRuleClassFunctions { //TODO(bazel-team): proper enum support - @SkylarkBuiltin(name = "DATA_CFG", returnType = ConfigurationTransition.class, + @SkylarkSignature(name = "DATA_CFG", returnType = ConfigurationTransition.class, doc = "Experimental. Specifies a transition to the data configuration.") private static final Object dataTransition = ConfigurationTransition.DATA; - @SkylarkBuiltin(name = "HOST_CFG", returnType = ConfigurationTransition.class, + @SkylarkSignature(name = "HOST_CFG", returnType = ConfigurationTransition.class, doc = "Specifies a transition to the host configuration.") private static final Object hostTransition = ConfigurationTransition.HOST; @@ -177,39 +178,42 @@ public class SkylarkRuleClassFunctions { // TODO(bazel-team): implement attribute copy and other rule properties - @SkylarkBuiltin(name = "rule", doc = + @SkylarkSignature(name = "rule", doc = "Creates a new rule. Store it in a global value, so that it can be loaded and called " + "from BUILD files.", onlyLoadingPhase = true, - returnType = Function.class, - mandatoryParams = { - @Param(name = "implementation", type = UserDefinedFunction.class, - doc = "the function implementing this rule, has to have exactly one parameter: " - + "ctx. The function is called during 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.") + returnType = BaseFunction.class, + mandatoryPositionals = { + @Param(name = "implementation", type = Function.class, + doc = "the function implementing this rule, has to have exactly one parameter: " + + "ctx. The function is called during 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.") }, - optionalParams = { - @Param(name = "test", type = Boolean.class, doc = "Whether this rule is a test rule. " - + "If True, the rule must end with _test (otherwise it cannot)."), - @Param(name = "attrs", type = Map.class, doc = - "dictionary to declare all the attributes of the rule. It maps from an attribute name " - + "to an attribute object (see attr module). " - + "Attributes starting with _ are private, and can be used to add " - + "an implicit dependency on a label."), - @Param(name = "outputs", doc = "outputs of this rule. " - + "It is a dictionary mapping from string to a template name. " - + "For example: {\"ext\": \"${name}.ext\"}.
" - + "The dictionary key becomes a field in ctx.outputs. " - // TODO(bazel-team): Make doc more clear, wrt late-bound attributes. - + "It may also be a function (which receives ctx.attr as argument) " - + "returning such a dictionary."), - @Param(name = "executable", type = Boolean.class, - doc = "whether this rule always outputs an executable of the same name or not. If True, " - + "there must be an action that generates ctx.outputs.executable."), - @Param(name = "output_to_genfiles", type = Boolean.class, - doc = "If true, the files will be generated in the genfiles directory instead of the " - + "bin directory. This is used for compatibility with existing rules.")}) + optionalPositionals = { + @Param(name = "test", type = Boolean.class, defaultValue = "False", + doc = "Whether this rule is a test rule. " + + "If True, the rule must end with _test (otherwise it cannot)."), + @Param(name = "attrs", type = Map.class, noneable = true, defaultValue = "None", doc = + "dictionary to declare all the attributes of the rule. It maps from an attribute name " + + "to an attribute object (see attr module). " + + "Attributes starting with _ are private, and can be used to add " + + "an implicit dependency on a label."), + @Param(name = "outputs", type = Map.class, callbackEnabled = true, noneable = true, + defaultValue = "None", doc = "outputs of this rule. " + + "It is a dictionary mapping from string to a template name. " + + "For example: {\"ext\": \"${name}.ext\"}.
" + + "The dictionary key becomes a field in ctx.outputs. " + // TODO(bazel-team): Make doc more clear, wrt late-bound attributes. + + "It may also be a function (which receives ctx.attr as argument) " + + "returning such a dictionary."), + @Param(name = "executable", type = Boolean.class, defaultValue = "False", + doc = "whether this rule always outputs an executable of the same name or not. If " + + "True, there must be an action that generates ctx.outputs.executable."), + @Param(name = "output_to_genfiles", type = Boolean.class, defaultValue = "False", + doc = "If true, the files will be generated in the genfiles directory instead of the " + + "bin directory. This is used for compatibility with existing rules.")}, + useAst = true, useEnvironment = true) private static final SkylarkFunction rule = new SkylarkFunction("rule") { @Override @@ -313,12 +317,13 @@ public class SkylarkRuleClassFunctions { } } - @SkylarkBuiltin(name = "Label", doc = "Creates a Label referring to a BUILD target. Use " + @SkylarkSignature(name = "Label", doc = "Creates a Label referring to a BUILD target. Use " + "this function only when you want to give a default value for the label attributes. " + "Example:
Label(\"//tools:default\")
", returnType = Label.class, - mandatoryParams = {@Param(name = "label_string", type = String.class, - doc = "the label string")}) + mandatoryPositionals = {@Param(name = "label_string", type = String.class, + doc = "the label string")}, + useLocation = true) private static final SkylarkFunction label = new SimpleSkylarkFunction("Label") { @Override public Object call(Map arguments, Location loc) throws EvalException, @@ -332,11 +337,11 @@ public class SkylarkRuleClassFunctions { } }; - @SkylarkBuiltin(name = "FileType", + @SkylarkSignature(name = "FileType", doc = "Creates a file filter from a list of strings. For example, to match files ending " + "with .cc or .cpp, use:
FileType([\".cc\", \".cpp\"])
", returnType = SkylarkFileType.class, - mandatoryParams = { + mandatoryPositionals = { @Param(name = "types", type = SkylarkList.class, generic1 = String.class, doc = "a list of the accepted file extensions")}) private static final SkylarkFunction fileType = new SimpleSkylarkFunction("FileType") { @@ -347,7 +352,7 @@ public class SkylarkRuleClassFunctions { } }; - @SkylarkBuiltin(name = "to_proto", + @SkylarkSignature(name = "to_proto", doc = "Creates a text message from the struct parameter. This method only works if all " + "struct elements (recursively) are strings, ints, booleans, other structs or a " + "list of these types. Quotes and new lines in strings are escaped. " @@ -362,7 +367,12 @@ public class SkylarkRuleClassFunctions { + "# key {\n# inner_key: 1\n# }\n# key {\n# inner_key: 2\n# }\n\n" + "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", - objectType = SkylarkClassObject.class, returnType = String.class) + objectType = SkylarkClassObject.class, returnType = String.class, + mandatoryPositionals = { + // TODO(bazel-team): shouldn't we accept any ClassObject? + @Param(name = "self", type = SkylarkClassObject.class, + doc = "this struct")}, + useLocation = true) private static final SkylarkFunction toProto = new SimpleSkylarkFunction("to_proto") { @Override public Object call(Map arguments, Location loc) throws EvalException, 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 cc582ab17e..0019fe8683 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 @@ -36,12 +36,12 @@ import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.syntax.Label; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin; -import com.google.devtools.build.lib.syntax.SkylarkBuiltin.Param; import com.google.devtools.build.lib.syntax.SkylarkFunction; import com.google.devtools.build.lib.syntax.SkylarkFunction.SimpleSkylarkFunction; import com.google.devtools.build.lib.syntax.SkylarkList; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; +import com.google.devtools.build.lib.syntax.SkylarkSignature; +import com.google.devtools.build.lib.syntax.SkylarkSignature.Param; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Map; @@ -69,32 +69,43 @@ public class SkylarkRuleImplementationFunctions { * command = 'command', * ) */ - @SkylarkBuiltin(name = "action", + @SkylarkSignature(name = "action", doc = "Creates an action that runs an executable or a shell command.", objectType = SkylarkRuleContext.class, returnType = Environment.NoneType.class, - mandatoryParams = { - @Param(name = "outputs", type = SkylarkList.class, generic1 = Artifact.class, - doc = "list of the output files of the action")}, - optionalParams = { - @Param(name = "inputs", type = SkylarkList.class, generic1 = Artifact.class, - doc = "list of the input files of the action"), - @Param(name = "executable", doc = "the executable file to be called by the action"), - @Param(name = "arguments", type = SkylarkList.class, generic1 = String.class, - doc = "command line arguments of the action"), - @Param(name = "mnemonic", type = String.class, doc = "mnemonic"), - @Param(name = "command", doc = "shell command to execute"), - @Param(name = "progress_message", type = String.class, - doc = "progress message to show to the user during the build, e.g. \"Compiling foo.cc to" - + " create foo.o\""), - @Param(name = "use_default_shell_env", type = Boolean.class, - doc = "whether the action should use the built in shell environment or not"), - @Param(name = "env", type = Map.class, doc = "sets the dictionary of environment variables"), - @Param(name = "execution_requirements", type = Map.class, - doc = "information for scheduling the action"), - @Param(name = "input_manifests", type = Map.class, - doc = "sets the map of input manifests files; " - + "they are typicially generated by the command_helper")}) + mandatoryPositionals = { + @Param(name = "self", type = SkylarkRuleContext.class, doc = "This RuleContext.")}, + mandatoryNamedOnly = { + @Param(name = "outputs", type = SkylarkList.class, generic1 = Artifact.class, + doc = "list of the output files of the action")}, + optionalNamedOnly = { + @Param(name = "inputs", type = SkylarkList.class, generic1 = Artifact.class, + defaultValue = "[]", doc = "list of the input files of the action"), + @Param(name = "executable", type = Object.class, // File or PathFragment or None + defaultValue = "None", + doc = "the executable file to be called by the action"), + @Param(name = "arguments", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", doc = "command line arguments of the action"), + @Param(name = "mnemonic", type = String.class, noneable = true, + defaultValue = "None", doc = "mnemonic"), + @Param(name = "command", type = Object.class, // string or ListOf(string) or NoneType + defaultValue = "None", doc = "shell command to execute"), + @Param(name = "progress_message", type = String.class, noneable = true, + defaultValue = "None", + doc = "progress message to show to the user during the build, " + + "e.g. \"Compiling foo.cc to create foo.o\""), + @Param(name = "use_default_shell_env", type = Boolean.class, defaultValue = "False", + doc = "whether the action should use the built in shell environment or not"), + @Param(name = "env", type = Map.class, noneable = true, defaultValue = "None", + doc = "sets the dictionary of environment variables"), + @Param(name = "execution_requirements", type = Map.class, noneable = true, + defaultValue = "None", + doc = "information for scheduling the action"), + @Param(name = "input_manifests", type = Map.class, noneable = true, + defaultValue = "None", + doc = "sets the map of input manifests files; " + + "they are typicially generated by the command_helper")}, + useLocation = true) private static final SkylarkFunction createSpawnAction = new SimpleSkylarkFunction("action") { @@ -175,17 +186,17 @@ public class SkylarkRuleImplementationFunctions { }; // TODO(bazel-team): improve this method to be more memory friendly - @SkylarkBuiltin(name = "file_action", + @SkylarkSignature(name = "file_action", doc = "Creates a file write action.", objectType = SkylarkRuleContext.class, - returnType = Environment.NoneType.class, - optionalParams = { - @Param(name = "executable", type = Boolean.class, - doc = "whether the output file should be executable (default is False)"), - }, - mandatoryParams = { + returnType = FileWriteAction.class, + mandatoryPositionals = { + @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")}) + @Param(name = "content", type = String.class, doc = "the contents of the file")}, + optionalPositionals = { + @Param(name = "executable", type = Boolean.class, + doc = "whether the output file should be executable (default is False)")}) private static final SkylarkFunction createFileWriteAction = new SimpleSkylarkFunction("file_action") { @@ -204,18 +215,22 @@ public class SkylarkRuleImplementationFunctions { } }; - @SkylarkBuiltin(name = "template_action", + @SkylarkSignature(name = "template_action", doc = "Creates a template expansion action.", objectType = SkylarkRuleContext.class, - returnType = Environment.NoneType.class, - mandatoryParams = { - @Param(name = "template", type = Artifact.class, doc = "the template file"), - @Param(name = "output", type = Artifact.class, doc = "the output file"), - @Param(name = "substitutions", type = Map.class, - doc = "substitutions to make when expanding the template")}, - optionalParams = { - @Param(name = "executable", type = Boolean.class, - doc = "whether the output file should be executable (default is False)")}) + returnType = TemplateExpansionAction.class, + mandatoryPositionals = { + @Param(name = "self", type = SkylarkRuleContext.class, doc = "this context")}, + mandatoryNamedOnly = { + @Param(name = "template", type = Artifact.class, + doc = "the template file"), + @Param(name = "output", type = Artifact.class, + doc = "the output file"), + @Param(name = "substitutions", type = Map.class, + doc = "substitutions to make when expanding the template")}, + optionalNamedOnly = { + @Param(name = "executable", type = Boolean.class, + doc = "whether the output file should be executable (default is False)")}) private static final SkylarkFunction createTemplateAction = new SimpleSkylarkFunction("template_action") { @@ -245,12 +260,13 @@ public class SkylarkRuleImplementationFunctions { * A built in Skylark helper function to access the * Transitive info providers of Transitive info collections. */ - @SkylarkBuiltin(name = "provider", + @SkylarkSignature(name = "provider", doc = "Returns the transitive info provider provided by the target.", - mandatoryParams = { - @Param(name = "target", type = TransitiveInfoCollection.class, - doc = "the configured target which provides the provider"), - @Param(name = "type", type = String.class, doc = "the class type of the provider")}) + mandatoryPositionals = { + @Param(name = "target", type = TransitiveInfoCollection.class, + doc = "the configured target which provides the provider"), + @Param(name = "type", type = String.class, doc = "the class type of the provider")}, + useLocation = true) private static final SkylarkFunction provider = new SimpleSkylarkFunction("provider") { @Override public Object call(Map params, Location loc) throws EvalException { @@ -271,21 +287,28 @@ public class SkylarkRuleImplementationFunctions { }; // TODO(bazel-team): Remove runfile states from Skylark. - @SkylarkBuiltin(name = "runfiles", + @SkylarkSignature(name = "runfiles", doc = "Creates a runfiles object.", objectType = SkylarkRuleContext.class, returnType = Runfiles.class, - optionalParams = { - @Param(name = "files", type = SkylarkList.class, generic1 = Artifact.class, - 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 NestedSets - // we can remove this and just use files = [file] + list(set) - @Param(name = "transitive_files", type = SkylarkNestedSet.class, generic1 = Artifact.class, - doc = "The (transitive) set of files to be added to the runfiles."), - @Param(name = "collect_data", type = Boolean.class, doc = "Whether to collect the data " - + "runfiles from the dependencies in srcs, data and deps attributes."), - @Param(name = "collect_default", type = Boolean.class, doc = "Whether to collect the default " - + "runfiles from the dependencies in srcs, data and deps attributes.")}) + mandatoryPositionals = { + @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context.")}, + optionalPositionals = { + @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 + // NestedSets we can remove this and just use files = [file] + list(set) + // Also, allow empty set for init + @Param(name = "transitive_files", type = SkylarkNestedSet.class, generic1 = Artifact.class, + noneable = true, defaultValue = "None", + doc = "The (transitive) set of files to be added to the runfiles."), + @Param(name = "collect_data", type = Boolean.class, defaultValue = "False", + doc = "Whether to collect the data " + + "runfiles from the dependencies in srcs, data and deps attributes."), + @Param(name = "collect_default", type = Boolean.class, defaultValue = "False", + doc = "Whether to collect the default " + + "runfiles from the dependencies in srcs, data and deps attributes.")}, + useLocation = true) private static final SkylarkFunction runfiles = new SimpleSkylarkFunction("runfiles") { @Override public Object call(Map params, Location loc) throws EvalException, @@ -309,15 +332,16 @@ public class SkylarkRuleImplementationFunctions { } }; - @SkylarkBuiltin(name = "command_helper", doc = "Experimental. Creates a command helper class.", + @SkylarkSignature(name = "command_helper", doc = "Experimental. Creates a command helper class.", objectType = SkylarkRuleContext.class, returnType = CommandHelper.class, - mandatoryParams = { - @Param(name = "tools", type = SkylarkList.class, generic1 = TransitiveInfoCollection.class, - doc = "list of tools (list of targets)"), - @Param(name = "label_dict", type = Map.class, - doc = "dictionary of resolved labels and the corresponding list of Files " - + "(a dict of Label : list of Files)")}) + mandatoryPositionals = { + @Param(name = "self", type = SkylarkRuleContext.class, doc = "this RuleContext"), + @Param(name = "tools", type = SkylarkList.class, generic1 = TransitiveInfoCollection.class, + doc = "list of tools (list of targets)"), + @Param(name = "label_dict", type = Map.class, defaultValue = "{}", + doc = "dictionary of resolved labels and the corresponding list of Files " + + "(a dict of Label : list of Files)")}) private static final SkylarkFunction createCommandHelper = new SimpleSkylarkFunction("command_helper") { @SuppressWarnings("unchecked") -- cgit v1.2.3