diff options
27 files changed, 285 insertions, 237 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java index 2fbf670d8d..2292c9d857 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java @@ -33,9 +33,9 @@ import com.google.devtools.build.lib.analysis.config.HostTransition; import com.google.devtools.build.lib.analysis.config.RunUnder; import com.google.devtools.build.lib.analysis.constraints.EnvironmentRule; import com.google.devtools.build.lib.analysis.test.TestConfiguration; -import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.Attribute; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelListLateBoundDefault; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClass.Builder; @@ -43,7 +43,6 @@ import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; import com.google.devtools.build.lib.packages.TestSize; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileTypeSet; -import java.util.List; /** * Rule class definitions used by (almost) every rule. @@ -75,16 +74,15 @@ public class BaseRuleClasses { * extra_actions themselves (to avoid cycles). */ @VisibleForTesting - static final LateBoundDefault<?, List<Label>> ACTION_LISTENER = - LateBoundDefault.fromTargetConfiguration( + static final LabelListLateBoundDefault<?> ACTION_LISTENER = + LabelListLateBoundDefault.fromTargetConfiguration( BuildConfiguration.class, - ImmutableList.of(), (rule, attributes, configuration) -> configuration.getActionListeners()); // TODO(b/65746853): provide a way to do this without passing the entire configuration /** Implementation for the :run_under attribute. */ - public static final LateBoundDefault<?, Label> RUN_UNDER = - LateBoundDefault.fromTargetConfiguration( + public static final LabelLateBoundDefault<?> RUN_UNDER = + LabelLateBoundDefault.fromTargetConfiguration( BuildConfiguration.class, null, (rule, attributes, configuration) -> { diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java index 5e9c9e13df..f0cf3d9046 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java @@ -22,6 +22,7 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.analysis.skylark.annotations.SkylarkConfigurationField; import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.packages.Attribute.AbstractLabelLateBoundDefault; import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.Rule; @@ -33,18 +34,18 @@ import java.util.concurrent.ExecutionException; import javax.annotation.concurrent.Immutable; /** - * An implementation of {@link LateBoundDefault} which obtains a late-bound attribute value - * (of type 'label') specifically by skylark configuration fragment name and field name, as - * registered by {@link SkylarkConfigurationField}. + * An implementation of {@link LateBoundDefault} which obtains a late-bound attribute value (of type + * 'label') specifically by skylark configuration fragment name and field name, as registered by + * {@link SkylarkConfigurationField}. * - * <p>For example, a SkylarkLateBoundDefault on "java" and "toolchain" would - * require a valid configuration fragment named "java" with a method annotated with - * {@link SkylarkConfigurationField} of name "toolchain". This {@link LateBoundDefault} would - * provide a late-bound dependency (defined by the label returned by that configuration field) - * in the current target configuration. + * <p>For example, a SkylarkLateBoundDefault on "java" and "toolchain" would require a valid + * configuration fragment named "java" with a method annotated with {@link + * SkylarkConfigurationField} of name "toolchain". This {@link LateBoundDefault} would provide a + * late-bound dependency (defined by the label returned by that configuration field) in the current + * target configuration. */ @Immutable -public class SkylarkLateBoundDefault<FragmentT> extends LateBoundDefault<FragmentT, Label> { +public class SkylarkLateBoundDefault<FragmentT> extends AbstractLabelLateBoundDefault<FragmentT> { private final Method method; private final String fragmentName; diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index 884dd6c5ba..20ce7e1d10 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -75,7 +75,7 @@ import com.google.devtools.build.lib.bazel.rules.workspace.MavenServerRule; import com.google.devtools.build.lib.bazel.rules.workspace.NewGitRepositoryRule; import com.google.devtools.build.lib.bazel.rules.workspace.NewHttpArchiveRule; import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.rules.Alias.AliasRule; import com.google.devtools.build.lib.rules.android.AarImportBaseRule; import com.google.devtools.build.lib.rules.android.AndroidConfiguration; @@ -430,7 +430,7 @@ public class BazelRuleClassProvider { new RuleSet() { @Override public void init(Builder builder) { - LateBoundDefault<?, Label> hostJdkAttribute = JavaSemantics.hostJdkAttribute(builder); + LabelLateBoundDefault<?> hostJdkAttribute = JavaSemantics.hostJdkAttribute(builder); BazelJavaProtoAspect bazelJavaProtoAspect = new BazelJavaProtoAspect(hostJdkAttribute); BazelJavaLiteProtoAspect bazelJavaLiteProtoAspect = new BazelJavaLiteProtoAspect(hostJdkAttribute); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java index f1a816e0f8..228b680416 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java @@ -45,7 +45,7 @@ import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.analysis.config.HostTransition; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.Attribute; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; @@ -77,8 +77,8 @@ public class BazelCppRuleClasses { * <p>If rule has an implicit $stl_default attribute returns STL version set on the command line * or if not set, the value of the $stl_default attribute. Returns {@code null} otherwise. */ - public static final LateBoundDefault<?, Label> STL = - LateBoundDefault.fromTargetConfiguration( + public static final LabelLateBoundDefault<?> STL = + LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, null, (rule, attributes, cppConfig) -> { @@ -463,8 +463,8 @@ public class BazelCppRuleClasses { } /** Implementation for the :lipo_context attribute. */ - static final LateBoundDefault<?, Label> LIPO_CONTEXT = - LateBoundDefault.fromTargetConfiguration( + static final LabelLateBoundDefault<?> LIPO_CONTEXT = + LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, null, (rule, attributes, cppConfig) -> { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java index 43139b40c5..feec6ce3c3 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java @@ -15,8 +15,7 @@ package com.google.devtools.build.lib.bazel.rules.java.proto; import com.google.devtools.build.lib.bazel.rules.java.BazelJavaSemantics; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.rules.java.proto.JavaLiteProtoAspect; /** An Aspect which BazelJavaLiteProtoLibrary injects to build Java Lite protos. */ @@ -25,7 +24,7 @@ public class BazelJavaLiteProtoAspect extends JavaLiteProtoAspect { public static final String DEFAULT_PROTO_TOOLCHAIN_LABEL = "@com_google_protobuf_javalite//:javalite_toolchain"; - public BazelJavaLiteProtoAspect(LateBoundDefault<?, Label> hostJdkAttribute) { + public BazelJavaLiteProtoAspect(LabelLateBoundDefault<?> hostJdkAttribute) { super( BazelJavaSemantics.INSTANCE, null /* jacocoLabel */, diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java index 6370095fd9..e376cf3d95 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java @@ -21,12 +21,11 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.bazel.rules.java.BazelJavaSemantics; -import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.rules.java.proto.JavaProtoAspect; import com.google.devtools.build.lib.rules.java.proto.RpcSupport; import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder; @@ -35,7 +34,7 @@ import java.util.List; /** An Aspect which BazelJavaProtoLibrary injects to build Java SPEED protos. */ public class BazelJavaProtoAspect extends JavaProtoAspect { - public BazelJavaProtoAspect(LateBoundDefault<?, Label> hostJdkAttribute) { + public BazelJavaProtoAspect(LabelLateBoundDefault<?> hostJdkAttribute) { super( BazelJavaSemantics.INSTANCE, null, /* jacocoAttr */ diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java index be90d861e3..77e7e42007 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java @@ -27,9 +27,8 @@ import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.analysis.config.HostTransition; import com.google.devtools.build.lib.bazel.rules.cpp.BazelCppRuleClasses; -import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; import com.google.devtools.build.lib.packages.TriState; @@ -44,8 +43,8 @@ import com.google.devtools.build.lib.util.FileType; public final class BazelPyRuleClasses { public static final FileType PYTHON_SOURCE = FileType.of(".py"); - public static final LateBoundDefault<?, Label> PY_INTERPRETER = - LateBoundDefault.fromTargetConfiguration( + public static final LabelLateBoundDefault<?> PY_INTERPRETER = + LabelLateBoundDefault.fromTargetConfiguration( BazelPythonConfiguration.class, null, (rule, attributes, bazelPythonConfig) -> bazelPythonConfig.getPythonTop()); diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java index d6b1cebef1..75ff0f3332 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java +++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java @@ -32,6 +32,7 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition; import com.google.devtools.build.lib.analysis.config.transitions.NoTransition; import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition; +import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassNamePredicate; @@ -1501,7 +1502,7 @@ public final class Attribute implements Comparable<Attribute> { } } - private static final class SimpleLateBoundDefault<FragmentT, ValueT> + private static class SimpleLateBoundDefault<FragmentT, ValueT> extends LateBoundDefault<FragmentT, ValueT> { private final Resolver<FragmentT, ValueT> resolver; @@ -1523,8 +1524,8 @@ public final class Attribute implements Comparable<Attribute> { // TODO(b/65746853): Remove documentation about accepting BuildConfiguration when uses are cleaned // up. /** - * Provider of values for late-bound attributes. See - * {@link Attribute#value(LateBoundDefault<?, ? extends TYPE> value)}. + * Provider of values for late-bound attributes. See {@link Attribute#value(LateBoundDefault<?, ? + * extends TYPE> value)}. * * <p>Use sparingly - having different values for attributes during loading and analysis can * confuse users. @@ -1532,7 +1533,8 @@ public final class Attribute implements Comparable<Attribute> { * @param <FragmentT> The type of value that is used to compute this value. This is usually a * subclass of BuildConfiguration.Fragment. It may also be Void to receive null, or * BuildConfiguration itself to receive the entire configuration. - * @param <ValueT> The type of value returned by this class. + * @param <ValueT> The type of value returned by this class. Must be either {@link Void}, a {@link + * Label}, or a {@link List} of {@link Label} objects. */ @Immutable public abstract static class LateBoundDefault<FragmentT, ValueT> { @@ -1551,107 +1553,18 @@ public final class Attribute implements Comparable<Attribute> { private final Class<FragmentT> fragmentClass; /** - * Creates a new LateBoundDefault which uses the rule, its configured attributes, and a fragment - * of the target configuration. - * - * <p>Note that the configuration fragment here does not take into account any transitions that - * are on the attribute with this LateBoundDefault as its value. The configuration will be the - * same as the configuration given to the target bearing the attribute. - * - * <p>Nearly all LateBoundDefaults should use this constructor. There are few situations where - * it isn't the appropriate option. - * - * <p>If you want a late-bound dependency which is configured in the host configuration, just - * use this method with {@link com.google.devtools.build.lib.analysis.config.HostTransition}. - * If you also need to decide the label of the dependency with information gained from the host - * configuration - and it's very unlikely that you do - you can use - * {@link #fromHostConfiguration} as well. - * - * <p>If you want to decide an attribute's value based on the value of its other attributes, - * use a subclass of {@link ComputedDefault}. The only time you should need - * {@link #fromRuleAndAttributes} is if you need access to three or more configurable - * attributes, or if you need to match names with a late-bound attribute on another rule. - * - * <p>If you have a constant-valued attribute, but you need it to have the same name as an - * attribute on another rule which is late-bound, use {@link #fromConstant} or - * {@link #alwaysNull}. - * - * @param fragmentClass The fragment to receive from the target configuration. May also be - * BuildConfiguration.class to receive the entire configuration (deprecated) - in this case, - * you must only use methods of BuildConfiguration itself, and not use any fragments. - * @param defaultValue The default value to return at loading time, when the configuration is - * not available. - * @param resolver A function which will compute the actual value with the configuration. - */ - public static <FragmentT, ValueT> LateBoundDefault<FragmentT, ValueT> fromTargetConfiguration( - Class<FragmentT> fragmentClass, ValueT defaultValue, Resolver<FragmentT, ValueT> resolver) { - Preconditions.checkArgument( - !fragmentClass.equals(Void.class), - "Use fromRuleAndAttributesOnly to specify a LateBoundDefault which does not use " - + "configuration."); - return new SimpleLateBoundDefault<>(false, fragmentClass, defaultValue, resolver); - } - - /** - * Creates a new LateBoundDefault which uses the rule, its configured attributes, and a fragment - * of the host configuration. - * - * <p>This should only be necessary in very specialized cases. In almost all cases, you don't - * need this method, just {@link #fromTargetConfiguration} and - * {@link com.google.devtools.build.lib.analysis.config.HostTransition}. - * - * <p>This method only affects the configuration fragment passed to {@link #resolve}. You must - * also use {@link com.google.devtools.build.lib.analysis.config.HostTransition}, so that the - * dependency will be analyzed in the host configuration. - * - * @param fragmentClass The fragment to receive from the host configuration. May also be - * BuildConfiguration.class to receive the entire configuration (deprecated) - in this case, - * you must only use methods of BuildConfiguration itself, and not use any fragments. - * It is very rare that a LateBoundDefault should need a host configuration fragment; use - * {@link #fromTargetConfiguration} in most cases. - * @param defaultValue The default value to return at loading time, when the configuration is - * not available. - * @param resolver A function which will compute the actual value with the configuration. - */ - public static <FragmentT, ValueT> LateBoundDefault<FragmentT, ValueT> fromHostConfiguration( - Class<FragmentT> fragmentClass, ValueT defaultValue, Resolver<FragmentT, ValueT> resolver) { - Preconditions.checkArgument( - !fragmentClass.equals(Void.class), - "Use fromRuleAndAttributesOnly to specify a LateBoundDefault which does not use " - + "configuration."); - return new SimpleLateBoundDefault<>(true, fragmentClass, defaultValue, resolver); - } - - /** - * Creates a new LateBoundDefault which uses only the rule and its configured attributes. - * - * <p>This should only be necessary in very specialized cases. In almost all cases, you don't - * need this method, just use {@link ComputedDefault}. - * - * <p>This is used primarily for computing values based on three or more configurable - * attributes and/or matching names with late-bound attributes on other rules. - * - * @param defaultValue The default value to return when the configuration is not available at - * loading time. - * @param resolver A function which will compute the actual value with the configuration. - */ - public static <ValueT> LateBoundDefault<Void, ValueT> fromRuleAndAttributesOnly( - ValueT defaultValue, Resolver<Void, ValueT> resolver) { - return new SimpleLateBoundDefault<>(false, Void.class, defaultValue, resolver); - } - - /** * Creates a new LateBoundDefault which always returns the given value. * * <p>This is used primarily for matching names with late-bound attributes on other rules and * for testing. Use normal default values if the name does not matter. */ - public static <ValueT> LateBoundDefault<Void, ValueT> fromConstant(final ValueT defaultValue) { - if (defaultValue == null) { - return alwaysNull(); - } - return new SimpleLateBoundDefault<>( - false, Void.class, defaultValue, (rule, attributes, unused) -> defaultValue); + @VisibleForTesting + public static LabelLateBoundDefault<Void> fromConstantForTesting(Label defaultValue) { + return new LabelLateBoundDefault<Void>( + false, + Void.class, + Preconditions.checkNotNull(defaultValue), + (rule, attributes, unused) -> defaultValue) {}; } /** @@ -1662,12 +1575,9 @@ public final class Attribute implements Comparable<Attribute> { */ @SuppressWarnings("unchecked") // bivariant implementation public static <ValueT> LateBoundDefault<Void, ValueT> alwaysNull() { - return (LateBoundDefault<Void, ValueT>) ALWAYS_NULL; + return (LateBoundDefault<Void, ValueT>) AlwaysNullLateBoundDefault.INSTANCE; } - private static final LateBoundDefault<Void, Void> ALWAYS_NULL = - new SimpleLateBoundDefault<>(false, Void.class, null, (rule, attributes, unused) -> null); - protected LateBoundDefault( boolean useHostConfiguration, Class<FragmentT> fragmentClass, @@ -1716,6 +1626,149 @@ public final class Attribute implements Comparable<Attribute> { public abstract ValueT resolve(Rule rule, AttributeMap attributes, FragmentT input); } + /** + * An abstract {@link LateBoundDefault} class so that {@code SkylarkLateBoundDefault} can derive + * from {@link LateBoundDefault} without compromising the type-safety of the second generic + * parameter to {@link LateBoundDefault}. + */ + public abstract static class AbstractLabelLateBoundDefault<FragmentT> + extends LateBoundDefault<FragmentT, Label> { + protected AbstractLabelLateBoundDefault( + boolean useHostConfiguration, Class<FragmentT> fragmentClass, Label defaultValue) { + super(useHostConfiguration, fragmentClass, defaultValue); + } + } + + private static class AlwaysNullLateBoundDefault extends SimpleLateBoundDefault<Void, Void> { + static final AlwaysNullLateBoundDefault INSTANCE = new AlwaysNullLateBoundDefault(); + + private AlwaysNullLateBoundDefault() { + super(false, Void.class, null, (rule, attributes, unused) -> null); + } + } + + /** A {@link LateBoundDefault} for a {@link Label}. */ + public static class LabelLateBoundDefault<FragmentT> + extends SimpleLateBoundDefault<FragmentT, Label> { + private LabelLateBoundDefault( + boolean useHostConfiguration, + Class<FragmentT> fragmentClass, + Label defaultValue, + Resolver<FragmentT, Label> resolver) { + super(useHostConfiguration, fragmentClass, defaultValue, resolver); + } + + /** + * Creates a new LabelLateBoundDefault which uses the rule, its configured attributes, and a + * fragment of the target configuration. + * + * <p>Note that the configuration fragment here does not take into account any transitions that + * are on the attribute with this LabelLateBoundDefault as its value. The configuration will be + * the same as the configuration given to the target bearing the attribute. + * + * <p>Nearly all LateBoundDefaults should use this constructor or {@link + * LabelListLateBoundDefault#fromTargetConfiguration}. There are few situations where it isn't + * the appropriate option. + * + * <p>If you want a late-bound dependency which is configured in the host configuration, just + * use this method with {@link com.google.devtools.build.lib.analysis.config.HostTransition}. If + * you also need to decide the label of the dependency with information gained from the host + * configuration - and it's very unlikely that you do - you can use {@link + * LabelLateBoundDefault#fromHostConfiguration} as well. + * + * <p>If you want to decide an attribute's value based on the value of its other attributes, use + * a subclass of {@link ComputedDefault}. The only time you should need {@link + * LabelListLateBoundDefault#fromRuleAndAttributesOnly} is if you need access to three or more + * configurable attributes, or if you need to match names with a late-bound attribute on another + * rule. + * + * <p>If you have a constant-valued attribute, but you need it to have the same name as an + * attribute on another rule which is late-bound, use {@link #alwaysNull}. + * + * @param fragmentClass The fragment to receive from the target configuration. May also be + * BuildConfiguration.class to receive the entire configuration (deprecated) - in this case, + * you must only use methods of BuildConfiguration itself, and not use any fragments. + * @param defaultValue The default {@link Label} to return at loading time, when the + * configuration is not available. + * @param resolver A function which will compute the actual value with the configuration. + */ + public static <FragmentT> LabelLateBoundDefault<FragmentT> fromTargetConfiguration( + Class<FragmentT> fragmentClass, Label defaultValue, Resolver<FragmentT, Label> resolver) { + Preconditions.checkArgument( + !fragmentClass.equals(Void.class), + "Use fromRuleAndAttributesOnly to specify a LateBoundDefault which does not use " + + "configuration."); + return new LabelLateBoundDefault<>(false, fragmentClass, defaultValue, resolver); + } + + /** + * Creates a new LateBoundDefault which uses the rule, its configured attributes, and a fragment + * of the host configuration. + * + * <p>This should only be necessary in very specialized cases. In almost all cases, you don't + * need this method, just {@link #fromTargetConfiguration} and {@link + * com.google.devtools.build.lib.analysis.config.HostTransition}. + * + * <p>This method only affects the configuration fragment passed to {@link #resolve}. You must + * also use {@link com.google.devtools.build.lib.analysis.config.HostTransition}, so that the + * dependency will be analyzed in the host configuration. + * + * @param fragmentClass The fragment to receive from the host configuration. May also be + * BuildConfiguration.class to receive the entire configuration (deprecated) - in this case, + * you must only use methods of BuildConfiguration itself, and not use any fragments. It is + * very rare that a LateBoundDefault should need a host configuration fragment; use {@link + * #fromTargetConfiguration} in most cases. + * @param defaultValue The default {@link Label} to return at loading time, when the + * configuration is not available. + * @param resolver A function which will compute the actual value with the configuration. + */ + public static <FragmentT> LabelLateBoundDefault<FragmentT> fromHostConfiguration( + Class<FragmentT> fragmentClass, Label defaultValue, Resolver<FragmentT, Label> resolver) { + Preconditions.checkArgument( + !fragmentClass.equals(Void.class), + "Use fromRuleAndAttributesOnly to specify a LateBoundDefault which does not use " + + "configuration."); + return new LabelLateBoundDefault<>(true, fragmentClass, defaultValue, resolver); + } + } + + /** A {@link LateBoundDefault} for a {@link List} of {@link Label} objects. */ + public static class LabelListLateBoundDefault<FragmentT> + extends SimpleLateBoundDefault<FragmentT, List<Label>> { + private LabelListLateBoundDefault( + boolean useHostConfiguration, + Class<FragmentT> fragmentClass, + Resolver<FragmentT, List<Label>> resolver) { + super(useHostConfiguration, fragmentClass, ImmutableList.of(), resolver); + } + + public static <FragmentT> LabelListLateBoundDefault<FragmentT> fromTargetConfiguration( + Class<FragmentT> fragmentClass, Resolver<FragmentT, List<Label>> resolver) { + Preconditions.checkArgument( + !fragmentClass.equals(Void.class), + "Use fromRuleAndAttributesOnly to specify a LateBoundDefault which does not use " + + "configuration."); + return new LabelListLateBoundDefault<>(false, fragmentClass, resolver); + } + + /** + * Creates a new LabelListLateBoundDefault which uses only the rule and its configured + * attributes. + * + * <p>This should only be necessary in very specialized cases. In almost all cases, you don't + * need this method, just use {@link ComputedDefault}. + * + * <p>This is used primarily for computing values based on three or more configurable attributes + * and/or matching names with late-bound attributes on other rules. + * + * @param resolver A function which will compute the actual value with the configuration. + */ + public static LabelListLateBoundDefault<Void> fromRuleAndAttributesOnly( + Resolver<Void, List<Label>> resolver) { + return new LabelListLateBoundDefault<>(false, Void.class, resolver); + } + } + private final String name; private final Type<?> type; diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java index 81cc6d308a..7a06eda76f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java @@ -43,7 +43,7 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; import com.google.devtools.build.lib.packages.Rule; @@ -199,8 +199,8 @@ public final class AndroidRuleClasses { public static final String NOCOMPRESS_EXTENSIONS_ATTR = "nocompress_extensions"; /** The default label of android_sdk option */ - public static LateBoundDefault<?, Label> getAndroidSdkLabel(Label androidSdk) { - return LateBoundDefault.fromTargetConfiguration( + public static LabelLateBoundDefault<?> getAndroidSdkLabel(Label androidSdk) { + return LabelLateBoundDefault.fromTargetConfiguration( AndroidConfiguration.class, androidSdk, (rule, attributes, configuration) -> configuration.getSdk()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java index 0cc09b83ea..c5e54c7976 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java +++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java @@ -24,7 +24,7 @@ import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClass.Builder; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; @@ -149,8 +149,8 @@ public class AppleToolchain { } /** The default label of the build-wide {@code xcode_config} configuration rule. */ - public static LateBoundDefault<?, Label> getXcodeConfigLabel(String toolsRepository) { - return LateBoundDefault.fromTargetConfiguration( + public static LabelLateBoundDefault<?> getXcodeConfigLabel(String toolsRepository) { + return LabelLateBoundDefault.fromTargetConfiguration( AppleConfiguration.class, Label.parseAbsoluteUnchecked( toolsRepository + AppleCommandLineOptions.DEFAULT_XCODE_VERSION_CONFIG_LABEL), diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRuleClasses.java index fb8c973973..45a7163f78 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRuleClasses.java @@ -28,7 +28,7 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelListLateBoundDefault; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; import com.google.devtools.build.lib.packages.RuleClass; @@ -119,10 +119,9 @@ public class ConfigRuleClasses { public static final String TARGET_PLATFORMS_ATTRIBUTE = ":target_platforms"; /** Implementation for the :target_platform attribute. */ - public static final LateBoundDefault<?, List<Label>> TARGET_PLATFORMS = - LateBoundDefault.fromTargetConfiguration( + public static final LabelListLateBoundDefault<?> TARGET_PLATFORMS = + LabelListLateBoundDefault.fromTargetConfiguration( PlatformConfiguration.class, - ImmutableList.of(), (rule, attributes, platformConfig) -> ConfigSettingRule.getTargetPlatformsIfRelevant(attributes, platformConfig)); diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java index a8369951dd..9170c794ff 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java @@ -27,7 +27,7 @@ import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.analysis.TemplateVariableInfo; import com.google.devtools.build.lib.analysis.config.HostTransition; import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClass.Builder; @@ -47,8 +47,8 @@ public final class CcToolchainRule implements RuleDefinition { return ruleClass.endsWith("cc_toolchain"); } - private static final LateBoundDefault<?, Label> LIBC_TOP = - LateBoundDefault.fromTargetConfiguration( + private static final LabelLateBoundDefault<?> LIBC_TOP = + LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, null, (rule, attributes, cppConfig) -> cppConfig.getSysrootLabel()); @@ -118,7 +118,7 @@ public final class CcToolchainRule implements RuleDefinition { .cfg(HostTransition.INSTANCE) .singleArtifact() .value( - LateBoundDefault.fromTargetConfiguration( + LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, null, // TODO(b/69547565): Remove call to isLLVMOptimizedFdo diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java index b4ce785afc..7940984e6f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java @@ -34,7 +34,7 @@ import com.google.devtools.build.lib.analysis.LanguageDependentFragment.LibraryL import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; import com.google.devtools.build.lib.packages.RuleTransitionFactory; import com.google.devtools.build.lib.rules.cpp.transitions.EnableLipoTransition; @@ -51,8 +51,8 @@ public class CppRuleClasses { * <p>This attribute connects a target to the LIPO context target configured with the lipo input * collector configuration. */ - public static final LateBoundDefault<?, Label> LIPO_CONTEXT_COLLECTOR = - LateBoundDefault.fromTargetConfiguration( + public static final LabelLateBoundDefault<?> LIPO_CONTEXT_COLLECTOR = + LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, null, // TODO(b/69548520): Remove call to isLipoOptimization @@ -72,13 +72,13 @@ public class CppRuleClasses { */ public static final String CROSSTOOL_LABEL = "//tools/cpp:toolchain"; - public static final LateBoundDefault<?, Label> DEFAULT_MALLOC = - LateBoundDefault.fromTargetConfiguration( + public static final LabelLateBoundDefault<?> DEFAULT_MALLOC = + LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, null, (rule, attributes, cppConfig) -> cppConfig.customMalloc()); - public static LateBoundDefault<CppConfiguration, Label> ccToolchainAttribute( + public static LabelLateBoundDefault<CppConfiguration> ccToolchainAttribute( RuleDefinitionEnvironment env) { - return LateBoundDefault.fromTargetConfiguration( + return LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, env.getToolsLabel(CROSSTOOL_LABEL), (rules, attributes, cppConfig) -> cppConfig.getCcToolchainRuleLabel()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java index 81094e902e..4d66952eab 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java @@ -36,7 +36,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; -import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.NativeAspectClass; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.rules.cpp.AspectLegalCppSemantics; @@ -71,17 +71,17 @@ public class CcProtoAspect extends NativeAspectClass implements ConfiguredAspect private static final String PROTO_TOOLCHAIN_ATTR = ":aspect_cc_proto_toolchain"; - private static final Attribute.LateBoundDefault<?, Label> PROTO_TOOLCHAIN_LABEL = - Attribute.LateBoundDefault.fromTargetConfiguration( + private static final LabelLateBoundDefault<?> PROTO_TOOLCHAIN_LABEL = + LabelLateBoundDefault.fromTargetConfiguration( ProtoConfiguration.class, Label.parseAbsoluteUnchecked("@com_google_protobuf//:cc_toolchain"), (rule, attributes, protoConfig) -> protoConfig.protoToolchainForCc()); private final CppSemantics cppSemantics; - private final Attribute.LateBoundDefault<?, Label> ccToolchainAttrValue; + private final LabelLateBoundDefault<?> ccToolchainAttrValue; - public CcProtoAspect(AspectLegalCppSemantics cppSemantics, - Attribute.LateBoundDefault<?, Label> ccToolchainAttrValue) { + public CcProtoAspect( + AspectLegalCppSemantics cppSemantics, LabelLateBoundDefault<?> ccToolchainAttrValue) { this.cppSemantics = cppSemantics; this.ccToolchainAttrValue = ccToolchainAttrValue; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java index 5fd61f5a75..b985fa9315 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java @@ -25,10 +25,9 @@ import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.analysis.TemplateVariableInfo; import com.google.devtools.build.lib.analysis.config.HostTransition; -import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.Attribute.ComputedDefault; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.RuleClass; @@ -48,8 +47,8 @@ public class GenRuleBaseRule implements RuleDefinition { * Late-bound dependency on the C++ toolchain <i>iff</i> the genrule has make variables that need * that toolchain. */ - public static LateBoundDefault<?, Label> ccToolchainAttribute(RuleDefinitionEnvironment env) { - return LateBoundDefault.fromTargetConfiguration( + public static LabelLateBoundDefault<?> ccToolchainAttribute(RuleDefinitionEnvironment env) { + return LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, env.getToolsLabel(CppRuleClasses.CROSSTOOL_LABEL), // null guards are needed for LateBoundAttributeTest diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java index 6ecd183e0b..d717602eed 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java @@ -37,7 +37,8 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelListLateBoundDefault; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; import com.google.devtools.build.lib.rules.java.DeployArchiveBuilder.Compression; import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType; @@ -119,8 +120,8 @@ public interface JavaSemantics { /** The java_toolchain.compatible_javacopts key for testonly compilations. */ public static final String TESTONLY_JAVACOPTS_KEY = "testonly"; - LateBoundDefault<?, Label> JAVA_TOOLCHAIN = - LateBoundDefault.fromTargetConfiguration( + LabelLateBoundDefault<?> JAVA_TOOLCHAIN = + LabelLateBoundDefault.fromTargetConfiguration( JavaConfiguration.class, Label.parseAbsoluteUnchecked(JAVA_TOOLCHAIN_LABEL), (rule, attributes, javaConfig) -> javaConfig.getToolchainLabel()); @@ -139,16 +140,16 @@ public interface JavaSemantics { OutputGroupInfo.HIDDEN_OUTPUT_GROUP_PREFIX + "gen_jars"; /** Implementation for the :jvm attribute. */ - static LateBoundDefault<?, Label> jvmAttribute(RuleDefinitionEnvironment env) { - return LateBoundDefault.fromTargetConfiguration( + static LabelLateBoundDefault<?> jvmAttribute(RuleDefinitionEnvironment env) { + return LabelLateBoundDefault.fromTargetConfiguration( JavaConfiguration.class, env.getToolsLabel(JavaImplicitAttributes.JDK_LABEL), (rule, attributes, configuration) -> configuration.getRuntimeLabel()); } /** Implementation for the :host_jdk attribute. */ - static LateBoundDefault<?, Label> hostJdkAttribute(RuleDefinitionEnvironment env) { - return LateBoundDefault.fromHostConfiguration( + static LabelLateBoundDefault<?> hostJdkAttribute(RuleDefinitionEnvironment env) { + return LabelLateBoundDefault.fromHostConfiguration( JavaConfiguration.class, env.getToolsLabel(JavaImplicitAttributes.HOST_JDK_LABEL), (rule, attributes, configuration) -> configuration.getRuntimeLabel()); @@ -158,8 +159,8 @@ public interface JavaSemantics { * Implementation for the :java_launcher attribute. Note that the Java launcher is disabled by * default, so it returns null for the configuration-independent default value. */ - LateBoundDefault<?, Label> JAVA_LAUNCHER = - LateBoundDefault.fromTargetConfiguration( + LabelLateBoundDefault<?> JAVA_LAUNCHER = + LabelLateBoundDefault.fromTargetConfiguration( JavaConfiguration.class, null, (rule, attributes, javaConfig) -> { @@ -181,30 +182,27 @@ public interface JavaSemantics { return javaConfig.getJavaLauncherLabel(); }); - LateBoundDefault<?, List<Label>> JAVA_PLUGINS = - LateBoundDefault.fromTargetConfiguration( + LabelListLateBoundDefault<?> JAVA_PLUGINS = + LabelListLateBoundDefault.fromTargetConfiguration( JavaConfiguration.class, - ImmutableList.of(), (rule, attributes, javaConfig) -> ImmutableList.copyOf(javaConfig.getPlugins())); /** Implementation for the :proguard attribute. */ - LateBoundDefault<?, Label> PROGUARD = - LateBoundDefault.fromTargetConfiguration( + LabelLateBoundDefault<?> PROGUARD = + LabelLateBoundDefault.fromTargetConfiguration( JavaConfiguration.class, null, (rule, attributes, javaConfig) -> javaConfig.getProguardBinary()); - LateBoundDefault<?, List<Label>> EXTRA_PROGUARD_SPECS = - LateBoundDefault.fromTargetConfiguration( + LabelListLateBoundDefault<?> EXTRA_PROGUARD_SPECS = + LabelListLateBoundDefault.fromTargetConfiguration( JavaConfiguration.class, - ImmutableList.of(), (rule, attributes, javaConfig) -> ImmutableList.copyOf(javaConfig.getExtraProguardSpecs())); - LateBoundDefault<?, List<Label>> BYTECODE_OPTIMIZERS = - LateBoundDefault.fromTargetConfiguration( + LabelListLateBoundDefault<?> BYTECODE_OPTIMIZERS = + LabelListLateBoundDefault.fromTargetConfiguration( JavaConfiguration.class, - ImmutableList.of(), (rule, attributes, javaConfig) -> { // Use a modicum of smarts to avoid implicit dependencies where we don't need them. JavaOptimizationMode optMode = javaConfig.getJavaOptimizationMode(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java index e08f1bdc38..a59282a6bc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java @@ -43,7 +43,7 @@ import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.Attribute; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.NativeAspectClass; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; import com.google.devtools.build.lib.rules.java.JavaCompilationArtifacts; @@ -70,8 +70,8 @@ public class JavaLiteProtoAspect extends NativeAspectClass implements Configured public static final String PROTO_TOOLCHAIN_ATTR = ":aspect_proto_toolchain_for_javalite"; - public static LateBoundDefault<?, Label> getProtoToolchainLabel(String defaultValue) { - return LateBoundDefault.fromTargetConfiguration( + public static LabelLateBoundDefault<?> getProtoToolchainLabel(String defaultValue) { + return LabelLateBoundDefault.fromTargetConfiguration( ProtoConfiguration.class, Label.parseAbsoluteUnchecked(defaultValue), (rule, attributes, protoConfig) -> protoConfig.protoToolchainForJavaLite()); @@ -81,13 +81,13 @@ public class JavaLiteProtoAspect extends NativeAspectClass implements Configured @Nullable private final String jacocoLabel; private final String defaultProtoToolchainLabel; - private final LateBoundDefault<?, Label> hostJdkAttribute; + private final LabelLateBoundDefault<?> hostJdkAttribute; public JavaLiteProtoAspect( JavaSemantics javaSemantics, @Nullable String jacocoLabel, String defaultProtoToolchainLabel, - LateBoundDefault<?, Label> hostJdkAttribute) { + LabelLateBoundDefault<?> hostJdkAttribute) { this.javaSemantics = javaSemantics; this.jacocoLabel = jacocoLabel; this.defaultProtoToolchainLabel = defaultProtoToolchainLabel; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java index f2bcc1b0a9..ed35597aa4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java @@ -42,7 +42,7 @@ import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.Attribute; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.NativeAspectClass; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; import com.google.devtools.build.lib.rules.java.JavaCompilationHelper; @@ -69,10 +69,10 @@ import javax.annotation.Nullable; public class JavaProtoAspect extends NativeAspectClass implements ConfiguredAspectFactory { private static final String SPEED_PROTO_TOOLCHAIN_ATTR = ":aspect_java_proto_toolchain"; - private final LateBoundDefault<?, Label> hostJdkAttribute; + private final LabelLateBoundDefault<?> hostJdkAttribute; - private static LateBoundDefault<?, Label> getSpeedProtoToolchainLabel(String defaultValue) { - return LateBoundDefault.fromTargetConfiguration( + private static LabelLateBoundDefault<?> getSpeedProtoToolchainLabel(String defaultValue) { + return LabelLateBoundDefault.fromTargetConfiguration( ProtoConfiguration.class, Label.parseAbsoluteUnchecked(defaultValue), (rule, attributes, protoConfig) -> protoConfig.protoToolchainForJava()); @@ -89,7 +89,7 @@ public class JavaProtoAspect extends NativeAspectClass implements ConfiguredAspe @Nullable String jacocoLabel, RpcSupport rpcSupport, String defaultSpeedProtoToolchainLabel, - LateBoundDefault<?, Label> hostJdkAttribute) { + LabelLateBoundDefault<?> hostJdkAttribute) { this.javaSemantics = javaSemantics; this.jacocoLabel = jacocoLabel; this.rpcSupport = rpcSupport; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java index de6f0702d0..19017248da 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java @@ -44,7 +44,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.NativeAspectClass; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; @@ -106,8 +106,8 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF protected static final ImmutableList<String> J2OBJC_PLUGIN_PARAMS = ImmutableList.of("file_dir_mapping", "generate_class_mappings"); - private static final LateBoundDefault<?, Label> DEAD_CODE_REPORT = - LateBoundDefault.fromTargetConfiguration( + private static final LabelLateBoundDefault<?> DEAD_CODE_REPORT = + LabelLateBoundDefault.fromTargetConfiguration( J2ObjcConfiguration.class, null, (rule, attributes, j2objcConfig) -> j2objcConfig.deadCodeReport().orNull()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java index 98e201a63e..6249e8977f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java @@ -39,7 +39,7 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.HostTransition; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; import com.google.devtools.build.lib.packages.RuleClass; @@ -158,8 +158,8 @@ public class ObjcRuleClasses { * * <p>TODO(cpeyser): Use AppleCcToolchain instead of CcToolchain once released. */ - public static final LateBoundDefault<?, Label> APPLE_TOOLCHAIN = - LateBoundDefault.fromTargetConfiguration( + public static final LabelLateBoundDefault<?> APPLE_TOOLCHAIN = + LabelLateBoundDefault.fromTargetConfiguration( CppConfiguration.class, Label.parseAbsoluteUnchecked(CROSSTOOL_LABEL), (rule, attributes, cppConfig) -> cppConfig.getCcToolchainRuleLabel()); @@ -712,14 +712,14 @@ public class ObjcRuleClasses { attr(HEADER_SCANNER_ATTRIBUTE, LABEL) .cfg(HostTransition.INSTANCE) .value( - LateBoundDefault.fromTargetConfiguration( + LabelLateBoundDefault.fromTargetConfiguration( ObjcConfiguration.class, env.getToolsLabel("//tools/objc:header_scanner"), (rule, attributes, objcConfig) -> objcConfig.getObjcHeaderScannerTool()))) .add( attr(APPLE_SDK_ATTRIBUTE, LABEL) .value( - LateBoundDefault.fromTargetConfiguration( + LabelLateBoundDefault.fromTargetConfiguration( ObjcConfiguration.class, null, // Apple SDKs are currently only used by ObjC header thinning feature diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java index e8ffdd6190..557cf5fa15 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java @@ -35,8 +35,8 @@ public final class BazelProtoLibraryRule implements RuleDefinition { private static final Label DEFAULT_PROTO_COMPILER = Label.parseAbsoluteUnchecked("@com_google_protobuf//:protoc"); - private static final Attribute.LateBoundDefault<?, Label> PROTO_COMPILER = - Attribute.LateBoundDefault.fromTargetConfiguration( + private static final Attribute.LabelLateBoundDefault<?> PROTO_COMPILER = + Attribute.LabelLateBoundDefault.fromTargetConfiguration( ProtoConfiguration.class, DEFAULT_PROTO_COMPILER, (rule, attributes, protoConfig) -> diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AspectDefinitionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AspectDefinitionTest.java index 9b11f04fb9..d6d0a967be 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/AspectDefinitionTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/AspectDefinitionTest.java @@ -28,6 +28,7 @@ import com.google.devtools.build.lib.packages.AdvertisedProviderSet; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy; @@ -76,8 +77,8 @@ public class AspectDefinitionTest { Attribute implicit = attr("$runtime", BuildType.LABEL) .value(Label.parseAbsoluteUnchecked("//run:time")) .build(); - LateBoundDefault<Void, Label> latebound = - LateBoundDefault.fromConstant(Label.parseAbsoluteUnchecked("//run:away")); + LabelLateBoundDefault<Void> latebound = + LateBoundDefault.fromConstantForTesting(Label.parseAbsoluteUnchecked("//run:away")); AspectDefinition simple = new AspectDefinition.Builder(TEST_ASPECT_CLASS) .add(implicit) .add(attr(":latebound", BuildType.LABEL).value(latebound)) diff --git a/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java b/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java index b4d91c341f..5673ebbeb3 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java @@ -27,10 +27,9 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.analysis.util.MockRule; -import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.Location; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.NoSuchTargetException; import com.google.devtools.build.lib.packages.Package; @@ -236,8 +235,8 @@ public class CircularDependencyTest extends BuildViewTestCase { /** A late bound dependency which depends on the 'dep' label if the 'define' is in --defines. */ // TODO(b/65746853): provide a way to do this without passing the entire configuration - private static final LateBoundDefault<BuildConfiguration, Label> LATE_BOUND_DEP = - LateBoundDefault.fromTargetConfiguration( + private static final LabelLateBoundDefault<BuildConfiguration> LATE_BOUND_DEP = + LabelLateBoundDefault.fromTargetConfiguration( BuildConfiguration.class, null, (rule, attributes, config) -> diff --git a/src/test/java/com/google/devtools/build/lib/analysis/ConfigurationsForLateBoundTargetsTest.java b/src/test/java/com/google/devtools/build/lib/analysis/ConfigurationsForLateBoundTargetsTest.java index fe0bd77489..75e51e4aec 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/ConfigurationsForLateBoundTargetsTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/ConfigurationsForLateBoundTargetsTest.java @@ -65,7 +65,7 @@ public class ConfigurationsForLateBoundTargetsTest extends AnalysisTestCase { .add( attr(":latebound_attr", LABEL) .value( - Attribute.LateBoundDefault.fromConstant( + Attribute.LateBoundDefault.fromConstantForTesting( Label.parseAbsoluteUnchecked("//foo:latebound_dep"))) .cfg(CHANGE_FOO_FLAG_TRANSITION)) .requiresConfigurationFragments(LateBoundSplitUtil.TestFragment.class); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/LateBoundSplitUtil.java b/src/test/java/com/google/devtools/build/lib/analysis/LateBoundSplitUtil.java index 0be1b97e4e..c5bfa97a43 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/LateBoundSplitUtil.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/LateBoundSplitUtil.java @@ -111,7 +111,7 @@ public class LateBoundSplitUtil { .allowedRuleClasses(Attribute.ANY_RULE) .cfg(SIMPLE_SPLIT) .value( - Attribute.LateBoundDefault.fromConstant( + Attribute.LateBoundDefault.fromConstantForTesting( Label.parseAbsoluteUnchecked("//foo:latebound_dep")))) .requiresConfigurationFragments(TestFragment.class); }); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/constraints/ConstraintsTest.java b/src/test/java/com/google/devtools/build/lib/analysis/constraints/ConstraintsTest.java index 7f7049c152..ee090f9a4e 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/constraints/ConstraintsTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/constraints/ConstraintsTest.java @@ -88,20 +88,25 @@ public class ConstraintsTest extends AbstractConstraintsTest { .compatibleWith(env.getLabel("//buildenv/rule_class_compat:a")) .restrictedTo(env.getLabel("//buildenv/rule_class_compat:b"))); - private static final MockRule RULE_WITH_IMPLICIT_AND_LATEBOUND_DEFAULTS = () -> MockRule.define( - "rule_with_implicit_and_latebound_deps", - (builder, env) -> - builder - .setUndocumented() - .add(Attribute.attr("$implicit", BuildType.LABEL) - .value(Label.parseAbsoluteUnchecked("//helpers:implicit"))) - .add(Attribute.attr(":latebound", BuildType.LABEL) - .value( - Attribute.LateBoundDefault.fromConstant( - Label.parseAbsoluteUnchecked("//helpers:latebound")))) - .add(Attribute.attr("normal", BuildType.LABEL) - .allowedFileTypes(FileTypeSet.NO_FILE) - .value(Label.parseAbsoluteUnchecked("//helpers:default")))); + private static final MockRule RULE_WITH_IMPLICIT_AND_LATEBOUND_DEFAULTS = + () -> + MockRule.define( + "rule_with_implicit_and_latebound_deps", + (builder, env) -> + builder + .setUndocumented() + .add( + Attribute.attr("$implicit", BuildType.LABEL) + .value(Label.parseAbsoluteUnchecked("//helpers:implicit"))) + .add( + Attribute.attr(":latebound", BuildType.LABEL) + .value( + Attribute.LateBoundDefault.fromConstantForTesting( + Label.parseAbsoluteUnchecked("//helpers:latebound")))) + .add( + Attribute.attr("normal", BuildType.LABEL) + .allowedFileTypes(FileTypeSet.NO_FILE) + .value(Label.parseAbsoluteUnchecked("//helpers:default")))); private static final MockRule RULE_WITH_ENFORCED_IMPLICIT_ATTRIBUTE = () -> MockRule.define( "rule_with_enforced_implicit_deps", diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java index ac8872f4c4..353f62f4a4 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java @@ -43,7 +43,7 @@ import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; -import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; +import com.google.devtools.build.lib.packages.Attribute.LabelListLateBoundDefault; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.NativeAspectClass; import com.google.devtools.build.lib.packages.Rule; @@ -731,11 +731,9 @@ public class TestAspects { attr("$dep", LABEL).value(Label.parseAbsoluteUnchecked("//extra:extra"))); // TODO(b/65746853): provide a way to do this without passing the entire configuration - private static final LateBoundDefault<?, List<Label>> PLUGINS_LABEL_LIST = - LateBoundDefault.fromTargetConfiguration( - JavaConfiguration.class, - ImmutableList.of(), - (rule, attributes, javaConfig) -> javaConfig.getPlugins()); + private static final LabelListLateBoundDefault<?> PLUGINS_LABEL_LIST = + LabelListLateBoundDefault.fromTargetConfiguration( + JavaConfiguration.class, (rule, attributes, javaConfig) -> javaConfig.getPlugins()); public static final MockRule LATE_BOUND_DEP_RULE = () -> MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define( |