diff options
author | Dmitry Lomov <dslomov@google.com> | 2016-08-10 18:29:04 +0000 |
---|---|---|
committer | Yue Gan <yueg@google.com> | 2016-08-11 09:14:21 +0000 |
commit | 8a07a959e10040642cdf2e6fa21edcd6a1e9212b (patch) | |
tree | e0109611dcfe55906c217b86aa411d7a74670185 /src/main/java/com/google/devtools/build/lib/rules | |
parent | f2f8408c4fa242ceb9352b49e50eb09863285dca (diff) |
Add 'provider()' function.
--
MOS_MIGRATED_REVID=129889793
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java | 73 |
1 files changed, 48 insertions, 25 deletions
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 8b6f05230a..734ae0b3a1 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 @@ -64,6 +64,7 @@ import com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException; import com.google.devtools.build.lib.packages.SkylarkAspect; import com.google.devtools.build.lib.packages.SkylarkClassObject; import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor; +import com.google.devtools.build.lib.packages.SkylarkExportable; import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.packages.TestSize; import com.google.devtools.build.lib.rules.SkylarkAttr.Descriptor; @@ -194,7 +195,7 @@ public class SkylarkRuleClassFunctions { @SkylarkSignature(name = "struct", returnType = SkylarkClassObject.class, doc = "Creates an immutable struct using the keyword arguments as attributes. It is used to group " - + "multiple values together.Example:<br>" + + "multiple values together. Example:<br>" + "<pre class=\"language-python\">s = struct(x = 2, y = 3)\n" + "return s.x + getattr(s, \"y\") # returns 5</pre>", extraKeywords = @Param(name = "kwargs", doc = "the struct attributes"), @@ -202,6 +203,23 @@ public class SkylarkRuleClassFunctions { private static final SkylarkClassObjectConstructor struct = SkylarkClassObjectConstructor.STRUCT; + @SkylarkSignature(name = "provider", returnType = SkylarkClassObjectConstructor.class, 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)" + + "return d.x + d.y # returns 5</pre>", + useLocation = true + ) + private static final BuiltinFunction provider = + new BuiltinFunction("provider") { + public SkylarkClassObjectConstructor invoke(Location location) { + return new SkylarkClassObjectConstructor( + "<no name>", // name is set on export. + location); + } + }; + // TODO(bazel-team): implement attribute copy and other rule properties @SkylarkSignature(name = "rule", doc = @@ -473,7 +491,7 @@ public class SkylarkRuleClassFunctions { /** The implementation for the magic function "rule" that creates Skylark rule classes */ - public static final class RuleFunction extends BaseFunction { + public static final class RuleFunction extends BaseFunction implements SkylarkExportable { private RuleClass.Builder builder; private RuleClass ruleClass; @@ -544,7 +562,7 @@ public class SkylarkRuleClassFunctions { /** * Export a RuleFunction from a Skylark file with a given name. */ - void export(Label skylarkLabel, String ruleClassName) throws EvalException { + public void export(Label skylarkLabel, String ruleClassName) throws EvalException { Preconditions.checkState(ruleClass == null && builder != null); this.skylarkLabel = skylarkLabel; if (type == RuleClassType.TEST != TargetUtils.isTestRuleName(ruleClassName)) { @@ -569,35 +587,40 @@ public class SkylarkRuleClassFunctions { Preconditions.checkState(ruleClass != null && builder == null); return ruleClass; } + + @Override + public boolean isExported() { + return skylarkLabel != null; + } } + /** + * All classes of values that need special processing after they are exported + * from an extension file. + * + * Order in list list is significant: all {@link }SkylarkAspect}s need to be exported + * before {@link RuleFunction}s etc. + */ + private static final List<Class<? extends SkylarkExportable>> EXPORTABLES = + ImmutableList.of( + SkylarkClassObjectConstructor.class, + SkylarkAspect.class, + RuleFunction.class); + public static void exportRuleFunctionsAndAspects(Environment env, Label skylarkLabel) throws EvalException { Set<String> globalNames = env.getGlobals().getDirectVariableNames(); - // Export aspects first since rules can depend on aspects. - for (String name : globalNames) { - Object value = env.lookup(name); - if (name == null) { - throw new AssertionError(String.format("No such variable: '%s'", name)); - } - if (value instanceof SkylarkAspect) { - SkylarkAspect skylarkAspect = (SkylarkAspect) value; - if (!skylarkAspect.isExported()) { - skylarkAspect.export(skylarkLabel, name); + for (Class<? extends SkylarkExportable> exportable : EXPORTABLES) { + for (String name : globalNames) { + Object value = env.lookup(name); + if (value == null) { + throw new AssertionError(String.format("No such variable: '%s'", name)); } - } - } - - for (String name : globalNames) { - Object value = env.lookup(name); - if (value == null) { - throw new AssertionError(String.format("No such variable: '%s'", name)); - } - if (value instanceof RuleFunction) { - RuleFunction function = (RuleFunction) value; - if (function.skylarkLabel == null) { - function.export(skylarkLabel, name); + if (exportable.isInstance(value)) { + if (!exportable.cast(value).isExported()) { + exportable.cast(value).export(skylarkLabel, name); + } } } } |