Make aspects work through bind().
bind() is assumed to be able to provide any provider. This is suboptimal, but beats the alternative of traversing the dependency graph to an arbitrary depth.
The reason for the removal of the iteration ability in TransitiveInfoCollection is that now aspects can be attached to BindConfiguredTarget, too, which is not a RuleConfiguredTarget. Whereas I could have implemented the iterator, it was used only in BindConfiguredTarget anyway, so there didn't seem to be much reason to.
Some work towards #952.
--
MOS_MIGRATED_REVID=120549877
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
index f438c99..645cd6d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
@@ -87,6 +87,10 @@
return providers.values().iterator();
}
+ public static ConfiguredAspect forAlias(ConfiguredAspect real) {
+ return new ConfiguredAspect(real.getName(), real.getProviders());
+ }
+
/**
* Builder for {@link ConfiguredAspect}.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
index fe8bddc..ef48488 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
@@ -61,7 +61,6 @@
* <p>Includes logic to derive the right configurations depending on transition type.
*/
public abstract class DependencyResolver {
-
protected DependencyResolver() {
}
@@ -450,7 +449,7 @@
}
private ImmutableSet<AspectDescriptor> requiredAspects(
- Aspect aspect, Attribute attribute, Target target, Rule originalRule) {
+ Aspect aspect, Attribute attribute, final Target target, Rule originalRule) {
if (!(target instanceof Rule)) {
return ImmutableSet.of();
}
@@ -459,7 +458,7 @@
RuleClass ruleClass = ((Rule) target).getRuleClassObject();
ImmutableSet.Builder<AspectDescriptor> result = ImmutableSet.builder();
for (Aspect aspectCandidate : aspectCandidates) {
- if (Sets.difference(
+ if (ruleClass.canHaveAnyProvider() || Sets.difference(
aspectCandidate.getDefinition().getRequiredProviders(),
ruleClass.getAdvertisedProviders())
.isEmpty()) {
@@ -499,8 +498,9 @@
return aspectCandidates;
}
- private void visitRule(Rule rule, ListMultimap<Attribute, LabelAndConfiguration> labelMap,
- NestedSetBuilder<Label> rootCauses, ListMultimap<Attribute, Dependency> outgoingEdges) {
+ private void visitRule(Rule rule,
+ ListMultimap<Attribute, LabelAndConfiguration> labelMap, NestedSetBuilder<Label> rootCauses,
+ ListMultimap<Attribute, Dependency> outgoingEdges) {
visitRule(rule, /*aspect=*/ null, labelMap, rootCauses, outgoingEdges);
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/EnvironmentGroupConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/EnvironmentGroupConfiguredTarget.java
index dd1c29f..3465a1d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/EnvironmentGroupConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/EnvironmentGroupConfiguredTarget.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.analysis;
-import com.google.common.collect.UnmodifiableIterator;
import com.google.devtools.build.lib.packages.EnvironmentGroup;
import com.google.devtools.build.lib.util.Preconditions;
@@ -38,9 +37,4 @@
// No providers.
return null;
}
-
- @Override
- public UnmodifiableIterator<TransitiveInfoProvider> iterator() {
- throw new UnsupportedOperationException();
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
index 86b837f..42178bf 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
@@ -16,7 +16,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.collect.UnmodifiableIterator;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -83,9 +82,4 @@
public Object get(String providerKey) {
return null;
}
-
- @Override
- public UnmodifiableIterator<TransitiveInfoProvider> iterator() {
- return providers.values().iterator();
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java
new file mode 100644
index 0000000..6e01d8e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java
@@ -0,0 +1,141 @@
+// Copyright 2016 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.analysis;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A single dependency with its configured target and aspects merged together.
+ *
+ * <p>This is an ephemeral object created only for the analysis of a single configured target.
+ * After that configured target is analyzed, this is thrown away.
+ */
+public class MergedConfiguredTarget extends AbstractConfiguredTarget {
+ private final ConfiguredTarget base;
+ private final ImmutableMap<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider>
+ providers;
+
+ private MergedConfiguredTarget(ConfiguredTarget base,
+ ImmutableMap<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> providers) {
+ super(base.getTarget(), base.getConfiguration());
+ this.base = base;
+ this.providers = providers;
+ }
+
+ /**
+ * Returns a value provided by this target. Only meant to use from Skylark.
+ */
+ @Override
+ public Object get(String providerKey) {
+ return getProvider(SkylarkProviders.class).getValue(providerKey);
+ }
+
+ @Override
+ public <P extends TransitiveInfoProvider> P getProvider(Class<P> providerClass) {
+ AnalysisUtils.checkProvider(providerClass);
+
+ Object provider = providers.get(providerClass);
+ if (provider == null) {
+ provider = base.getProvider(providerClass);
+ }
+
+ return providerClass.cast(provider);
+ }
+
+ /**
+ * Creates an instance based on a configured target and a set of aspects.
+ */
+ public static ConfiguredTarget of(ConfiguredTarget base,
+ Iterable<ConfiguredAspect> aspects) {
+ if (Iterables.isEmpty(aspects)) {
+ // If there are no aspects, don't bother with creating a proxy object
+ return base;
+ }
+
+ Set<Class<? extends TransitiveInfoProvider>> providers = new HashSet<>();
+
+ ImmutableSet<Class<? extends TransitiveInfoProvider>> baseProviders =
+ ImmutableSet.copyOf(providers);
+
+ // Merge output group providers.
+ OutputGroupProvider mergedOutputGroupProvider =
+ OutputGroupProvider.merge(getAllProviders(base, aspects, OutputGroupProvider.class));
+
+ // Merge Skylark providers.
+ SkylarkProviders mergedSkylarkProviders =
+ SkylarkProviders.merge(getAllProviders(base, aspects, SkylarkProviders.class));
+
+ // Merge extra-actions provider.
+ ExtraActionArtifactsProvider mergedExtraActionProviders = ExtraActionArtifactsProvider.merge(
+ getAllProviders(base, aspects, ExtraActionArtifactsProvider.class));
+
+ Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> aspectProviders =
+ new LinkedHashMap<>();
+ if (mergedOutputGroupProvider != null) {
+ aspectProviders.put(OutputGroupProvider.class, mergedOutputGroupProvider);
+ }
+ if (mergedSkylarkProviders != null) {
+ aspectProviders.put(SkylarkProviders.class, mergedSkylarkProviders);
+ }
+ if (mergedExtraActionProviders != null) {
+ aspectProviders.put(ExtraActionArtifactsProvider.class, mergedExtraActionProviders);
+ }
+
+ for (ConfiguredAspect aspect : aspects) {
+ for (Map.Entry<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> entry :
+ aspect.getProviders().entrySet()) {
+ if (OutputGroupProvider.class.equals(entry.getKey())
+ || SkylarkProviders.class.equals(entry.getKey())
+ || ExtraActionArtifactsProvider.class.equals(entry.getKey())) {
+ continue;
+ }
+
+ if (base.getProvider(entry.getKey()) != null
+ || aspectProviders.containsKey(entry.getKey())) {
+ throw new IllegalStateException("Provider " + entry.getKey() + " provided twice");
+ }
+
+ aspectProviders.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return new MergedConfiguredTarget(base, ImmutableMap.copyOf(aspectProviders));
+ }
+
+ private static <T extends TransitiveInfoProvider> List<T> getAllProviders(
+ ConfiguredTarget base, Iterable<ConfiguredAspect> aspects, Class<T> providerClass) {
+ T baseProvider = base.getProvider(providerClass);
+ List<T> providers = new ArrayList<>();
+ if (baseProvider != null) {
+ providers.add(baseProvider);
+ }
+
+ for (ConfiguredAspect configuredAspect : aspects) {
+ final T aspectProvider = configuredAspect.getProvider(providerClass);
+ if (aspectProvider == null) {
+ continue;
+ }
+ providers.add(aspectProvider);
+ }
+ return providers;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/PackageGroupConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/PackageGroupConfiguredTarget.java
index c148ecd..549932d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/PackageGroupConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/PackageGroupConfiguredTarget.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.analysis;
-import com.google.common.collect.UnmodifiableIterator;
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;
@@ -70,9 +69,4 @@
// No providers.
return null;
}
-
- @Override
- public UnmodifiableIterator<TransitiveInfoProvider> iterator() {
- throw new UnsupportedOperationException();
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
index 9773cc1..211097f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
@@ -16,8 +16,6 @@
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.UnmodifiableIterator;
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
import com.google.devtools.build.lib.analysis.config.RunUnder;
import com.google.devtools.build.lib.packages.OutputFile;
@@ -25,10 +23,7 @@
import com.google.devtools.build.lib.rules.SkylarkApiProvider;
import com.google.devtools.build.lib.util.Preconditions;
-import java.util.ArrayList;
-import java.util.HashSet;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -51,7 +46,6 @@
private final ImmutableMap<Class<? extends TransitiveInfoProvider>, Object> providers;
private final Set<ConfigMatchingProvider> configConditions;
- private final ImmutableList<ConfiguredAspect> configuredAspects;
RuleConfiguredTarget(RuleContext ruleContext,
ImmutableMap<String, Object> skylarkProviders,
@@ -76,7 +70,6 @@
this.providers = ImmutableMap.copyOf(providerBuilder);
this.configConditions = ruleContext.getConfigConditions();
- this.configuredAspects = ImmutableList.of();
// If this rule is the run_under target, then check that we have an executable; note that
// run_under is only set in the target configuration, and the target must also be analyzed for
@@ -98,117 +91,6 @@
}
/**
- * Merge a configured target with its associated aspects.
- *
- * <p>If aspects are present, the configured target must be created from a rule (instead of e.g.
- * an input or an output file).
- */
- public static ConfiguredTarget mergeAspects(
- ConfiguredTarget base, Iterable<ConfiguredAspect> aspects) {
- if (Iterables.isEmpty(aspects)) {
- // If there are no aspects, don't bother with creating a proxy object
- return base;
- } else {
- // Aspects can only be attached to rules for now. This invariant is upheld by
- // DependencyResolver#requiredAspects()
- return new RuleConfiguredTarget((RuleConfiguredTarget) base, aspects);
- }
- }
-
- /**
- * Creates an instance based on a configured target and a set of aspects.
- */
- private RuleConfiguredTarget(RuleConfiguredTarget base, Iterable<ConfiguredAspect> aspects) {
- super(base.getTarget(), base.getConfiguration());
-
- Set<Class<? extends TransitiveInfoProvider>> providers = new HashSet<>();
-
- providers.addAll(base.providers.keySet());
-
- // Merge output group providers.
- OutputGroupProvider mergedOutputGroupProvider =
- OutputGroupProvider.merge(getAllProviders(base, aspects, OutputGroupProvider.class));
-
- // Merge Skylark providers.
- SkylarkProviders mergedSkylarkProviders =
- SkylarkProviders.merge(getAllProviders(base, aspects, SkylarkProviders.class));
-
- // Merge extra-actions provider.
- ExtraActionArtifactsProvider mergedExtraActionProviders = ExtraActionArtifactsProvider.merge(
- getAllProviders(base, aspects, ExtraActionArtifactsProvider.class));
-
- // Validate that all other providers are only provided once.
- for (ConfiguredAspect configuredAspect : aspects) {
- for (TransitiveInfoProvider aspectProvider : configuredAspect) {
- Class<? extends TransitiveInfoProvider> aClass = aspectProvider.getClass();
- if (OutputGroupProvider.class.equals(aClass)) {
- continue;
- }
- if (SkylarkProviders.class.equals(aClass)) {
- continue;
- }
- if (ExtraActionArtifactsProvider.class.equals(aClass)) {
- continue;
- }
- if (!providers.add(aClass)) {
- throw new IllegalStateException("Provider " + aClass + " provided twice");
- }
- }
- }
-
- if (base.getProvider(OutputGroupProvider.class) == mergedOutputGroupProvider
- && base.getProvider(SkylarkProviders.class) == mergedSkylarkProviders
- && base.getProvider(ExtraActionArtifactsProvider.class) == mergedExtraActionProviders) {
- this.providers = base.providers;
- } else {
- ImmutableMap.Builder<Class<? extends TransitiveInfoProvider>, Object> builder =
- new ImmutableMap.Builder<>();
- for (Class<? extends TransitiveInfoProvider> aClass : base.providers.keySet()) {
- if (OutputGroupProvider.class.equals(aClass)) {
- continue;
- }
- if (SkylarkProviders.class.equals(aClass)) {
- continue;
- }
- if (ExtraActionArtifactsProvider.class.equals(aClass)) {
- continue;
- }
- builder.put(aClass, base.providers.get(aClass));
- }
- if (mergedOutputGroupProvider != null) {
- builder.put(OutputGroupProvider.class, mergedOutputGroupProvider);
- }
- if (mergedSkylarkProviders != null) {
- builder.put(SkylarkProviders.class, mergedSkylarkProviders);
- }
- if (mergedExtraActionProviders != null) {
- builder.put(ExtraActionArtifactsProvider.class, mergedExtraActionProviders);
- }
- this.providers = builder.build();
- }
- this.configConditions = base.configConditions;
- this.configuredAspects = ImmutableList.copyOf(aspects);
- }
-
- private static <T extends TransitiveInfoProvider> List<T> getAllProviders(
- RuleConfiguredTarget base, Iterable<ConfiguredAspect> aspects, Class<T> providerClass) {
- T baseProvider = base.getProvider(providerClass);
- List<T> providers = new ArrayList<>();
- if (baseProvider != null) {
- providers.add(baseProvider);
- }
-
- for (ConfiguredAspect configuredAspect : aspects) {
- final T aspectProvider = configuredAspect.getProvider(providerClass);
- if (aspectProvider == null) {
- continue;
- }
- providers.add(aspectProvider);
- }
- return providers;
- }
-
- /**
* The configuration conditions that trigger this rule's configurable attributes.
*/
Set<ConfigMatchingProvider> getConfigConditions() {
@@ -222,15 +104,10 @@
// class?
Object provider = providers.get(providerClass);
if (provider == null) {
- for (ConfiguredAspect configuredAspect : configuredAspects) {
- provider = configuredAspect.getProviders().get(providerClass);
- if (provider != null) {
- break;
- }
- }
+ return null;
+ } else {
+ return providerClass.cast(provider);
}
-
- return providerClass.cast(provider);
}
/**
@@ -247,23 +124,6 @@
}
@Override
- public UnmodifiableIterator<TransitiveInfoProvider> iterator() {
- Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> allProviders =
- new LinkedHashMap<>();
- for (int i = configuredAspects.size() - 1; i >= 0; i--) {
- for (TransitiveInfoProvider tip : configuredAspects.get(i)) {
- allProviders.put(tip.getClass(), tip);
- }
- }
-
- for (Map.Entry<Class<? extends TransitiveInfoProvider>, Object> entry : providers.entrySet()) {
- allProviders.put(entry.getKey(), entry.getKey().cast(entry.getValue()));
- }
-
- return ImmutableList.copyOf(allProviders.values()).iterator();
- }
-
- @Override
public String errorMessage(String name) {
return String.format("target (rule class of '%s') doesn't have provider '%s'.",
getTarget().getRuleClass(), name);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
index 2264d8f..42b8297 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.analysis;
-import com.google.common.collect.UnmodifiableIterator;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
@@ -95,7 +94,7 @@
+ "These extra providers are defined in the <code>struct</code> returned by the rule "
+ "implementation function.</li>"
+ "</ul>")
-public interface TransitiveInfoCollection extends Iterable<TransitiveInfoProvider> {
+public interface TransitiveInfoCollection {
/**
* Returns the transitive information provider requested, or null if the provider is not found.
@@ -121,10 +120,4 @@
* The transitive information has to have been added using the Skylark framework.
*/
@Nullable Object get(String providerKey);
-
- /**
- * Returns an unmodifiable iterator over the transitive info providers in the collections.
- */
- @Override
- UnmodifiableIterator<TransitiveInfoProvider> iterator();
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
index 9d2af18..be1bd0b 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
@@ -147,16 +147,17 @@
}
RuleClass ruleClass = ((Rule) to).getRuleClassObject();
ImmutableSet<Class<?>> providers = ruleClass.getAdvertisedProviders();
- return visitAspectsIfRequired((Rule) from, attribute, toStringSet(providers), dependencyFilter);
+ return visitAspectsIfRequired((Rule) from, attribute, ruleClass.canHaveAnyProvider(),
+ toStringSet(providers), dependencyFilter);
}
/**
* Returns the attribute -> set of labels that are provided by aspects of attribute.
*/
public static ImmutableMultimap<Attribute, Label> visitAspectsIfRequired(
- Rule from, Attribute attribute, Set<String> advertisedProviders,
+ Rule from, Attribute attribute, boolean canHaveAnyProvider, Set<String> advertisedProviders,
DependencyFilter dependencyFilter) {
- if (advertisedProviders.isEmpty()) {
+ if (advertisedProviders.isEmpty() && !canHaveAnyProvider) {
return ImmutableMultimap.of();
}
@@ -164,7 +165,7 @@
for (Aspect candidateClass : attribute.getAspects(from)) {
// Check if target satisfies condition for this aspect (has to provide all required
// TransitiveInfoProviders)
- if (!advertisedProviders.containsAll(
+ if (!canHaveAnyProvider && !advertisedProviders.containsAll(
candidateClass.getDefinition().getRequiredProviderNames())) {
continue;
}
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 18e69a2..7fd42dc 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
@@ -477,6 +477,7 @@
PredicatesWithMessage.<Rule>alwaysTrue();
private Predicate<String> preferredDependencyPredicate = Predicates.alwaysFalse();
private List<Class<?>> advertisedProviders = new ArrayList<>();
+ private boolean canHaveAnyProvider = false;
private BaseFunction configuredTargetFunction = null;
private Function<? super Rule, Map<String, Label>> externalBindingsFunction =
NO_EXTERNAL_BINDINGS;
@@ -571,7 +572,7 @@
return new RuleClass(name, skylark, skylarkExecutable, documented, publicByDefault,
binaryOutput, workspaceOnly, outputsDefaultExecutable, implicitOutputsFunction,
configurator, configuredTargetFactory, validityPredicate, preferredDependencyPredicate,
- ImmutableSet.copyOf(advertisedProviders), configuredTargetFunction,
+ ImmutableSet.copyOf(advertisedProviders), canHaveAnyProvider, configuredTargetFunction,
externalBindingsFunction, ruleDefinitionEnvironment, configurationFragmentPolicy.build(),
supportsConstraintChecking, attributes.values().toArray(new Attribute[0]));
}
@@ -726,10 +727,21 @@
* not be evaluated for the rule.
*/
public Builder advertiseProvider(Class<?>... providers) {
+ Preconditions.checkState(!canHaveAnyProvider);
Collections.addAll(advertisedProviders, providers);
return this;
}
+ /**
+ * Set if the rule can have any provider. This is true for "alias" rules like
+ * <code>bind</code> .
+ */
+ public Builder canHaveAnyProvider() {
+ Preconditions.checkState(advertisedProviders.isEmpty());
+ canHaveAnyProvider = true;
+ return this;
+ }
+
private void addAttribute(Attribute attribute) {
Preconditions.checkState(!attributes.containsKey(attribute.getName()),
"An attribute with the name '%s' already exists.", attribute.getName());
@@ -967,6 +979,8 @@
*/
private final ImmutableSet<Class<?>> advertisedProviders;
+ private final boolean canHaveAnyProvider;
+
/**
* The Skylark rule implementation of this RuleClass. Null for non Skylark executable RuleClasses.
*/
@@ -1012,6 +1026,7 @@
PredicateWithMessage<Rule> validityPredicate,
Predicate<String> preferredDependencyPredicate,
ImmutableSet<Class<?>> advertisedProviders,
+ boolean canHaveAnyProvider,
@Nullable BaseFunction configuredTargetFunction,
Function<? super Rule, Map<String, Label>> externalBindingsFunction,
@Nullable Environment ruleDefinitionEnvironment,
@@ -1033,6 +1048,7 @@
validityPredicate,
preferredDependencyPredicate,
advertisedProviders,
+ canHaveAnyProvider,
configuredTargetFunction,
externalBindingsFunction,
ruleDefinitionEnvironment,
@@ -1075,6 +1091,7 @@
ConfiguredTargetFactory<?, ?> configuredTargetFactory,
PredicateWithMessage<Rule> validityPredicate, Predicate<String> preferredDependencyPredicate,
ImmutableSet<Class<?>> advertisedProviders,
+ boolean canHaveAnyProvider,
@Nullable BaseFunction configuredTargetFunction,
Function<? super Rule, Map<String, Label>> externalBindingsFunction,
@Nullable Environment ruleDefinitionEnvironment,
@@ -1094,6 +1111,7 @@
this.validityPredicate = validityPredicate;
this.preferredDependencyPredicate = preferredDependencyPredicate;
this.advertisedProviders = advertisedProviders;
+ this.canHaveAnyProvider = canHaveAnyProvider;
this.configuredTargetFunction = configuredTargetFunction;
this.externalBindingsFunction = externalBindingsFunction;
this.ruleDefinitionEnvironment = ruleDefinitionEnvironment;
@@ -1269,6 +1287,14 @@
}
/**
+ * Returns true if this rule, when analyzed, can provide any provider. Used for "alias" rules,
+ * e.g. <code>bind()</code>.
+ */
+ public boolean canHaveAnyProvider() {
+ return canHaveAnyProvider;
+ }
+
+ /**
* For --compile_one_dependency: if multiple rules consume the specified target,
* should we choose this one over the "unpreferred" options?
*/
diff --git a/src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java b/src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java
index 470a11e..8a90c10 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java
@@ -256,4 +256,17 @@
return e.getMessage();
}
}
+
+ public static Label getAliasTarget(Target target) {
+ if (!(target instanceof Rule)) {
+ return null;
+ }
+
+ Rule rule = (Rule) target;
+ if (!rule.getRuleClass().equals("bind")) {
+ return null;
+ }
+
+ return AggregatingAttributeMapper.of(rule).get("actual", BuildType.LABEL);
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
index e66847e..ff0c743 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
@@ -19,7 +19,6 @@
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
-import com.google.common.collect.UnmodifiableIterator;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
@@ -183,11 +182,6 @@
public Object get(String providerKey) {
throw new UnsupportedOperationException();
}
-
- @Override
- public UnmodifiableIterator<TransitiveInfoProvider> iterator() {
- throw new UnsupportedOperationException();
- }
};
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/Bind.java b/src/main/java/com/google/devtools/build/lib/rules/repository/Bind.java
index db927bc..6ea3ede 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/Bind.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/Bind.java
@@ -16,7 +16,6 @@
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.UnmodifiableIterator;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
@@ -72,13 +71,6 @@
}
@Override
- public UnmodifiableIterator<TransitiveInfoProvider> iterator() {
- return configuredTarget == null
- ? ImmutableList.<TransitiveInfoProvider>of().iterator()
- : configuredTarget.iterator();
- }
-
- @Override
public Target getTarget() {
return configuredTarget == null ? null : configuredTarget.getTarget();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/BindRule.java b/src/main/java/com/google/devtools/build/lib/rules/repository/BindRule.java
index 9457d3b..da7ffb3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/BindRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/BindRule.java
@@ -45,6 +45,7 @@
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr("actual", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE))
.setWorkspaceOnly()
+ .canHaveAnyProvider()
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index d325445..56878b1 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -16,6 +16,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
+import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment;
import com.google.devtools.build.lib.analysis.ConfiguredAspect;
import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory;
@@ -42,6 +43,7 @@
import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.packages.SkylarkAspectClass;
import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.rules.SkylarkRuleClassFunctions.SkylarkAspect;
import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ConfiguredValueCreationException;
@@ -167,6 +169,11 @@
throw new AspectFunctionException(e);
}
+ Label aliasLabel = TargetUtils.getAliasTarget(target);
+ if (aliasLabel != null) {
+ return createAliasAspect(env, target, aliasLabel, aspect, key);
+ }
+
if (!(target instanceof Rule)) {
throw new AspectFunctionException(new AspectCreationException(
"aspects must be attached to rules"));
@@ -259,6 +266,32 @@
}
}
+ private SkyValue createAliasAspect(Environment env, Target originalTarget, Label aliasLabel,
+ Aspect aspect, AspectKey originalKey) {
+ SkyKey depKey = AspectValue.key(aliasLabel,
+ originalKey.getAspectConfiguration(),
+ originalKey.getBaseConfiguration(),
+ originalKey.getAspectClass(),
+ originalKey.getParameters());
+ AspectValue real = (AspectValue) env.getValue(depKey);
+ if (env.valuesMissing()) {
+ return null;
+ }
+
+ NestedSet<Package> transitivePackages = NestedSetBuilder.<Package>stableOrder()
+ .addTransitive(real.getTransitivePackages())
+ .add(originalTarget.getPackage())
+ .build();
+ return new AspectValue(
+ originalKey,
+ aspect,
+ originalTarget.getLabel(),
+ originalTarget.getLocation(),
+ ConfiguredAspect.forAlias(real.getConfiguredAspect()),
+ ImmutableList.<Action>of(),
+ transitivePackages);
+ }
+
@Nullable
private AspectValue createAspect(
Environment env,
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
index 4701750..0a5caf0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
@@ -33,7 +33,7 @@
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.Dependency;
import com.google.devtools.build.lib.analysis.LabelAndConfiguration;
-import com.google.devtools.build.lib.analysis.RuleConfiguredTarget;
+import com.google.devtools.build.lib.analysis.MergedConfiguredTarget;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -579,7 +579,7 @@
SkyKey depKey = TO_KEYS.apply(dep);
ConfiguredTarget depConfiguredTarget = depConfiguredTargetMap.get(depKey);
result.put(entry.getKey(),
- RuleConfiguredTarget.mergeAspects(depConfiguredTarget, depAspectMap.get(depKey)));
+ MergedConfiguredTarget.of(depConfiguredTarget, depAspectMap.get(depKey)));
}
return result;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 60904c1..ca8dfad 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -54,7 +54,7 @@
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.Dependency;
-import com.google.devtools.build.lib.analysis.RuleConfiguredTarget;
+import com.google.devtools.build.lib.analysis.MergedConfiguredTarget;
import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction.Factory;
@@ -1197,7 +1197,7 @@
configuredAspects.add(((AspectValue) result.get(aspectKey)).getConfiguredAspect());
}
- cts.put(key, RuleConfiguredTarget.mergeAspects(configuredTarget, configuredAspects));
+ cts.put(key, MergedConfiguredTarget.of(configuredTarget, configuredAspects));
}
return cts.build();
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 4035bfa..8a0c4f1 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
@@ -216,7 +216,7 @@
protected Collection<Label> getAspectLabels(Rule fromRule, Attribute attr, Label toLabel,
ValueOrException2<NoSuchPackageException, NoSuchTargetException> toVal,
- Environment env) {
+ final Environment env) {
SkyKey packageKey = PackageValue.key(toLabel.getPackageIdentifier());
try {
PackageValue pkgValue =
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalFunction.java
index 338d9c0..1852793 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalFunction.java
@@ -32,7 +32,6 @@
import java.util.Collection;
import java.util.Map.Entry;
-import java.util.Set;
import javax.annotation.Nullable;
@@ -96,8 +95,8 @@
}
// Retrieve the providers of the dep from the TransitiveTraversalValue, so we can avoid
// issuing a dep on its defining Package.
- Set<String> providers = traversalVal.getProviders();
- return AspectDefinition.visitAspectsIfRequired(fromRule, attr, providers,
+ return AspectDefinition.visitAspectsIfRequired(fromRule, attr,
+ traversalVal.canHaveAnyProvider(), traversalVal.getProviders(),
DependencyFilter.ALL_DEPS).values();
} catch (NoSuchThingException e) {
// Do nothing. This error was handled when we computed the corresponding
@@ -107,8 +106,8 @@
}
@Override
- SkyValue computeSkyValue(
- TargetAndErrorIfAny targetAndErrorIfAny, FirstErrorMessageAccumulator accumulator) {
+ SkyValue computeSkyValue(TargetAndErrorIfAny targetAndErrorIfAny,
+ FirstErrorMessageAccumulator accumulator) {
boolean targetLoadedSuccessfully = targetAndErrorIfAny.getErrorLoadingTarget() == null;
String firstErrorMessage = accumulator.getFirstErrorMessage();
return targetLoadedSuccessfully
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalValue.java
index 2070ff2..35fdc9a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalValue.java
@@ -39,19 +39,20 @@
@Immutable
@ThreadSafe
public class TransitiveTraversalValue implements SkyValue {
-
+ private final boolean canHaveAnyProvider;
@Nullable private final ImmutableSet<String> providers;
@Nullable private final String firstErrorMessage;
- private TransitiveTraversalValue(
+ private TransitiveTraversalValue(boolean canHaveAnyProvider,
@Nullable Iterable<String> providers, @Nullable String firstErrorMessage) {
+ this.canHaveAnyProvider = canHaveAnyProvider;
this.providers = (providers == null) ? null : canonicalSet(providers);
this.firstErrorMessage =
(firstErrorMessage == null) ? null : StringCanonicalizer.intern(firstErrorMessage);
}
public static TransitiveTraversalValue unsuccessfulTransitiveTraversal(String firstErrorMessage) {
- return new TransitiveTraversalValue(null, Preconditions.checkNotNull(firstErrorMessage));
+ return new TransitiveTraversalValue(false, null, Preconditions.checkNotNull(firstErrorMessage));
}
public static TransitiveTraversalValue forTarget(
@@ -59,14 +60,16 @@
if (target instanceof Rule) {
Rule rule = (Rule) target;
return new TransitiveTraversalValue(
- toStringSet(rule.getRuleClassObject().getAdvertisedProviders()), firstErrorMessage);
+ rule.getRuleClassObject().canHaveAnyProvider(),
+ toStringSet(rule.getRuleClassObject().getAdvertisedProviders()),
+ firstErrorMessage);
}
- return new TransitiveTraversalValue(ImmutableList.<String>of(), firstErrorMessage);
+ return new TransitiveTraversalValue(false, ImmutableList.<String>of(), firstErrorMessage);
}
public static TransitiveTraversalValue withProviders(
Collection<String> providers, @Nullable String firstErrorMessage) {
- return new TransitiveTraversalValue(ImmutableSet.copyOf(providers), firstErrorMessage);
+ return new TransitiveTraversalValue(false, ImmutableSet.copyOf(providers), firstErrorMessage);
}
private static ImmutableSet<String> canonicalSet(Iterable<String> strIterable) {
@@ -88,6 +91,13 @@
}
/**
+ * Returns if the associated target can have any provider. True for "alias" rules.
+ */
+ public boolean canHaveAnyProvider() {
+ return canHaveAnyProvider;
+ }
+
+ /**
* Returns the set of provider names from the target, if the target is a {@link Rule}. If there
* were errors loading the target, returns {@code null}.
*/
@@ -115,12 +125,13 @@
}
TransitiveTraversalValue that = (TransitiveTraversalValue) o;
return Objects.equals(this.firstErrorMessage, that.firstErrorMessage)
- && Objects.equals(this.providers, that.providers);
+ && Objects.equals(this.providers, that.providers)
+ && Objects.equals(this.canHaveAnyProvider, canHaveAnyProvider);
}
@Override
public int hashCode() {
- return 31 * Objects.hashCode(firstErrorMessage) + Objects.hashCode(providers);
+ return Objects.hash(firstErrorMessage, providers, canHaveAnyProvider);
}
@ThreadSafe
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index d531b65..3960aa7 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -997,6 +997,7 @@
"//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/rules/cpp",
"//src/main/java/com/google/devtools/build/skyframe",
+ "//src/test/java/com/google/devtools/build/lib:actions_testutil",
"//src/test/java/com/google/devtools/build/lib:packages_testutil",
"//third_party:guava",
"//third_party:jsr305",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
index ea9e4bb..253ac66 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
@@ -96,9 +96,7 @@
assertThat(a.getProvider(RuleInfo.class).getData()).containsExactly("rule //a:a");
}
- // Disabled because this is a bug. Also note that if we fix this, query also needs to be fixed
- // so that it reports implicit dependencies reached through these aspects.
- //@Test
+ @Test
public void aspectCreationWorksThroughBind() throws Exception {
setRules(new TestAspects.BaseRule(), new TestAspects.HonestRule(),
new TestAspects.AspectRequiringProviderRule());
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 36d539a..ef9b65d 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
@@ -95,7 +95,7 @@
return new RuleClass("ruleA", false, false, false, false, false, false,
ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE,
DUMMY_CONFIGURED_TARGET_FACTORY, PredicatesWithMessage.<Rule>alwaysTrue(),
- PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), null,
+ PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), false, null,
NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
MissingFragmentPolicy.FAIL_ANALYSIS, true,
attr("my-string-attr", STRING).mandatory().build(),
@@ -115,8 +115,9 @@
return new RuleClass("ruleB", false, false, false, false, false, false,
ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
- MissingFragmentPolicy.FAIL_ANALYSIS, true, attributes.toArray(new Attribute[0]));
+ ImmutableSet.<Class<?>>of(), false, null, NO_EXTERNAL_BINDINGS, null,
+ ImmutableSet.<Class<?>>of(), MissingFragmentPolicy.FAIL_ANALYSIS, true,
+ attributes.toArray(new Attribute[0]));
}
@Test
@@ -229,8 +230,8 @@
RuleClass depsRuleClass = new RuleClass("ruleDeps", false, false, false, false, false, false,
ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
- MissingFragmentPolicy.FAIL_ANALYSIS, true,
+ ImmutableSet.<Class<?>>of(), false, null, NO_EXTERNAL_BINDINGS, null,
+ ImmutableSet.<Class<?>>of(), MissingFragmentPolicy.FAIL_ANALYSIS, true,
attr("list1", LABEL_LIST).mandatory().legacyAllowAnyFileType().build(),
attr("list2", LABEL_LIST).mandatory().legacyAllowAnyFileType().build(),
attr("list3", LABEL_LIST).mandatory().legacyAllowAnyFileType().build());
@@ -260,8 +261,8 @@
RuleClass ruleClass = new RuleClass("ruleVis", false, false, false, false, false, false,
ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
- MissingFragmentPolicy.FAIL_ANALYSIS, true,
+ ImmutableSet.<Class<?>>of(), false, null, NO_EXTERNAL_BINDINGS, null,
+ ImmutableSet.<Class<?>>of(), MissingFragmentPolicy.FAIL_ANALYSIS, true,
attr("visibility", LABEL_LIST).legacyAllowAnyFileType().build());
Map<String, Object> attributeValues = new HashMap<>();
attributeValues.put("visibility", Arrays.asList("//visibility:legacy_public"));
@@ -346,8 +347,9 @@
"stuff-%{outs}-bar"),
RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
- MissingFragmentPolicy.FAIL_ANALYSIS, true, attr("outs", OUTPUT_LIST).build());
+ ImmutableSet.<Class<?>>of(), false, null, NO_EXTERNAL_BINDINGS, null,
+ ImmutableSet.<Class<?>>of(), MissingFragmentPolicy.FAIL_ANALYSIS, true,
+ attr("outs", OUTPUT_LIST).build());
Map<String, Object> attributeValues = new HashMap<>();
attributeValues.put("outs", Collections.singletonList("explicit_out"));
@@ -368,8 +370,9 @@
RuleClass ruleClass = new RuleClass("ruleClass", false, false, false, false, false, false,
ImplicitOutputsFunction.fromTemplates("%{dirname}lib%{basename}.bar"), RuleClass.NO_CHANGE,
DUMMY_CONFIGURED_TARGET_FACTORY, PredicatesWithMessage.<Rule>alwaysTrue(),
- PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS,
- null, ImmutableSet.<Class<?>>of(), MissingFragmentPolicy.FAIL_ANALYSIS, true);
+ PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), false, null,
+ NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
+ MissingFragmentPolicy.FAIL_ANALYSIS, true);
Rule rule = createRule(ruleClass, "myRule", Collections.<String, Object>emptyMap(),
testRuleLocation);
@@ -389,8 +392,9 @@
return new RuleClass("ruleClass", false, false, false, false, false, false,
ImplicitOutputsFunction.fromTemplates("empty"), RuleClass.NO_CHANGE,
DUMMY_CONFIGURED_TARGET_FACTORY, PredicatesWithMessage.<Rule>alwaysTrue(),
- PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS,
- null, ImmutableSet.<Class<?>>of(), MissingFragmentPolicy.FAIL_ANALYSIS, true,
+ PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), false, null,
+ NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
+ MissingFragmentPolicy.FAIL_ANALYSIS, true,
attr("condition", BOOLEAN).value(false).build(),
attr("declared1", BOOLEAN).value(false).build(),
attr("declared2", BOOLEAN).value(false).build(),
@@ -536,8 +540,9 @@
ImplicitOutputsFunction.fromTemplates("first-%{name}", "second-%{name}", "out-%{outs}"),
RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
- MissingFragmentPolicy.FAIL_ANALYSIS, true, attr("outs", OUTPUT_LIST).build());
+ ImmutableSet.<Class<?>>of(), false, null, NO_EXTERNAL_BINDINGS, null,
+ ImmutableSet.<Class<?>>of(), MissingFragmentPolicy.FAIL_ANALYSIS, true,
+ attr("outs", OUTPUT_LIST).build());
Map<String, Object> attributeValues = new HashMap<>();
attributeValues.put("outs", ImmutableList.of("third", "fourth"));
@@ -560,8 +565,8 @@
RuleClass ruleClass = new RuleClass("ruleA", false, false, false, false, false, false,
ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
- MissingFragmentPolicy.FAIL_ANALYSIS, true,
+ ImmutableSet.<Class<?>>of(), false, null, NO_EXTERNAL_BINDINGS, null,
+ ImmutableSet.<Class<?>>of(), MissingFragmentPolicy.FAIL_ANALYSIS, true,
attr("a", STRING_LIST).mandatory().build(),
attr("b", STRING_LIST).mandatory().build(),
attr("c", STRING_LIST).mandatory().build(),
@@ -696,7 +701,7 @@
RuleClass parentRuleClass = new RuleClass("parent_rule", false, false, false, false, false,
false, ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null,
+ ImmutableSet.<Class<?>>of(), false, null, NO_EXTERNAL_BINDINGS, null,
ImmutableSet.<Class<?>>of(DummyFragment.class), MissingFragmentPolicy.FAIL_ANALYSIS, true,
attr("attr", STRING).build());
return parentRuleClass;