aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Michael Staib <mstaib@google.com>2015-09-29 23:31:51 +0000
committerGravatar Florian Weikert <fwe@google.com>2015-09-30 09:36:25 +0000
commitb51251ed0df121b50fba315d4eee17fa40049e83 (patch)
treed36907ff0df148711168c8cfaa8cc2eb43201f61 /src
parent5fb1073d31e392e2f39a067647337043500b348e (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')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/ConfigurationFragmentPolicy.java214
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleClass.java141
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java5
-rw-r--r--src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java8
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);
}