diff options
author | cparsons <cparsons@google.com> | 2018-05-07 05:58:01 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-05-07 05:59:20 -0700 |
commit | 30d877ab145e45cdba725decc5a4967492f19c43 (patch) | |
tree | 12850c1cd6f8c776bccd4c45f4234a1c0b0515d0 /src | |
parent | 589f6c39947863237e507fc6ca7d00ec4be3e69b (diff) |
Migrate almost all Skylark global modules to skylarkbuildapi
There are still a few global @SkylarkSignature-annotated top-level objects that need to be migrated in SkylarkRuleClassFunctions, but this migrates everything else.
RELNOTES: None.
PiperOrigin-RevId: 195652038
Diffstat (limited to 'src')
8 files changed, 768 insertions, 578 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkCommandLine.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkCommandLine.java index 6dd7b7f258..d96712650a 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkCommandLine.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkCommandLine.java @@ -16,36 +16,13 @@ package com.google.devtools.build.lib.analysis.skylark; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.skylarkinterface.Param; -import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; +import com.google.devtools.build.lib.skylarkbuildapi.SkylarkCommandLineApi; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; /** A Skylark module class to create memory efficient command lines. */ -@SkylarkModule( - name = "cmd_helper", - namespace = true, - category = SkylarkModuleCategory.BUILTIN, - doc = "Deprecated. Module for creating memory efficient command lines." -) -public class SkylarkCommandLine { +public class SkylarkCommandLine implements SkylarkCommandLineApi { - @SkylarkCallable( - name = "join_paths", - doc = - "Deprecated. Creates a single command line argument joining the paths of a set " - + "of files on the separator string.", - 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." - ) - } - ) + @Override public String joinPaths(String separator, SkylarkNestedSet files) { NestedSet<Artifact> artifacts = files.getSet(Artifact.class); // TODO(bazel-team): lazy evaluate diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkFileType.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkFileType.java index 814d199000..85caec5181 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkFileType.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkFileType.java @@ -17,9 +17,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; +import com.google.devtools.build.lib.skylarkbuildapi.FileTypeApi; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.util.FileType; @@ -27,15 +25,8 @@ import com.google.devtools.build.lib.util.FileTypeSet; import java.util.List; /** A wrapper class for FileType and FileTypeSet functionality in Skylark. */ -@SkylarkModule( - name = "FileType", - category = SkylarkModuleCategory.NONE, - doc = - "Deprecated. File type for file filtering. Can be used to filter collections of labels " - + "for certain file types." -) @AutoCodec -public class SkylarkFileType { +public class SkylarkFileType implements FileTypeApi<Artifact> { private final FileType fileType; @@ -52,16 +43,7 @@ public class SkylarkFileType { return FileTypeSet.of(fileType); } - @SkylarkCallable(doc = - "Returns a list created from the elements of the parameter containing all the " - + "<a href=\"File.html\"><code>File</code></a>s that match the FileType. The parameter " - + "must be a <a href=\"depset.html\"><code>depset</code></a> or a " - + "<a href=\"list.html\"><code>list</code></a>.") - // toIterablesStrict() will ensure the parameter is a SkylarkNestedSet or a java Iterable - // (including SkylarkList). If it fails, the error location information will be inserted by the - // Skylark interface framework. If there's a dynamic type error on a non-Artifact element, the - // error will also be handled by the Skylark interface framework. - @SuppressWarnings("unchecked") + @Override public ImmutableList<Artifact> filter(Object filesUnchecked) throws EvalException { return ImmutableList.copyOf( FileType.filter( diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java index 59a711a30e..4933d0a48e 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java @@ -32,6 +32,7 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.ActionsProvider; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.DefaultInfo; @@ -71,11 +72,8 @@ import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier; import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.packages.TestSize; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.skylarkbuildapi.SkylarkRuleFunctionsApi; import com.google.devtools.build.lib.skylarkinterface.Param; -import com.google.devtools.build.lib.skylarkinterface.ParamType; -import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; -import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor; -import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature; import com.google.devtools.build.lib.syntax.BaseFunction; @@ -100,8 +98,7 @@ import java.util.concurrent.ExecutionException; /** * A helper class to provide an easier API for Skylark rule definitions. */ -@SkylarkGlobalLibrary -public class SkylarkRuleClassFunctions { +public class SkylarkRuleClassFunctions implements SkylarkRuleFunctionsApi<Artifact> { // TODO(bazel-team): Copied from ConfiguredRuleClassProvider for the transition from built-in // rules to skylark extensions. Using the same instance would require a large refactoring. @@ -293,47 +290,7 @@ public class SkylarkRuleClassFunctions { ) private static final NativeProvider<?> actions = ActionsProvider.SKYLARK_CONSTRUCTOR; - @SkylarkCallable( - name = "provider", - doc = - "Creates a declared provider 'constructor'. The return value of this " - + "function can be used to create \"struct-like\" values. Example:<br>" - + "<pre class=\"language-python\">data = provider()\n" - + "d = data(x = 2, y = 3)\n" - + "print(d.x + d.y) # prints 5</pre>", - parameters = { - @Param( - name = "doc", - type = String.class, - legacyNamed = true, - defaultValue = "''", - doc = - "A description of the provider that can be extracted by documentation generating tools." - ), - @Param( - name = "fields", - doc = "If specified, restricts the set of allowed fields. <br>" - + "Possible values are:" - + "<ul>" - + " <li> list of fields:<br>" - + " <pre class=\"language-python\">provider(fields = ['a', 'b'])</pre><p>" - + " <li> dictionary field name -> documentation:<br>" - + " <pre class=\"language-python\">provider(\n" - + " fields = { 'a' : 'Documentation for a', 'b' : 'Documentation for b' })</pre>" - + "</ul>" - + "All fields are optional.", - allowedTypes = { - @ParamType(type = SkylarkList.class, generic1 = String.class), - @ParamType(type = SkylarkDict.class) - }, - noneable = true, - named = true, - positional = false, - defaultValue = "None" - ) - }, - useLocation = true - ) + @Override public Provider provider(String doc, Object fields, Location location) throws EvalException { Iterable<String> fieldNames = null; if (fields instanceof SkylarkList<?>) { @@ -355,199 +312,7 @@ public class SkylarkRuleClassFunctions { } // TODO(bazel-team): implement attribute copy and other rule properties - @SkylarkCallable( - name = "rule", - doc = - "Creates a new rule, which can be called from a BUILD file or a macro to create targets." - + "<p>Rules must be assigned to global variables in a .bzl file; the name of the " - + "global variable is the rule's name." - + "<p>Test rules are required to have a name ending in <code>_test</code>, while all " - + "other rules must not have this suffix. (This restriction applies only to rules, not " - + "to their targets.)", - parameters = { - @Param( - name = "implementation", - type = BaseFunction.class, - legacyNamed = true, - 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." - ), - @Param( - name = "test", - type = Boolean.class, - legacyNamed = true, - defaultValue = "False", - doc = - "Whether this rule is a test rule, that is, whether it may be the subject of a " - + "<code>blaze test</code> command. All test rules are automatically considered " - + "<a href='#rule.executable'>executable</a>; it is unnecessary (and discouraged) " - + "to explicitly set <code>executable = True</code> for a test rule. See the " - + "<a href='../rules.$DOC_EXT#executable-rules-and-test-rules'>Rules page</a> for " - + "more information." - ), - @Param( - name = "attrs", - type = SkylarkDict.class, - legacyNamed = true, - 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 <a href=\"attr.html\">attr</a> module). " - + "Attributes starting with <code>_</code> are private, and can be used to " - + "add an implicit dependency on a label. The attribute <code>name</code> is " - + "implicitly added and must not be specified. Attributes " - + "<code>visibility</code>, <code>deprecation</code>, <code>tags</code>, " - + "<code>testonly</code>, and <code>features</code> are implicitly added and " - + "cannot be overridden." - ), - // TODO(bazel-team): need to give the types of these builtin attributes - @Param( - name = "outputs", - type = SkylarkDict.class, - legacyNamed = true, - callbackEnabled = true, - noneable = true, - defaultValue = "None", - doc = - "<b>Experimental:</b> This API is in the process of being redesigned." - + "<p>A schema for defining predeclared outputs. Unlike <a href='attr.html#output'>" - + "<code>output</code></a> and <a href='attr.html#output_list'><code>output_list" - + "</code></a> attributes, the user does not specify the labels for these files. " - + "See the <a href='../rules.$DOC_EXT#files'>Rules page</a> for more on " - + "predeclared outputs." - + "<p>The value of this argument is either a dictionary or a callback function " - + "that produces a dictionary. The callback works similar to computed dependency " - + "attributes: The function's parameter names are matched against the rule's " - + "attributes, so for example if you pass <code>outputs = _my_func</code> with the " - + "definition <code>def _my_func(srcs, deps): ...</code>, the function has access " - + "to the attributes <code>srcs</code> and <code>deps</code>. Whether the " - + "dictionary is specified directly or via a function, it is interpreted as " - + "follows." - + "<p>Each entry in the dictionary creates a predeclared output where the key is " - + "an identifier and the value is a string template that determines the output's " - + "label. In the rule's implementation function, the identifier becomes the field " - + "name used to access the output's <a href='File.html'><code>File</code></a> in " - + "<a href='ctx.html#outputs'><code>ctx.outputs</code></a>. The output's label has " - + "the same package as the rule, and the part after the package is produced by " - + "substituting each placeholder of the form <code>\"%{ATTR}\"</code> with a " - + "string formed from the value of the attribute <code>ATTR</code>:" - + "<ul>" - + "<li>String-typed attributes are substituted verbatim." - + "<li>Label-typed attributes become the part of the label after the package, " - + "minus the file extension. For example, the label <code>\"//pkg:a/b.c\"</code> " - + "becomes <code>\"a/b\"</code>." - + "<li>Output-typed attributes become the part of the label after the package, " - + "including the file extension (for the above example, <code>\"a/b.c\"</code>)." - + "<li>All list-typed attributes (for example, <code>attr.label_list</code>) used " - + "in placeholders are required to have <i>exactly one element</i>. Their " - + "conversion is the same as their non-list version (<code>attr.label</code>)." - + "<li>Other attribute types may not appear in placeholders." - + "<li>The special non-attribute placeholders <code>%{dirname}</code> and <code>" - + "%{basename}</code> expand to those parts of the rule's label, excluding its " - + "package. For example, in <code>\"//pkg:a/b.c\"</code>, the dirname is <code>" - + "a</code> and the basename is <code>b.c</code>." - + "</ul>" - + "<p>In practice, the most common substitution placeholder is " - + "<code>\"%{name}\"</code>. For example, for a target named \"foo\", the outputs " - + "dict <code>{\"bin\": \"%{name}.exe\"}</code> predeclares an output named " - + "<code>foo.exe</code> that is accessible in the implementation function as " - + "<code>ctx.outputs.bin</code>." - ), - @Param( - name = "executable", - type = Boolean.class, - legacyNamed = true, - defaultValue = "False", - doc = - "Whether this rule is considered executable, that is, whether it may be the subject of " - + "a <code>blaze run</code> command. See the " - + "<a href='../rules.$DOC_EXT#executable-rules-and-test-rules'>Rules page</a> for " - + "more information." - ), - @Param( - name = "output_to_genfiles", - type = Boolean.class, - legacyNamed = true, - defaultValue = "False", - doc = - "If true, the files will be generated in the genfiles directory instead of the " - + "bin directory. Unless you need it for compatibility with existing rules " - + "(e.g. when generating header files for C++), do not set this flag." - ), - @Param( - name = "fragments", - type = SkylarkList.class, - legacyNamed = true, - generic1 = String.class, - defaultValue = "[]", - doc = - "List of names of configuration fragments that the rule requires " - + "in target configuration." - ), - @Param( - name = "host_fragments", - type = SkylarkList.class, - legacyNamed = true, - generic1 = String.class, - defaultValue = "[]", - doc = - "List of names of configuration fragments that the rule requires " - + "in host configuration." - ), - @Param( - name = "_skylark_testable", - type = Boolean.class, - legacyNamed = true, - defaultValue = "False", - doc = - "<i>(Experimental)</i><br/><br/>" - + "If true, this rule will expose its actions for inspection by rules that " - + "depend on it via an <a href=\"globals.html#Actions\">Actions</a> " - + "provider. The provider is also available to the rule itself by calling " - + "<a href=\"ctx.html#created_actions\">ctx.created_actions()</a>." - + "<br/><br/>" - + "This should only be used for testing the analysis-time behavior of " - + "Skylark rules. This flag may be removed in the future." - ), - @Param( - name = "toolchains", - type = SkylarkList.class, - legacyNamed = true, - generic1 = String.class, - defaultValue = "[]", - doc = - "<i>(Experimental)</i><br/><br/>" - + "If set, the set of toolchains this rule requires. Toolchains will be " - + "found by checking the current platform, and provided to the rule " - + "implementation via <code>ctx.toolchain</code>." - ), - @Param( - name = "doc", - type = String.class, - legacyNamed = true, - defaultValue = "''", - doc = "A description of the rule that can be extracted by documentation generating tools." - ), - @Param( - name = "provides", - type = SkylarkList.class, - named = true, - positional = false, - defaultValue = "[]", - doc = - "A list of providers this rule is guaranteed to provide. " - + "It is an error if a provider is listed here and the rule " - + "implementation function does not return it." - ), - }, - useAst = true, - useEnvironment = true - ) + @Override @SuppressWarnings({"rawtypes", "unchecked"}) // castMap produces // an Attribute.Builder instead of a Attribute.Builder<?> but it's OK. public BaseFunction rule( @@ -690,122 +455,7 @@ public class SkylarkRuleClassFunctions { return requiredToolchains.build(); } - @SkylarkCallable( - name = "aspect", - doc = - "Creates a new aspect. The result of this function must be stored in a global value. " - + "Please see the <a href=\"../aspects.md\">introduction to Aspects</a> for more " - + "details.", - parameters = { - @Param( - name = "implementation", - type = BaseFunction.class, - legacyNamed = true, - 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 <a href=\"ctx.html\">ctx</a>. Attributes of the target are " - + "available via ctx.rule field. The function is called during the analysis " - + "phase for each application of an aspect to a target." - ), - @Param( - name = "attr_aspects", - type = SkylarkList.class, - legacyNamed = true, - generic1 = String.class, - defaultValue = "[]", - doc = - "List of attribute names. The aspect propagates along dependencies specified " - + "by attributes of a target with this name. The list can also contain a single " - + "string '*': in that case aspect propagates along all dependencies of a target." - ), - @Param( - name = "attrs", - type = SkylarkDict.class, - legacyNamed = true, - noneable = true, - defaultValue = "None", - doc = - "dictionary to declare all the attributes of the aspect. " - + "It maps from an attribute name to an attribute object " - + "(see <a href=\"attr.html\">attr</a> module). " - + "Aspect attributes are available to implementation function as fields of ctx " - + "parameter. Implicit attributes starting with <code>_</code> must have default " - + "values, and have type <code>label</code> or <code>label_list</code>. " - + "Explicit attributes must have type <code>string</code>, and must use the " - + "<code>values</code> restriction. If explicit attributes are present, the " - + "aspect can only be used with rules that have attributes of the same name and " - + "type, with valid values." - ), - @Param( - name = "required_aspect_providers", - type = SkylarkList.class, - legacyNamed = true, - defaultValue = "[]", - doc = - "Allow the aspect to inspect other aspects. If the aspect propagates along " - + "a dependency, and the underlying rule sends a different aspect along that " - + "dependency, and that aspect provides one of the providers listed here, this " - + "aspect will see the providers provided by that aspect. " - + "<p>The value should be either a list of providers, or a " - + "list of lists of providers. This aspect will 'see' the underlying aspects that " - + "provide ALL providers from at least ONE of these lists. A single list of " - + "providers will be automatically converted to a list containing one list of " - + "providers." - ), - @Param( - name = "provides", - type = SkylarkList.class, - legacyNamed = true, - defaultValue = "[]", - doc = - "A list of providers this aspect is guaranteed to provide. " - + "It is an error if a provider is listed here and the aspect " - + "implementation function does not return it." - ), - @Param( - name = "fragments", - type = SkylarkList.class, - legacyNamed = true, - generic1 = String.class, - defaultValue = "[]", - doc = - "List of names of configuration fragments that the aspect requires " - + "in target configuration." - ), - @Param( - name = "host_fragments", - type = SkylarkList.class, - legacyNamed = true, - generic1 = String.class, - defaultValue = "[]", - doc = - "List of names of configuration fragments that the aspect requires " - + "in host configuration." - ), - @Param( - name = "toolchains", - type = SkylarkList.class, - legacyNamed = true, - generic1 = String.class, - defaultValue = "[]", - doc = - "<i>(Experimental)</i><br/><br/>" - + "If set, the set of toolchains this rule requires. Toolchains will be " - + "found by checking the current platform, and provided to the rule " - + "implementation via <code>ctx.toolchain</code>." - ), - @Param( - name = "doc", - type = String.class, - legacyNamed = true, - defaultValue = "''", - doc = "A description of the aspect that can be extracted by documentation generating tools." - ) - }, - useEnvironment = true, - useAst = true - ) + @Override public SkylarkAspect aspect( BaseFunction implementation, SkylarkList attributeAspects, @@ -1050,36 +700,7 @@ public class SkylarkRuleClassFunctions { ImmutableList.of( SkylarkProvider.class, SkylarkDefinedAspect.class, SkylarkRuleFunction.class); - @SkylarkCallable( - 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. " - + "The argument must refer to an absolute label. " - + "Example: <br><pre class=language-python>Label(\"//tools:default\")</pre>", - parameters = { - @Param(name = "label_string", type = String.class, legacyNamed = true, - doc = "the label string."), - @Param( - name = "relative_to_caller_repository", - type = Boolean.class, - defaultValue = "False", - named = true, - positional = false, - doc = - "Deprecated. Do not use. " - + "When relative_to_caller_repository is True and the calling thread is a rule's " - + "implementation function, then a repo-relative label //foo:bar is resolved " - + "relative to the rule's repository. For calls to Label from any other " - + "thread, or calls in which the relative_to_caller_repository flag is False, " - + "a repo-relative label is resolved relative to the file in which the " - + "Label() call appears." - ) - }, - useLocation = true, - useEnvironment = true - ) - @SkylarkConstructor(objectType = Label.class) + @Override public Label label( String labelString, Boolean relativeToCallerRepository, Location loc, Environment env) throws EvalException { @@ -1100,26 +721,7 @@ public class SkylarkRuleClassFunctions { } } - @SkylarkCallable( - name = "FileType", - doc = - "Deprecated. Creates a file filter from a list of strings. For example, to match " - + "files ending with .cc or .cpp, use: " - + "<pre class=language-python>FileType([\".cc\", \".cpp\"])</pre>", - parameters = { - @Param( - name = "types", - type = SkylarkList.class, - legacyNamed = true, - generic1 = String.class, - defaultValue = "[]", - doc = "a list of the accepted file extensions." - ) - }, - useLocation = true, - useEnvironment = true - ) - @SkylarkConstructor(objectType = SkylarkFileType.class) + @Override public SkylarkFileType fileType(SkylarkList types, Location loc, Environment env) throws EvalException { if (env.getSemantics().incompatibleDisallowFileType()) { 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 43220320f5..4c9e7d8641 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 @@ -16,10 +16,7 @@ package com.google.devtools.build.lib.packages; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.events.Location; -import com.google.devtools.build.lib.skylarkinterface.Param; -import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; +import com.google.devtools.build.lib.skylarkbuildapi.SkylarkNativeModuleApi; import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.FuncallExpression; @@ -32,55 +29,9 @@ import com.google.devtools.build.lib.syntax.Type.ConversionException; * A class for the Skylark native module. TODO(laurentlb): Some definitions are duplicated from * PackageFactory. */ -@SkylarkModule( - name = "native", - category = SkylarkModuleCategory.BUILTIN, - doc = - "A built-in module to support native rules and other package helper functions. " - + "All native rules appear as functions in this module, e.g. " - + "<code>native.cc_library</code>. " - + "Note that the native module is only available in the loading phase " - + "(i.e. for macros, not for rule implementations). Attributes will ignore " - + "<code>None</code> values, and treat them as if the attribute was unset.<br>" - + "The following functions are also available:" -) -public class SkylarkNativeModule { +public class SkylarkNativeModule implements SkylarkNativeModuleApi { - @SkylarkCallable( - name = "glob", - doc = - "Glob returns a list of every file in the current package that:<ul>\n" - + "<li>Matches at least one pattern in <code>include</code>.</li>\n" - + "<li>Does not match any of the patterns in <code>exclude</code> " - + "(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>).", - parameters = { - @Param( - name = "include", - type = SkylarkList.class, - generic1 = String.class, - defaultValue = "[]", - doc = "The list of glob patterns to include." - ), - @Param( - name = "exclude", - type = SkylarkList.class, - generic1 = String.class, - defaultValue = "[]", - doc = "The list of glob patterns to exclude." - ), - // TODO(bazel-team): accept booleans as well as integers? (and eventually migrate?) - @Param( - name = "exclude_directories", - type = Integer.class, - defaultValue = "1", - doc = "A flag whether to exclude directories or not." - ) - }, - useAst = true, - useEnvironment = true - ) + @Override public SkylarkList<?> glob( SkylarkList<?> include, SkylarkList<?> exclude, @@ -92,17 +43,7 @@ public class SkylarkNativeModule { return PackageFactory.callGlob(null, include, exclude, excludeDirectories != 0, ast, env); } - @SkylarkCallable( - name = "existing_rule", - doc = - "Returns a dictionary representing the attributes of a previously defined rule, " - + "or None if the rule does not exist.", - parameters = { - @Param(name = "name", type = String.class, doc = "The name of the rule.") - }, - useAst = true, - useEnvironment = true - ) + @Override public Object existingRule(String name, FuncallExpression ast, Environment env) throws EvalException, InterruptedException { env.checkLoadingOrWorkspacePhase("native.existing_rule", ast.getLocation()); @@ -118,15 +59,7 @@ public class SkylarkNativeModule { If necessary, we could allow filtering by tag (anytag, alltags), name (regexp?), kind ? For now, we ignore this, since users can implement it in Skylark. */ - @SkylarkCallable( - name = "existing_rules", - doc = - "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.", - useAst = true, - useEnvironment = true - ) + @Override public SkylarkDict<String, SkylarkDict<String, Object>> existingRules( FuncallExpression ast, Environment env) throws EvalException, InterruptedException { @@ -134,19 +67,7 @@ public class SkylarkNativeModule { return PackageFactory.callGetRulesFunction(ast, env); } - @SkylarkCallable(name = "package_group", - 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.", - 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 = "[]", named = true, positional = false, - doc = "A complete enumeration of packages in this group."), - @Param(name = "includes", type = SkylarkList.class, generic1 = String.class, - defaultValue = "[]", named = true, positional = false, - doc = "Other package groups that are included in this one.")}, - useAst = true, useEnvironment = true) + @Override public Runtime.NoneType packageGroup(String name, SkylarkList<?> packages, SkylarkList<?> includes, FuncallExpression ast, Environment env) throws EvalException { @@ -154,20 +75,7 @@ public class SkylarkNativeModule { return PackageFactory.callPackageFunction(name, packages, includes, ast, env); } - @SkylarkCallable(name = "exports_files", - doc = "Specifies a list of files belonging to this package that are exported to other " - + "packages but not otherwise mentioned.", - parameters = { - @Param(name = "srcs", type = SkylarkList.class, generic1 = String.class, - 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, 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, - defaultValue = "None", doc = "Licenses to be specified.")}, - useAst = true, useEnvironment = true) + @Override public Runtime.NoneType exportsFiles(SkylarkList<?> srcs, Object visibility, Object licenses, FuncallExpression ast, Environment env) throws EvalException { @@ -175,19 +83,7 @@ public class SkylarkNativeModule { return PackageFactory.callExportsFiles(srcs, visibility, licenses, ast, env); } - @SkylarkCallable( - name = "package_name", - doc = - "The name of the package being evaluated. " - + "For example, in the BUILD file <code>some/package/BUILD</code>, its value " - + "will be <code>some/package</code>. " - + "If the BUILD file calls a function defined in a .bzl file, " - + "<code>package_name()</code> will match the caller BUILD file package. " - + "This function is equivalent to the deprecated variable <code>PACKAGE_NAME</code>.", - parameters = {}, - useAst = true, - useEnvironment = true - ) + @Override public String packageName(FuncallExpression ast, Environment env) throws EvalException { env.checkLoadingPhase("native.package_name", ast.getLocation()); @@ -196,19 +92,7 @@ public class SkylarkNativeModule { return packageId.getPackageFragment().getPathString(); } - @SkylarkCallable( - name = "repository_name", - doc = - "The name of the repository the rule or build extension is called from. " - + "For example, in packages that are called into existence by the WORKSPACE stanza " - + "<code>local_repository(name='local', path=...)</code> it will be set to " - + "<code>@local</code>. In packages in the main repository, it will be set to " - + "<code>@</code>. This function is equivalent to the deprecated variable " - + "<code>REPOSITORY_NAME</code>.", - parameters = {}, - useLocation = true, - useEnvironment = true - ) + @Override public String repositoryName(Location location, Environment env) throws EvalException { env.checkLoadingPhase("native.repository_name", location); diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/FileTypeApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/FileTypeApi.java new file mode 100644 index 0000000000..cbff500d36 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/FileTypeApi.java @@ -0,0 +1,41 @@ +// Copyright 2018 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.skylarkbuildapi; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; +import com.google.devtools.build.lib.syntax.EvalException; + +/** + * Interface for an object representing the type of file. + */ +@SkylarkModule( + name = "FileType", + category = SkylarkModuleCategory.NONE, + doc = + "Deprecated. File type for file filtering. Can be used to filter collections of labels " + + "for certain file types." +) +public interface FileTypeApi<FileApiT extends FileApi> { + + @SkylarkCallable(doc = + "Returns a list created from the elements of the parameter containing all the " + + "<a href=\"File.html\"><code>File</code></a>s that match the FileType. The parameter " + + "must be a <a href=\"depset.html\"><code>depset</code></a> or a " + + "<a href=\"list.html\"><code>list</code></a>.") + public ImmutableList<FileApiT> filter(Object filesUnchecked) throws EvalException; +} diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkCommandLineApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkCommandLineApi.java new file mode 100644 index 0000000000..9d5ee49393 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkCommandLineApi.java @@ -0,0 +1,50 @@ +// Copyright 2018 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.skylarkbuildapi; + +import com.google.devtools.build.lib.skylarkinterface.Param; +import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; +import com.google.devtools.build.lib.syntax.SkylarkNestedSet; + +/** + * Interface for a module associated with creating efficient command lines. + */ +@SkylarkModule( + name = "cmd_helper", + namespace = true, + category = SkylarkModuleCategory.BUILTIN, + doc = "Deprecated. Module for creating memory efficient command lines." +) +public interface SkylarkCommandLineApi { + + @SkylarkCallable( + name = "join_paths", + doc = + "Deprecated. Creates a single command line argument joining the paths of a set " + + "of files on the separator string.", + parameters = { + @Param(name = "separator", type = String.class, doc = "the separator string to join on."), + @Param( + name = "files", + type = SkylarkNestedSet.class, + generic1 = FileApi.class, + doc = "the files to concatenate." + ) + } + ) + public String joinPaths(String separator, SkylarkNestedSet files); +} diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkNativeModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkNativeModuleApi.java new file mode 100644 index 0000000000..3e73359a8d --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkNativeModuleApi.java @@ -0,0 +1,182 @@ +// Copyright 2018 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.skylarkbuildapi; + +import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.skylarkinterface.Param; +import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; +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.Runtime; +import com.google.devtools.build.lib.syntax.SkylarkDict; +import com.google.devtools.build.lib.syntax.SkylarkList; + +/** + * Interface for a module with native rule and package helper functions. + */ +@SkylarkModule( + name = "native", + category = SkylarkModuleCategory.BUILTIN, + doc = + "A built-in module to support native rules and other package helper functions. " + + "All native rules appear as functions in this module, e.g. " + + "<code>native.cc_library</code>. " + + "Note that the native module is only available in the loading phase " + + "(i.e. for macros, not for rule implementations). Attributes will ignore " + + "<code>None</code> values, and treat them as if the attribute was unset.<br>" + + "The following functions are also available:" +) +public interface SkylarkNativeModuleApi { + + @SkylarkCallable( + name = "glob", + doc = + "Glob returns a list of every file in the current package that:<ul>\n" + + "<li>Matches at least one pattern in <code>include</code>.</li>\n" + + "<li>Does not match any of the patterns in <code>exclude</code> " + + "(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>).", + parameters = { + @Param( + name = "include", + type = SkylarkList.class, + generic1 = String.class, + defaultValue = "[]", + doc = "The list of glob patterns to include." + ), + @Param( + name = "exclude", + type = SkylarkList.class, + generic1 = String.class, + defaultValue = "[]", + doc = "The list of glob patterns to exclude." + ), + // TODO(bazel-team): accept booleans as well as integers? (and eventually migrate?) + @Param( + name = "exclude_directories", + type = Integer.class, + defaultValue = "1", + doc = "A flag whether to exclude directories or not." + ) + }, + useAst = true, + useEnvironment = true + ) + public SkylarkList<?> glob( + SkylarkList<?> include, + SkylarkList<?> exclude, + Integer excludeDirectories, + FuncallExpression ast, + Environment env) + throws EvalException, InterruptedException; + + @SkylarkCallable( + name = "existing_rule", + doc = + "Returns a dictionary representing the attributes of a previously defined rule, " + + "or None if the rule does not exist.", + parameters = { + @Param(name = "name", type = String.class, doc = "The name of the rule.") + }, + useAst = true, + useEnvironment = true + ) + public Object existingRule(String name, FuncallExpression ast, Environment env) + throws EvalException, InterruptedException; + + @SkylarkCallable( + name = "existing_rules", + doc = + "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.", + useAst = true, + useEnvironment = true + ) + public SkylarkDict<String, SkylarkDict<String, Object>> existingRules( + FuncallExpression ast, Environment env) + throws EvalException, InterruptedException; + + @SkylarkCallable(name = "package_group", + 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.", + 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 = "[]", named = true, positional = false, + doc = "A complete enumeration of packages in this group."), + @Param(name = "includes", type = SkylarkList.class, generic1 = String.class, + defaultValue = "[]", named = true, positional = false, + doc = "Other package groups that are included in this one.")}, + useAst = true, useEnvironment = true) + public Runtime.NoneType packageGroup(String name, SkylarkList<?> packages, + SkylarkList<?> includes, + FuncallExpression ast, Environment env) throws EvalException; + + @SkylarkCallable(name = "exports_files", + doc = "Specifies a list of files belonging to this package that are exported to other " + + "packages but not otherwise mentioned.", + parameters = { + @Param(name = "srcs", type = SkylarkList.class, generic1 = String.class, + 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, 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, + defaultValue = "None", doc = "Licenses to be specified.")}, + useAst = true, useEnvironment = true) + public Runtime.NoneType exportsFiles(SkylarkList<?> srcs, Object visibility, Object licenses, + FuncallExpression ast, Environment env) + throws EvalException; + + @SkylarkCallable( + name = "package_name", + doc = + "The name of the package being evaluated. " + + "For example, in the BUILD file <code>some/package/BUILD</code>, its value " + + "will be <code>some/package</code>. " + + "If the BUILD file calls a function defined in a .bzl file, " + + "<code>package_name()</code> will match the caller BUILD file package. " + + "This function is equivalent to the deprecated variable <code>PACKAGE_NAME</code>.", + parameters = {}, + useAst = true, + useEnvironment = true + ) + public String packageName(FuncallExpression ast, Environment env) + throws EvalException; + + @SkylarkCallable( + name = "repository_name", + doc = + "The name of the repository the rule or build extension is called from. " + + "For example, in packages that are called into existence by the WORKSPACE stanza " + + "<code>local_repository(name='local', path=...)</code> it will be set to " + + "<code>@local</code>. In packages in the main repository, it will be set to " + + "<code>@</code>. This function is equivalent to the deprecated variable " + + "<code>REPOSITORY_NAME</code>.", + parameters = {}, + useLocation = true, + useEnvironment = true + ) + public String repositoryName(Location location, Environment env) + throws EvalException; +} diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java new file mode 100644 index 0000000000..53d25e8073 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java @@ -0,0 +1,472 @@ +// Copyright 2018 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.skylarkbuildapi; + +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.skylarkinterface.Param; +import com.google.devtools.build.lib.skylarkinterface.ParamType; +import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor; +import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary; +import com.google.devtools.build.lib.syntax.BaseFunction; +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.SkylarkDict; +import com.google.devtools.build.lib.syntax.SkylarkList; + +/** + * Interface for a global Skylark library containing rule-related helper and registration functions. + */ +@SkylarkGlobalLibrary +public interface SkylarkRuleFunctionsApi<FileApiT extends FileApi> { + + @SkylarkCallable( + name = "provider", + doc = + "Creates a declared provider 'constructor'. The return value of this " + + "function can be used to create \"struct-like\" values. Example:<br>" + + "<pre class=\"language-python\">data = provider()\n" + + "d = data(x = 2, y = 3)\n" + + "print(d.x + d.y) # prints 5</pre>", + parameters = { + @Param( + name = "doc", + type = String.class, + legacyNamed = true, + defaultValue = "''", + doc = + "A description of the provider that can be extracted by documentation generating tools." + ), + @Param( + name = "fields", + doc = "If specified, restricts the set of allowed fields. <br>" + + "Possible values are:" + + "<ul>" + + " <li> list of fields:<br>" + + " <pre class=\"language-python\">provider(fields = ['a', 'b'])</pre><p>" + + " <li> dictionary field name -> documentation:<br>" + + " <pre class=\"language-python\">provider(\n" + + " fields = { 'a' : 'Documentation for a', 'b' : 'Documentation for b' })</pre>" + + "</ul>" + + "All fields are optional.", + allowedTypes = { + @ParamType(type = SkylarkList.class, generic1 = String.class), + @ParamType(type = SkylarkDict.class) + }, + noneable = true, + named = true, + positional = false, + defaultValue = "None" + ) + }, + useLocation = true + ) + public ProviderApi provider(String doc, Object fields, Location location) throws EvalException; + + @SkylarkCallable( + name = "rule", + doc = + "Creates a new rule, which can be called from a BUILD file or a macro to create targets." + + "<p>Rules must be assigned to global variables in a .bzl file; the name of the " + + "global variable is the rule's name." + + "<p>Test rules are required to have a name ending in <code>_test</code>, while all " + + "other rules must not have this suffix. (This restriction applies only to rules, not " + + "to their targets.)", + parameters = { + @Param( + name = "implementation", + type = BaseFunction.class, + legacyNamed = true, + 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." + ), + @Param( + name = "test", + type = Boolean.class, + legacyNamed = true, + defaultValue = "False", + doc = + "Whether this rule is a test rule, that is, whether it may be the subject of a " + + "<code>blaze test</code> command. All test rules are automatically considered " + + "<a href='#rule.executable'>executable</a>; it is unnecessary (and discouraged) " + + "to explicitly set <code>executable = True</code> for a test rule. See the " + + "<a href='../rules.$DOC_EXT#executable-rules-and-test-rules'>Rules page</a> for " + + "more information." + ), + @Param( + name = "attrs", + type = SkylarkDict.class, + legacyNamed = true, + 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 <a href=\"attr.html\">attr</a> module). " + + "Attributes starting with <code>_</code> are private, and can be used to " + + "add an implicit dependency on a label. The attribute <code>name</code> is " + + "implicitly added and must not be specified. Attributes " + + "<code>visibility</code>, <code>deprecation</code>, <code>tags</code>, " + + "<code>testonly</code>, and <code>features</code> are implicitly added and " + + "cannot be overridden." + ), + // TODO(bazel-team): need to give the types of these builtin attributes + @Param( + name = "outputs", + type = SkylarkDict.class, + legacyNamed = true, + callbackEnabled = true, + noneable = true, + defaultValue = "None", + doc = + "<b>Experimental:</b> This API is in the process of being redesigned." + + "<p>A schema for defining predeclared outputs. Unlike <a href='attr.html#output'>" + + "<code>output</code></a> and <a href='attr.html#output_list'><code>output_list" + + "</code></a> attributes, the user does not specify the labels for these files. " + + "See the <a href='../rules.$DOC_EXT#files'>Rules page</a> for more on " + + "predeclared outputs." + + "<p>The value of this argument is either a dictionary or a callback function " + + "that produces a dictionary. The callback works similar to computed dependency " + + "attributes: The function's parameter names are matched against the rule's " + + "attributes, so for example if you pass <code>outputs = _my_func</code> with the " + + "definition <code>def _my_func(srcs, deps): ...</code>, the function has access " + + "to the attributes <code>srcs</code> and <code>deps</code>. Whether the " + + "dictionary is specified directly or via a function, it is interpreted as " + + "follows." + + "<p>Each entry in the dictionary creates a predeclared output where the key is " + + "an identifier and the value is a string template that determines the output's " + + "label. In the rule's implementation function, the identifier becomes the field " + + "name used to access the output's <a href='File.html'><code>File</code></a> in " + + "<a href='ctx.html#outputs'><code>ctx.outputs</code></a>. The output's label has " + + "the same package as the rule, and the part after the package is produced by " + + "substituting each placeholder of the form <code>\"%{ATTR}\"</code> with a " + + "string formed from the value of the attribute <code>ATTR</code>:" + + "<ul>" + + "<li>String-typed attributes are substituted verbatim." + + "<li>Label-typed attributes become the part of the label after the package, " + + "minus the file extension. For example, the label <code>\"//pkg:a/b.c\"</code> " + + "becomes <code>\"a/b\"</code>." + + "<li>Output-typed attributes become the part of the label after the package, " + + "including the file extension (for the above example, <code>\"a/b.c\"</code>)." + + "<li>All list-typed attributes (for example, <code>attr.label_list</code>) used " + + "in placeholders are required to have <i>exactly one element</i>. Their " + + "conversion is the same as their non-list version (<code>attr.label</code>)." + + "<li>Other attribute types may not appear in placeholders." + + "<li>The special non-attribute placeholders <code>%{dirname}</code> and <code>" + + "%{basename}</code> expand to those parts of the rule's label, excluding its " + + "package. For example, in <code>\"//pkg:a/b.c\"</code>, the dirname is <code>" + + "a</code> and the basename is <code>b.c</code>." + + "</ul>" + + "<p>In practice, the most common substitution placeholder is " + + "<code>\"%{name}\"</code>. For example, for a target named \"foo\", the outputs " + + "dict <code>{\"bin\": \"%{name}.exe\"}</code> predeclares an output named " + + "<code>foo.exe</code> that is accessible in the implementation function as " + + "<code>ctx.outputs.bin</code>." + ), + @Param( + name = "executable", + type = Boolean.class, + legacyNamed = true, + defaultValue = "False", + doc = + "Whether this rule is considered executable, that is, whether it may be the subject of " + + "a <code>blaze run</code> command. See the " + + "<a href='../rules.$DOC_EXT#executable-rules-and-test-rules'>Rules page</a> for " + + "more information." + ), + @Param( + name = "output_to_genfiles", + type = Boolean.class, + legacyNamed = true, + defaultValue = "False", + doc = + "If true, the files will be generated in the genfiles directory instead of the " + + "bin directory. Unless you need it for compatibility with existing rules " + + "(e.g. when generating header files for C++), do not set this flag." + ), + @Param( + name = "fragments", + type = SkylarkList.class, + legacyNamed = true, + generic1 = String.class, + defaultValue = "[]", + doc = + "List of names of configuration fragments that the rule requires " + + "in target configuration." + ), + @Param( + name = "host_fragments", + type = SkylarkList.class, + legacyNamed = true, + generic1 = String.class, + defaultValue = "[]", + doc = + "List of names of configuration fragments that the rule requires " + + "in host configuration." + ), + @Param( + name = "_skylark_testable", + type = Boolean.class, + legacyNamed = true, + defaultValue = "False", + doc = + "<i>(Experimental)</i><br/><br/>" + + "If true, this rule will expose its actions for inspection by rules that " + + "depend on it via an <a href=\"globals.html#Actions\">Actions</a> " + + "provider. The provider is also available to the rule itself by calling " + + "<a href=\"ctx.html#created_actions\">ctx.created_actions()</a>." + + "<br/><br/>" + + "This should only be used for testing the analysis-time behavior of " + + "Skylark rules. This flag may be removed in the future." + ), + @Param( + name = "toolchains", + type = SkylarkList.class, + legacyNamed = true, + generic1 = String.class, + defaultValue = "[]", + doc = + "<i>(Experimental)</i><br/><br/>" + + "If set, the set of toolchains this rule requires. Toolchains will be " + + "found by checking the current platform, and provided to the rule " + + "implementation via <code>ctx.toolchain</code>." + ), + @Param( + name = "doc", + type = String.class, + legacyNamed = true, + defaultValue = "''", + doc = "A description of the rule that can be extracted by documentation generating tools." + ), + @Param( + name = "provides", + type = SkylarkList.class, + named = true, + positional = false, + defaultValue = "[]", + doc = + "A list of providers this rule is guaranteed to provide. " + + "It is an error if a provider is listed here and the rule " + + "implementation function does not return it." + ), + }, + useAst = true, + useEnvironment = true + ) + public BaseFunction rule( + BaseFunction implementation, + Boolean test, + Object attrs, + Object implicitOutputs, + Boolean executable, + Boolean outputToGenfiles, + SkylarkList<?> fragments, + SkylarkList<?> hostFragments, + Boolean skylarkTestable, + SkylarkList<String> toolchains, + String doc, + SkylarkList<?> providesArg, + FuncallExpression ast, + Environment funcallEnv) + throws EvalException; + + @SkylarkCallable( + name = "aspect", + doc = + "Creates a new aspect. The result of this function must be stored in a global value. " + + "Please see the <a href=\"../aspects.md\">introduction to Aspects</a> for more " + + "details.", + parameters = { + @Param( + name = "implementation", + type = BaseFunction.class, + legacyNamed = true, + 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 <a href=\"ctx.html\">ctx</a>. Attributes of the target are " + + "available via ctx.rule field. The function is called during the analysis " + + "phase for each application of an aspect to a target." + ), + @Param( + name = "attr_aspects", + type = SkylarkList.class, + legacyNamed = true, + generic1 = String.class, + defaultValue = "[]", + doc = "List of attribute names. The aspect propagates along dependencies specified " + + "by attributes of a target with this name. The list can also contain a single " + + "string '*': in that case aspect propagates along all dependencies of a target." + ), + @Param( + name = "attrs", + type = SkylarkDict.class, + legacyNamed = true, + noneable = true, + defaultValue = "None", + doc = "dictionary to declare all the attributes of the aspect. " + + "It maps from an attribute name to an attribute object " + + "(see <a href=\"attr.html\">attr</a> module). " + + "Aspect attributes are available to implementation function as fields of ctx " + + "parameter. Implicit attributes starting with <code>_</code> must have default " + + "values, and have type <code>label</code> or <code>label_list</code>. " + + "Explicit attributes must have type <code>string</code>, and must use the " + + "<code>values</code> restriction. If explicit attributes are present, the " + + "aspect can only be used with rules that have attributes of the same name and " + + "type, with valid values." + ), + @Param( + name = "required_aspect_providers", + type = SkylarkList.class, + legacyNamed = true, + defaultValue = "[]", + doc = "Allow the aspect to inspect other aspects. If the aspect propagates along " + + "a dependency, and the underlying rule sends a different aspect along that " + + "dependency, and that aspect provides one of the providers listed here, this " + + "aspect will see the providers provided by that aspect. " + + "<p>The value should be either a list of providers, or a " + + "list of lists of providers. This aspect will 'see' the underlying aspects " + + "that provide ALL providers from at least ONE of these lists. A single list " + + "of providers will be automatically converted to a list containing one list of " + + "providers." + ), + @Param( + name = "provides", + type = SkylarkList.class, + legacyNamed = true, + defaultValue = "[]", + doc = + "A list of providers this aspect is guaranteed to provide. " + + "It is an error if a provider is listed here and the aspect " + + "implementation function does not return it." + ), + @Param( + name = "fragments", + type = SkylarkList.class, + legacyNamed = true, + generic1 = String.class, + defaultValue = "[]", + doc = + "List of names of configuration fragments that the aspect requires " + + "in target configuration." + ), + @Param( + name = "host_fragments", + type = SkylarkList.class, + legacyNamed = true, + generic1 = String.class, + defaultValue = "[]", + doc = + "List of names of configuration fragments that the aspect requires " + + "in host configuration." + ), + @Param( + name = "toolchains", + type = SkylarkList.class, + legacyNamed = true, + generic1 = String.class, + defaultValue = "[]", + doc = + "<i>(Experimental)</i><br/><br/>" + + "If set, the set of toolchains this rule requires. Toolchains will be " + + "found by checking the current platform, and provided to the rule " + + "implementation via <code>ctx.toolchain</code>." + ), + @Param( + name = "doc", + type = String.class, + legacyNamed = true, + defaultValue = "''", + doc = "A description of the aspect that can be extracted by documentation generating " + + "tools." + ) + }, + useEnvironment = true, + useAst = true + ) + public SkylarkAspectApi aspect( + BaseFunction implementation, + SkylarkList attributeAspects, + Object attrs, + SkylarkList requiredAspectProvidersArg, + SkylarkList providesArg, + SkylarkList fragments, + SkylarkList hostFragments, + SkylarkList<String> toolchains, + String doc, + FuncallExpression ast, + Environment funcallEnv) + throws EvalException; + + @SkylarkCallable( + 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. " + + "The argument must refer to an absolute label. " + + "Example: <br><pre class=language-python>Label(\"//tools:default\")</pre>", + parameters = { + @Param(name = "label_string", type = String.class, legacyNamed = true, + doc = "the label string."), + @Param( + name = "relative_to_caller_repository", + type = Boolean.class, + defaultValue = "False", + named = true, + positional = false, + doc = "Deprecated. Do not use. " + + "When relative_to_caller_repository is True and the calling thread is a rule's " + + "implementation function, then a repo-relative label //foo:bar is resolved " + + "relative to the rule's repository. For calls to Label from any other " + + "thread, or calls in which the relative_to_caller_repository flag is False, " + + "a repo-relative label is resolved relative to the file in which the " + + "Label() call appears." + ) + }, + useLocation = true, + useEnvironment = true + ) + @SkylarkConstructor(objectType = Label.class) + public Label label( + String labelString, Boolean relativeToCallerRepository, Location loc, Environment env) + throws EvalException; + + @SkylarkCallable( + name = "FileType", + doc = + "Deprecated. Creates a file filter from a list of strings. For example, to match " + + "files ending with .cc or .cpp, use: " + + "<pre class=language-python>FileType([\".cc\", \".cpp\"])</pre>", + parameters = { + @Param( + name = "types", + type = SkylarkList.class, + legacyNamed = true, + generic1 = String.class, + defaultValue = "[]", + doc = "a list of the accepted file extensions." + ) + }, + useLocation = true, + useEnvironment = true + ) + @SkylarkConstructor(objectType = FileTypeApi.class) + public FileTypeApi<FileApiT> fileType(SkylarkList<?> types, Location loc, Environment env) + throws EvalException; +} |