From 2a6752078f66cf14d1481486e836571e0df6974c Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Mon, 20 Mar 2017 18:06:48 +0000 Subject: Enable rules to transition based on their Rule objects. This begins to allow for cases where a rule sets configuration based on its attributes, such as where a rule attribute names flags and their values - sort of a reverse select. There are no such cases yet, but they're coming! -- PiperOrigin-RevId: 150648357 MOS_MIGRATED_REVID=150648357 --- .../devtools/build/lib/packages/RuleClass.java | 58 ++++++++++++++++------ 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/packages/RuleClass.java') diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java index eeacba5ad7..1a2dbb2127 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java @@ -445,6 +445,22 @@ public class RuleClass { } } + /** + * A RuleTransitionFactory which always returns the same transition. + */ + private static final class FixedTransitionFactory implements RuleTransitionFactory { + private final Transition transition; + + private FixedTransitionFactory(Transition transition) { + this.transition = transition; + } + + @Override + public Transition buildTransitionFor(Rule rule) { + return transition; + } + } + /** List of required attributes for normal rules, name and type. */ public static final ImmutableList REQUIRED_ATTRIBUTES_FOR_NORMAL_RULES = ImmutableList.of(attr("tags", Type.STRING_LIST).build()); @@ -470,7 +486,7 @@ public class RuleClass { private boolean outputsDefaultExecutable = false; private ImplicitOutputsFunction implicitOutputsFunction = ImplicitOutputsFunction.NONE; private Configurator configurator = NO_CHANGE; - private Transition transition; + private RuleTransitionFactory transitionFactory; private ConfiguredTargetFactory configuredTargetFactory = null; private PredicateWithMessage validityPredicate = PredicatesWithMessage.alwaysTrue(); @@ -584,7 +600,7 @@ public class RuleClass { outputsDefaultExecutable, implicitOutputsFunction, configurator, - transition, + transitionFactory, configuredTargetFactory, validityPredicate, preferredDependencyPredicate, @@ -718,8 +734,9 @@ public class RuleClass { public Builder cfg(Configurator configurator) { Preconditions.checkState(type != RuleClassType.ABSTRACT, "Setting not inherited property (cfg) of abstract rule class '%s'", name); - Preconditions.checkState(transition == null, - "Property cfg cannot be set to both a configurator and a transition"); + Preconditions.checkState(this.transitionFactory == null && this.configurator == NO_CHANGE, + "Property cfg has already been set"); + Preconditions.checkNotNull(configurator); this.configurator = configurator; return this; } @@ -734,9 +751,20 @@ public class RuleClass { public Builder cfg(Transition transition) { Preconditions.checkState(type != RuleClassType.ABSTRACT, "Setting not inherited property (cfg) of abstract rule class '%s'", name); - Preconditions.checkState(configurator == NO_CHANGE, - "Property cfg cannot be set to both a configurator and a transition"); - this.transition = transition; + Preconditions.checkState(this.transitionFactory == null && this.configurator == NO_CHANGE, + "Property cfg has already been set"); + Preconditions.checkNotNull(transition); + this.transitionFactory = new FixedTransitionFactory(transition); + return this; + } + + public Builder cfg(RuleTransitionFactory transitionFactory) { + Preconditions.checkState(type != RuleClassType.ABSTRACT, + "Setting not inherited property (cfg) of abstract rule class '%s'", name); + Preconditions.checkState(this.transitionFactory == null && this.configurator == NO_CHANGE, + "Property cfg has already been set"); + Preconditions.checkNotNull(transitionFactory); + this.transitionFactory = transitionFactory; return this; } @@ -1000,12 +1028,10 @@ public class RuleClass { private final Configurator configurator; /** - * A configuration transition that should be applied on any edge of the configured target graph - * that leads into a target of this rule class. - * - *

This transition must be a PatchTransition, but that class is not accessible in this package. + * A factory which will produce a configuration transition that should be applied on any edge of + * the configured target graph that leads into a target of this rule class. */ - private final Transition transition; + private final RuleTransitionFactory transitionFactory; /** * The factory that creates configured targets from this rule. @@ -1090,7 +1116,7 @@ public class RuleClass { boolean outputsDefaultExecutable, ImplicitOutputsFunction implicitOutputsFunction, Configurator configurator, - Transition transition, + RuleTransitionFactory transitionFactory, ConfiguredTargetFactory configuredTargetFactory, PredicateWithMessage validityPredicate, Predicate preferredDependencyPredicate, @@ -1112,7 +1138,7 @@ public class RuleClass { this.binaryOutput = binaryOutput; this.implicitOutputsFunction = implicitOutputsFunction; this.configurator = Preconditions.checkNotNull(configurator); - this.transition = transition; + this.transitionFactory = transitionFactory; this.configuredTargetFactory = configuredTargetFactory; this.validityPredicate = validityPredicate; this.preferredDependencyPredicate = preferredDependencyPredicate; @@ -1182,8 +1208,8 @@ public class RuleClass { return (Configurator) configurator; } - public Transition getTransition() { - return transition; + public RuleTransitionFactory getTransitionFactory() { + return transitionFactory; } @SuppressWarnings("unchecked") -- cgit v1.2.3