diff options
author | Michael Staib <mstaib@google.com> | 2015-09-29 23:31:51 +0000 |
---|---|---|
committer | Florian Weikert <fwe@google.com> | 2015-09-30 09:36:25 +0000 |
commit | b51251ed0df121b50fba315d4eee17fa40049e83 (patch) | |
tree | d36907ff0df148711168c8cfaa8cc2eb43201f61 /src | |
parent | 5fb1073d31e392e2f39a067647337043500b348e (diff) |
Extract configuration fragment access logic into ConfigurationFragmentPolicy.
This is the first step toward giving aspects the ability to define their own
required configuration fragments, extracting the required configuration
metadata into a common place.
This should be a no-op refactoring.
--
MOS_MIGRATED_REVID=104249500
Diffstat (limited to 'src')
6 files changed, 268 insertions, 131 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java index 1a2488f881..6d97e86c42 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java @@ -34,6 +34,8 @@ import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy; +import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy; import com.google.devtools.build.lib.packages.ConstantRuleVisibility; import com.google.devtools.build.lib.packages.EnvironmentGroup; import com.google.devtools.build.lib.packages.InputFile; @@ -43,7 +45,6 @@ import com.google.devtools.build.lib.packages.PackageGroupsRuleVisibility; import com.google.devtools.build.lib.packages.PackageSpecification; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleClass; -import com.google.devtools.build.lib.packages.RuleClass.MissingFragmentPolicy; import com.google.devtools.build.lib.packages.RuleVisibility; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.rules.SkylarkRuleConfiguredTargetBuilder; @@ -229,14 +230,16 @@ public final class ConfiguredTargetFactory { if (ruleContext.hasErrors()) { return null; } - if (!rule.getRuleClassObject().getRequiredConfigurationFragments().isEmpty()) { + ConfigurationFragmentPolicy configurationFragmentPolicy = + rule.getRuleClassObject().getConfigurationFragmentPolicy(); + if (!configurationFragmentPolicy.getRequiredConfigurationFragments().isEmpty()) { MissingFragmentPolicy missingFragmentPolicy = - rule.getRuleClassObject().missingFragmentPolicy(); + configurationFragmentPolicy.getMissingFragmentPolicy(); if (missingFragmentPolicy != MissingFragmentPolicy.IGNORE && !configuration.hasAllFragments( - rule.getRuleClassObject().getRequiredConfigurationFragments())) { + configurationFragmentPolicy.getRequiredConfigurationFragments())) { if (missingFragmentPolicy == MissingFragmentPolicy.FAIL_ANALYSIS) { - ruleContext.ruleError(missingFragmentError(ruleContext)); + ruleContext.ruleError(missingFragmentError(ruleContext, configurationFragmentPolicy)); return null; } return createFailConfiguredTarget(ruleContext); @@ -254,10 +257,11 @@ public final class ConfiguredTargetFactory { } } - private String missingFragmentError(RuleContext ruleContext) { + private String missingFragmentError( + RuleContext ruleContext, ConfigurationFragmentPolicy configurationFragmentPolicy) { RuleClass ruleClass = ruleContext.getRule().getRuleClassObject(); Set<Class<?>> missingFragments = new LinkedHashSet<>(); - for (Class<?> fragment : ruleClass.getRequiredConfigurationFragments()) { + for (Class<?> fragment : configurationFragmentPolicy.getRequiredConfigurationFragments()) { if (!ruleContext.getConfiguration().hasFragment(fragment.asSubclass(Fragment.class))) { missingFragments.add(fragment); } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java index 19dbcc354b..9d21ec6fff 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java @@ -51,6 +51,7 @@ import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; import com.google.devtools.build.lib.packages.Attribute.SplitTransition; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.BuildType; +import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy; import com.google.devtools.build.lib.packages.FileTarget; import com.google.devtools.build.lib.packages.FilesetEntry; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction; @@ -137,6 +138,7 @@ public final class RuleContext extends TargetContext private final ImmutableSet<String> features; private final Map<String, Attribute> attributeMap; private final BuildConfiguration hostConfiguration; + private final ConfigurationFragmentPolicy configurationFragmentPolicy; private final ErrorReporter reporter; private ActionOwner actionOwner; @@ -150,6 +152,7 @@ public final class RuleContext extends TargetContext super(builder.env, builder.rule, builder.configuration, builder.prerequisiteMap.get(null), builder.visibility); this.rule = builder.rule; + this.configurationFragmentPolicy = builder.configurationFragmentPolicy; this.targetMap = targetMap; this.filesetEntryMap = filesetEntryMap; this.configConditions = configConditions; @@ -167,7 +170,7 @@ public final class RuleContext extends TargetContext parseFeatures(getConfiguration().getDefaultFeatures(), globallyEnabled, globallyDisabled); for (ImmutableMap.Entry<Class<? extends Fragment>, Fragment> entry : getConfiguration().getAllFragments().entrySet()) { - if (rule.getRuleClassObject().isLegalConfigurationFragment(entry.getKey())) { + if (configurationFragmentPolicy.isLegalConfigurationFragment(entry.getKey())) { globallyEnabled.addAll(entry.getValue().configurationEnabledFeatures(this)); } } @@ -308,9 +311,13 @@ public final class RuleContext extends TargetContext return getConfiguration(config).getSkylarkFragmentNames(); } + public ConfigurationFragmentPolicy getConfigurationFragment() { + return configurationFragmentPolicy; + } + public <T extends Fragment> boolean isLegalFragment( Class<T> fragment, ConfigurationTransition config) { - return rule.getRuleClassObject().isLegalConfigurationFragment(fragment, config); + return configurationFragmentPolicy.isLegalConfigurationFragment(fragment, config); } public <T extends Fragment> boolean isLegalFragment(Class<T> fragment) { @@ -1223,6 +1230,7 @@ public final class RuleContext extends TargetContext public static final class Builder implements RuleErrorConsumer { private final AnalysisEnvironment env; private final Rule rule; + private final ConfigurationFragmentPolicy configurationFragmentPolicy; private final BuildConfiguration configuration; private final BuildConfiguration hostConfiguration; private final PrerequisiteValidator prerequisiteValidator; @@ -1236,6 +1244,7 @@ public final class RuleContext extends TargetContext PrerequisiteValidator prerequisiteValidator) { this.env = Preconditions.checkNotNull(env); this.rule = Preconditions.checkNotNull(rule); + this.configurationFragmentPolicy = rule.getRuleClassObject().getConfigurationFragmentPolicy(); this.configuration = Preconditions.checkNotNull(configuration); this.hostConfiguration = Preconditions.checkNotNull(hostConfiguration); this.prerequisiteValidator = prerequisiteValidator; diff --git a/src/main/java/com/google/devtools/build/lib/packages/ConfigurationFragmentPolicy.java b/src/main/java/com/google/devtools/build/lib/packages/ConfigurationFragmentPolicy.java new file mode 100644 index 0000000000..abad84899e --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/packages/ConfigurationFragmentPolicy.java @@ -0,0 +1,214 @@ +// Copyright 2015 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.packages; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; +import com.google.devtools.build.lib.syntax.FragmentClassNameResolver; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * Policy used to express the set of configuration fragments which are legal for a rule or aspect + * to access. + */ +public final class ConfigurationFragmentPolicy { + + /** + * How to handle the case if the configuration is missing fragments that are required according + * to the rule class. + */ + public enum MissingFragmentPolicy { + /** + * Some rules are monolithic across languages, and we want them to continue to work even when + * individual languages are disabled. Use this policy if the rule implementation is handling + * missing fragments. + */ + IGNORE, + + /** + * Use this policy to generate fail actions for the target rather than failing the analysis + * outright. Again, this is used when rules are monolithic across languages, but we still need + * to analyze the dependent libraries. (Instead of this mechanism, consider annotating + * attributes as unused if certain fragments are unavailable.) + */ + CREATE_FAIL_ACTIONS, + + /** + * Use this policy to fail the analysis of that target with an error message; this is the + * default. + */ + FAIL_ANALYSIS; + } + + /** + * Builder to construct a new ConfigurationFragmentPolicy. + */ + public static final class Builder { + private Set<Class<?>> requiredConfigurationFragments = new LinkedHashSet<>(); + private Map<ConfigurationTransition, ImmutableSet<String>> requiredConfigurationFragmentNames = + new LinkedHashMap<>(); + private MissingFragmentPolicy missingFragmentPolicy = MissingFragmentPolicy.FAIL_ANALYSIS; + private FragmentClassNameResolver fragmentNameResolver; + + /** + * Declares that the implementation of the associated rule class requires the given + * configuration fragments to be present in the configuration. The value is inherited by + * subclasses. + * + * <p>For backwards compatibility, if the set is empty, all fragments may be accessed. But note + * that this is only enforced in the {@link com.google.devtools.build.lib.analysis.RuleContext} + * class. + */ + public Builder requiresConfigurationFragments(Collection<Class<?>> configurationFragments) { + requiredConfigurationFragments.addAll(configurationFragments); + return this; + } + + /** + * Declares that the implementation of the associated rule class requires the given + * configuration fragments to be present in the configuration. The value is inherited by + * subclasses. + * + * <p>For backwards compatibility, if the set is empty, all fragments may be accessed. But note + * that this is only enforced in the {@link com.google.devtools.build.lib.analysis.RuleContext} + * class. + */ + public Builder requiresConfigurationFragments(Class<?>... configurationFragments) { + Collections.addAll(requiredConfigurationFragments, configurationFragments); + return this; + } + + /** + * Sets the policy for the case where the configuration is missing required fragments (see + * {@link #requiresConfigurationFragments}). + */ + public Builder setMissingFragmentPolicy(MissingFragmentPolicy missingFragmentPolicy) { + this.missingFragmentPolicy = missingFragmentPolicy; + return this; + } + + /** + * Declares the configuration fragments that are required by this rule. + * + * <p>In contrast to {@link #requiresConfigurationFragments(Class...)}, this method a) takes the + * names of fragments instead of their classes and b) distinguishes whether the fragments can be + * accessed in host (HOST) or target (NONE) configuration. + */ + public Builder requiresConfigurationFragments( + FragmentClassNameResolver fragmentNameResolver, + Map<ConfigurationTransition, ImmutableSet<String>> configurationFragmentNames) { + requiredConfigurationFragmentNames.putAll(configurationFragmentNames); + this.fragmentNameResolver = fragmentNameResolver; + return this; + } + + public ConfigurationFragmentPolicy build() { + return new ConfigurationFragmentPolicy( + ImmutableSet.copyOf(requiredConfigurationFragments), + ImmutableMap.copyOf(requiredConfigurationFragmentNames), + fragmentNameResolver, + missingFragmentPolicy); + } + } + + /** + * The set of required configuration fragments; this should list all fragments that can be + * accessed by the rule implementation. If empty, all fragments are allowed to be accessed for + * backwards compatibility. + */ + private final ImmutableSet<Class<?>> requiredConfigurationFragments; + + /** + * A dictionary that maps configurations (NONE for target configuration, HOST for host + * configuration) to lists of names of required configuration fragments. + */ + private final ImmutableMap<ConfigurationTransition, ImmutableSet<String>> + requiredConfigurationFragmentNames; + + /** + * Used to resolve the names of fragments in order to compare them to values in {@link + * #requiredConfigurationFragmentNames} + */ + private final FragmentClassNameResolver fragmentNameResolver; + + /** + * What to do during analysis if a configuration fragment is missing. + */ + private final MissingFragmentPolicy missingFragmentPolicy; + + private ConfigurationFragmentPolicy( + ImmutableSet<Class<?>> requiredConfigurationFragments, + ImmutableMap<ConfigurationTransition, ImmutableSet<String>> + requiredConfigurationFragmentNames, + FragmentClassNameResolver fragmentNameResolver, + MissingFragmentPolicy missingFragmentPolicy) { + this.requiredConfigurationFragments = requiredConfigurationFragments; + this.requiredConfigurationFragmentNames = requiredConfigurationFragmentNames; + this.fragmentNameResolver = fragmentNameResolver; + this.missingFragmentPolicy = missingFragmentPolicy; + } + + /** + * The set of required configuration fragments; this contains all fragments that can be + * accessed by the rule implementation. If empty, all fragments are allowed to be accessed for + * backwards compatibility. + */ + public Set<Class<?>> getRequiredConfigurationFragments() { + return requiredConfigurationFragments; + } + + /** + * Checks if the configuration fragment may be accessed (i.e., if it's declared) in the specified + * configuration (target or host). + */ + public boolean isLegalConfigurationFragment( + Class<?> configurationFragment, ConfigurationTransition config) { + return requiredConfigurationFragments.contains(configurationFragment) + || hasLegalFragmentName(configurationFragment, config); + } + + public boolean isLegalConfigurationFragment(Class<?> configurationFragment) { + // NONE means target configuration. + return isLegalConfigurationFragment(configurationFragment, ConfigurationTransition.NONE); + } + + /** + * Checks whether the name of the given fragment class was declared as required in the + * specified configuration (target or host). + */ + private boolean hasLegalFragmentName( + Class<?> configurationFragment, ConfigurationTransition config) { + if (fragmentNameResolver == null) { + return false; + } + + String name = fragmentNameResolver.resolveName(configurationFragment); + ImmutableSet<String> fragmentNames = requiredConfigurationFragmentNames.get(config); + return (name != null && fragmentNames != null && fragmentNames.contains(name)); + } + + /** + * Whether to fail analysis if any of the required configuration fragments are missing. + */ + public MissingFragmentPolicy getMissingFragmentPolicy() { + return missingFragmentPolicy; + } +} 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 a806435457..663498860f 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 @@ -35,6 +35,7 @@ import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; import com.google.devtools.build.lib.packages.BuildType.SelectorList; +import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; import com.google.devtools.build.lib.syntax.Argument; import com.google.devtools.build.lib.syntax.BaseFunction; @@ -198,33 +199,6 @@ public final class RuleClass { }; /** - * How to handle the case if the configuration is missing fragments that are required according - * to the rule class. - */ - public enum MissingFragmentPolicy { - /** - * Some rules are monolithic across languages, and we want them to continue to work even when - * individual languages are disabled. Use this policy if the rule implementation is handling - * missing fragments. - */ - IGNORE, - - /** - * Use this policy to generate fail actions for the target rather than failing the analysis - * outright. Again, this is used when rules are monolithic across languages, but we still need - * to analyze the dependent libraries. (Instead of this mechanism, consider annotating - * attributes as unused if certain fragments are unavailable.) - */ - CREATE_FAIL_ACTIONS, - - /** - * Use this policy to fail the analysis of that target with an error message; this is the - * default. - */ - FAIL_ANALYSIS; - } - - /** * For Bazel's constraint system: the attribute that declares the set of environments a rule * supports, overriding the defaults for their respective groups. */ @@ -502,11 +476,8 @@ public final class RuleClass { private Function<? super Rule, Map<String, Label>> externalBindingsFunction = NO_EXTERNAL_BINDINGS; private Environment ruleDefinitionEnvironment = null; - private Set<Class<?>> configurationFragments = new LinkedHashSet<>(); - private MissingFragmentPolicy missingFragmentPolicy = MissingFragmentPolicy.FAIL_ANALYSIS; - private Map<ConfigurationTransition, ImmutableSet<String>> requiredFragmentNames = - new LinkedHashMap<>(); - private FragmentClassNameResolver fragmentNameResolver; + private ConfigurationFragmentPolicy.Builder configurationFragmentPolicy = + new ConfigurationFragmentPolicy.Builder(); private boolean supportsConstraintChecking = true; @@ -534,8 +505,10 @@ public final class RuleClass { if (parent.preferredDependencyPredicate != Predicates.<String>alwaysFalse()) { setPreferredDependencyPredicate(parent.preferredDependencyPredicate); } - configurationFragments.addAll(parent.requiredConfigurationFragments); - missingFragmentPolicy = parent.missingFragmentPolicy; + configurationFragmentPolicy.requiresConfigurationFragments( + parent.getConfigurationFragmentPolicy().getRequiredConfigurationFragments()); + configurationFragmentPolicy.setMissingFragmentPolicy( + parent.getConfigurationFragmentPolicy().getMissingFragmentPolicy()); supportsConstraintChecking = parent.supportsConstraintChecking; for (Attribute attribute : parent.getAttributes()) { @@ -593,8 +566,7 @@ public final class RuleClass { workspaceOnly, outputsDefaultExecutable, implicitOutputsFunction, configurator, configuredTargetFactory, validityPredicate, preferredDependencyPredicate, ImmutableSet.copyOf(advertisedProviders), configuredTargetFunction, - externalBindingsFunction, ruleDefinitionEnvironment, configurationFragments, - ImmutableMap.copyOf(requiredFragmentNames), fragmentNameResolver, missingFragmentPolicy, + externalBindingsFunction, ruleDefinitionEnvironment, configurationFragmentPolicy.build(), supportsConstraintChecking, attributes.values().toArray(new Attribute[0])); } @@ -606,8 +578,8 @@ public final class RuleClass { * that this is only enforced in the {@link com.google.devtools.build.lib.analysis.RuleContext} * class. */ - public Builder requiresConfigurationFragments(Class<?>... configurationFragment) { - Collections.addAll(configurationFragments, configurationFragment); + public Builder requiresConfigurationFragments(Class<?>... configurationFragments) { + configurationFragmentPolicy.requiresConfigurationFragments(configurationFragments); return this; } @@ -616,7 +588,7 @@ public final class RuleClass { * {@link #requiresConfigurationFragments}). */ public Builder setMissingFragmentPolicy(MissingFragmentPolicy missingFragmentPolicy) { - this.missingFragmentPolicy = missingFragmentPolicy; + configurationFragmentPolicy.setMissingFragmentPolicy(missingFragmentPolicy); return this; } @@ -630,8 +602,8 @@ public final class RuleClass { public Builder requiresConfigurationFragments( FragmentClassNameResolver fragmentNameResolver, Map<ConfigurationTransition, ImmutableSet<String>> configurationFragmentNames) { - requiredFragmentNames.putAll(configurationFragmentNames); - this.fragmentNameResolver = fragmentNameResolver; + configurationFragmentPolicy.requiresConfigurationFragments( + fragmentNameResolver, configurationFragmentNames); return this; } @@ -978,29 +950,9 @@ public final class RuleClass { @Nullable private final Environment ruleDefinitionEnvironment; /** - * The set of required configuration fragments; this should list all fragments that can be - * accessed by the rule implementation. If empty, all fragments are allowed to be accessed for - * backwards compatibility. - */ - private final ImmutableSet<Class<?>> requiredConfigurationFragments; - - /** - * A dictionary that maps configurations (NONE for target configuration, HOST for host - * configuration) to lists of names of required configuration fragments. - */ - private final ImmutableMap<ConfigurationTransition, ImmutableSet<String>> - requiredConfigurationFragmentNames; - - /** - * Used to resolve the names of fragments in order to compare them to values in {@link - * #requiredConfigurationFragmentNames} - */ - private final FragmentClassNameResolver fragmentNameResolver; - - /** - * What to do during analysis if a configuration fragment is missing. + * The set of configuration fragments which are legal for this rule's implementation to access. */ - private final MissingFragmentPolicy missingFragmentPolicy; + private final ConfigurationFragmentPolicy configurationFragmentPolicy; /** * Determines whether instances of this rule should be checked for constraint compatibility @@ -1049,10 +1001,10 @@ public final class RuleClass { configuredTargetFunction, externalBindingsFunction, ruleDefinitionEnvironment, - allowedConfigurationFragments, - ImmutableMap.<ConfigurationTransition, ImmutableSet<String>>of(), - null, // FragmentClassNameResolver - missingFragmentPolicy, + new ConfigurationFragmentPolicy.Builder() + .requiresConfigurationFragments(allowedConfigurationFragments) + .setMissingFragmentPolicy(missingFragmentPolicy) + .build(), supportsConstraintChecking, attributes); } @@ -1091,10 +1043,7 @@ public final class RuleClass { @Nullable BaseFunction configuredTargetFunction, Function<? super Rule, Map<String, Label>> externalBindingsFunction, @Nullable Environment ruleDefinitionEnvironment, - Set<Class<?>> allowedConfigurationFragments, - ImmutableMap<ConfigurationTransition, ImmutableSet<String>> allowedConfigurationFragmentNames, - @Nullable FragmentClassNameResolver fragmentNameResolver, - MissingFragmentPolicy missingFragmentPolicy, + ConfigurationFragmentPolicy configurationFragmentPolicy, boolean supportsConstraintChecking, Attribute... attributes) { this.name = name; @@ -1115,10 +1064,7 @@ public final class RuleClass { this.attributes = ImmutableList.copyOf(attributes); this.workspaceOnly = workspaceOnly; this.outputsDefaultExecutable = outputsDefaultExecutable; - this.requiredConfigurationFragments = ImmutableSet.copyOf(allowedConfigurationFragments); - this.requiredConfigurationFragmentNames = allowedConfigurationFragmentNames; - this.fragmentNameResolver = fragmentNameResolver; - this.missingFragmentPolicy = missingFragmentPolicy; + this.configurationFragmentPolicy = configurationFragmentPolicy; this.supportsConstraintChecking = supportsConstraintChecking; // create the index: @@ -1264,49 +1210,10 @@ public final class RuleClass { } /** - * The set of required configuration fragments; this contains all fragments that can be - * accessed by the rule implementation. If empty, all fragments are allowed to be accessed for - * backwards compatibility. - */ - public Set<Class<?>> getRequiredConfigurationFragments() { - return requiredConfigurationFragments; - } - - /** - * Checks if the configuration fragment may be accessed (i.e., if it's declared) in the specified - * configuration (target or host). - */ - public boolean isLegalConfigurationFragment( - Class<?> configurationFragment, ConfigurationTransition config) { - return requiredConfigurationFragments.contains(configurationFragment) - || hasLegalFragmentName(configurationFragment, config); - } - - public boolean isLegalConfigurationFragment(Class<?> configurationFragment) { - // NONE means target configuration. - return isLegalConfigurationFragment(configurationFragment, ConfigurationTransition.NONE); - } - - /** - * Checks whether the name of the given fragment class was declared as required fragment in the - * specified configuration (target or host). - */ - private boolean hasLegalFragmentName( - Class<?> configurationFragment, ConfigurationTransition config) { - if (fragmentNameResolver == null) { - return false; - } - - String name = fragmentNameResolver.resolveName(configurationFragment); - ImmutableSet<String> fragmentNames = requiredConfigurationFragmentNames.get(config); - return (name != null && fragmentNames != null && fragmentNames.contains(name)); - } - - /** - * Whether to fail analysis if any of the required configuration fragments are missing. + * Returns this rule's policy for configuration fragment access. */ - public MissingFragmentPolicy missingFragmentPolicy() { - return missingFragmentPolicy; + public ConfigurationFragmentPolicy getConfigurationFragmentPolicy() { + return configurationFragmentPolicy; } /** diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java index 06e068dd2e..8053543fab 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy; import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.packages.NoSuchTargetException; import com.google.devtools.build.lib.packages.NoSuchThingException; @@ -136,8 +137,10 @@ public class TransitiveTargetFunction // Get configuration fragments directly required by this target. if (target instanceof Rule) { + ConfigurationFragmentPolicy configurationFragmentPolicy = + target.getAssociatedRule().getRuleClassObject().getConfigurationFragmentPolicy(); Set<Class<?>> configFragments = - target.getAssociatedRule().getRuleClassObject().getRequiredConfigurationFragments(); + configurationFragmentPolicy.getRequiredConfigurationFragments(); // An empty result means this rule requires all fragments (which practically means // the rule isn't yet declaring its actually needed fragments). So load everything. configFragments = configFragments.isEmpty() ? getAllFragments() : configFragments; diff --git a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java index f64d341230..0a89a760ee 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java @@ -1,4 +1,4 @@ -// Copyright 2006-2015 Google Inc. All rights reserved. +// Copyright 2015 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. @@ -43,9 +43,9 @@ import com.google.devtools.build.lib.events.EventKind; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.events.Location.LineAndColumn; import com.google.devtools.build.lib.packages.Attribute.ValidityPredicate; +import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy; import com.google.devtools.build.lib.packages.Package.Builder; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; -import com.google.devtools.build.lib.packages.RuleClass.MissingFragmentPolicy; import com.google.devtools.build.lib.packages.util.PackageLoadingTestCase; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.Path; @@ -712,9 +712,9 @@ public class RuleClassTest extends PackageLoadingTestCase { public void testRequiredFragmentInheritance() throws Exception { RuleClass parentRuleClass = createParentRuleClass(); RuleClass childRuleClass = createChildRuleClass(parentRuleClass); - assertThat(parentRuleClass.getRequiredConfigurationFragments()) + assertThat(parentRuleClass.getConfigurationFragmentPolicy().getRequiredConfigurationFragments()) .containsExactly(DummyFragment.class); - assertThat(childRuleClass.getRequiredConfigurationFragments()) + assertThat(childRuleClass.getConfigurationFragmentPolicy().getRequiredConfigurationFragments()) .containsExactly(DummyFragment.class); } |