Fix AspectKey for required aspects
This CL removes the inherited propagation information from the AspectKey of the required aspects. This information should not affect the execution of the aspect on a certain target but it only controls its propagation over the dependency graph. Therefore it should not be part of the AspectKey, instead this CL moves the control of the required aspects propagation to the DependencyResolver.
PiperOrigin-RevId: 395730300
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 cccbf0d..09226e4 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
@@ -58,7 +58,9 @@
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.skyframe.ToolchainContextKey;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -390,7 +392,7 @@
ImmutableList.Builder<Aspect> propagatingAspects = ImmutableList.builder();
propagatingAspects.addAll(attribute.getAspects(fromRule));
collectPropagatingAspects(
- aspects,
+ ImmutableList.copyOf(aspects),
attribute.getName(),
config,
entry.getKey().getOwningAspect(),
@@ -680,7 +682,6 @@
}
if (Void.class.equals(fragmentClass)) {
return lateBoundDefault.resolve(rule, attributeMap, null);
-
}
@SuppressWarnings("unchecked")
FragmentT fragment =
@@ -711,7 +712,7 @@
}
/**
- * Collects the aspects from {@code aspectPath} that need to be propagated along the attribute
+ * Collects the aspects from {@code aspectsPath} that need to be propagated along the attribute
* {@code attributeName}.
*
* <p>It can happen that some of the aspects cannot be propagated if the dependency doesn't have a
@@ -719,12 +720,16 @@
* dependency is known.
*/
private static void collectPropagatingAspects(
- Iterable<Aspect> aspectPath,
+ ImmutableList<Aspect> aspectsPath,
String attributeName,
BuildConfiguration config,
@Nullable AspectClass aspectOwningAttribute,
- ImmutableList.Builder<Aspect> filteredAspectPath) {
- for (Aspect aspect : aspectPath) {
+ ImmutableList.Builder<Aspect> allFilteredAspects) {
+ int aspectsNum = aspectsPath.size();
+ ArrayList<Aspect> filteredAspectsPath = new ArrayList<>();
+
+ for (int i = aspectsNum - 1; i >= 0; i--) {
+ Aspect aspect = aspectsPath.get(i);
if (!aspect.getDefinition().propagateViaAttribute().test(config, attributeName)) {
// This condition is only included to support the migration to platform-based Android
// toolchain selection. See DexArchiveAspect for details. One that migration is complete,
@@ -737,10 +742,25 @@
}
if (aspect.getDefinition().propagateAlong(attributeName)
- || aspect.getDescriptor().inheritedPropagateAlong(attributeName)) {
- filteredAspectPath.add(aspect);
+ || isAspectRequired(aspect, filteredAspectsPath)) {
+ // Add the aspect if it can propagate over this {@code attributeName} based on its
+ // attr_aspects or it is required by an aspect already in the {@code filteredAspectsPath}.
+ filteredAspectsPath.add(aspect);
}
}
+ // Reverse filteredAspectsPath to return it to the same order as the input aspectsPath.
+ Collections.reverse(filteredAspectsPath);
+ allFilteredAspects.addAll(filteredAspectsPath);
+ }
+
+ /** Checks if {@code aspect} is required by any aspect in the {@code aspectsPath}. */
+ private static boolean isAspectRequired(Aspect aspect, ArrayList<Aspect> aspectsPath) {
+ for (Aspect existingAspect : aspectsPath) {
+ if (existingAspect.getDefinition().requires(aspect)) {
+ return true;
+ }
+ }
+ return false;
}
/** Returns the attributes that should be visited for this rule/aspect combination. */
@@ -790,17 +810,24 @@
}
Rule toRule = (Rule) toTarget;
- ImmutableList.Builder<Aspect> filteredAspectPath = ImmutableList.builder();
+ ArrayList<Aspect> filteredAspectPath = new ArrayList<>();
AdvertisedProviderSet advertisedProviders =
toRule.getRuleClassObject().getAdvertisedProviders();
- for (Aspect aspect : aspects) {
+
+ int aspectsNum = aspects.size();
+ for (int i = aspectsNum - 1; i >= 0; i--) {
+ Aspect aspect = aspects.get(i);
if (aspect.getDefinition().getRequiredProviders().isSatisfiedBy(advertisedProviders)
- || aspect.getDescriptor().satisfiesInheritedRequiredProviders(advertisedProviders)) {
+ || isAspectRequired(aspect, filteredAspectPath)) {
+ // Add the aspect if {@code advertisedProviders} satisfy its required providers or it is
+ // required by an aspect already in the {@code filteredAspectPath}.
filteredAspectPath.add(aspect);
}
}
+
+ Collections.reverse(filteredAspectPath);
try {
- return AspectCollection.create(filteredAspectPath.build());
+ return AspectCollection.create(filteredAspectPath);
} catch (AspectCycleOnPathException e) {
throw new InconsistentAspectOrderException(toTarget, e);
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java
index 254bb74..bd37698 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java
@@ -265,10 +265,6 @@
/** baseAspectName= */
null,
builder.getAspectsListBuilder(),
- /** inheritedRequiredProviders= */
- ImmutableList.of(),
- /** inheritedAttributeAspects= */
- ImmutableList.of(),
/** allowAspectsParameters= */
true);
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Aspect.java b/src/main/java/com/google/devtools/build/lib/packages/Aspect.java
index bdd9ec6..2824b48 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Aspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Aspect.java
@@ -16,7 +16,6 @@
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
@@ -29,9 +28,9 @@
/**
* An instance of a given {@code AspectClass} with loaded definition and parameters.
*
- * This is an aspect equivalent of {@link Rule} class for build rules.
+ * <p>This is an aspect equivalent of {@link Rule} class for build rules.
*
- * Note: this class does not have {@code equals()} and {@code hashCode()} redefined, so should
+ * <p>Note: this class does not have {@code equals()} and {@code hashCode()} redefined, so should
* not be used in SkyKeys.
*/
@Immutable
@@ -57,46 +56,14 @@
private final AspectDefinition aspectDefinition;
private Aspect(
- AspectClass aspectClass,
- AspectDefinition aspectDefinition,
- AspectParameters parameters) {
- this.aspectDescriptor = new AspectDescriptor(
- Preconditions.checkNotNull(aspectClass),
- Preconditions.checkNotNull(parameters));
- this.aspectDefinition = Preconditions.checkNotNull(aspectDefinition);
- }
-
- private Aspect(
- AspectClass aspectClass,
- AspectDefinition aspectDefinition,
- AspectParameters parameters,
- RequiredProviders inheritedRequiredProviders,
- ImmutableSet<String> inheritedAttributeAspects) {
+ AspectClass aspectClass, AspectDefinition aspectDefinition, AspectParameters parameters) {
this.aspectDescriptor =
new AspectDescriptor(
- Preconditions.checkNotNull(aspectClass),
- Preconditions.checkNotNull(parameters),
- inheritedRequiredProviders,
- inheritedAttributeAspects);
+ Preconditions.checkNotNull(aspectClass), Preconditions.checkNotNull(parameters));
this.aspectDefinition = Preconditions.checkNotNull(aspectDefinition);
}
- public static Aspect forNative(
- NativeAspectClass nativeAspectClass,
- AspectParameters parameters,
- RequiredProviders inheritedRequiredProviders,
- ImmutableSet<String> inheritedAttributeAspects) {
- AspectDefinition definition = definitionCache.get(nativeAspectClass).get(parameters);
- return new Aspect(
- nativeAspectClass,
- definition,
- parameters,
- inheritedRequiredProviders,
- inheritedAttributeAspects);
- }
-
- public static Aspect forNative(
- NativeAspectClass nativeAspectClass, AspectParameters parameters) {
+ public static Aspect forNative(NativeAspectClass nativeAspectClass, AspectParameters parameters) {
AspectDefinition definition = definitionCache.get(nativeAspectClass).get(parameters);
return new Aspect(nativeAspectClass, definition, parameters);
}
@@ -108,27 +75,16 @@
public static Aspect forStarlark(
StarlarkAspectClass starlarkAspectClass,
AspectDefinition aspectDefinition,
- AspectParameters parameters,
- RequiredProviders inheritedRequiredProviders,
- ImmutableSet<String> inheritedAttributeAspects) {
- return new Aspect(
- starlarkAspectClass,
- aspectDefinition,
- parameters,
- inheritedRequiredProviders,
- inheritedAttributeAspects);
+ AspectParameters parameters) {
+ return new Aspect(starlarkAspectClass, aspectDefinition, parameters);
}
- /**
- * Returns the aspectClass required for building the aspect.
- */
+ /** Returns the aspectClass required for building the aspect. */
public AspectClass getAspectClass() {
return aspectDescriptor.getAspectClass();
}
- /**
- * Returns parameters for evaluation of the aspect.
- */
+ /** Returns parameters for evaluation of the aspect. */
public AspectParameters getParameters() {
return aspectDescriptor.getParameters();
}
@@ -184,9 +140,7 @@
return forStarlark(
(StarlarkAspectClass) aspectDescriptor.getAspectClass(),
aspectDefinition,
- aspectDescriptor.getParameters(),
- aspectDescriptor.getInheritedRequiredProviders(),
- aspectDescriptor.getInheritedAttributeAspects());
+ aspectDescriptor.getParameters());
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java b/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java
index bf90746..c833f14 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java
@@ -53,8 +53,7 @@
* {@link AspectClass}
* |
* V
- * {@code AspectDescriptor} <- {@link AspectParameters}, {@code inheritedRequiredProviders},
- * \ {@code inheritedAttributeAspects}
+ * {@code AspectDescriptor} <- {@link AspectParameters}
* \
* V
* {@link Aspect} <- {@link AspectDefinition} (might require loading Starlark files)
@@ -70,9 +69,8 @@
* label of .bzl file + symbol name.
* <li>{@link AspectParameters} is a (key,value) pair list that can be used to parameterize aspect
* classes
- * <li>{@link AspectDescriptor} is a wrapper for {@code AspectClass}, {@link AspectParameters},
- * {@code inheritedRequiredProviders} and {@code inheritedAttributeAspects}. It uniquely
- * identifies the aspect and can be used in SkyKeys.
+ * <li>{@link AspectDescriptor} is a pair of {@code AspectClass} and {@link AspectParameters}. It
+ * uniquely identifies the aspect and can be used in SkyKeys.
* <li>{@link AspectDefinition} is a class encapsulating the aspect definition (what attributes
* aspoect has, and along which dependencies does it propagate.
* <li>{@link Aspect} is a fully instantiated instance of an Aspect after it is loaded. Getting an
@@ -84,10 +82,9 @@
* </ul>
*
* {@link AspectDescriptor}, or in general, a tuple of ({@link AspectClass}, {@link
- * AspectParameters}), {@code inheritedRequiredProviders} and {@code inheritedAttributeAspects} is
- * an identifier that should be used in SkyKeys or in other contexts that need equality for aspects.
- * See also {@link com.google.devtools.build.lib.skyframe.AspectFunction} for details on Skyframe
- * treatment of Aspects.
+ * AspectParameters}) is an identifier that should be used in SkyKeys or in other contexts that need
+ * equality for aspects. See also {@link com.google.devtools.build.lib.skyframe.AspectFunction} for
+ * details on Skyframe treatment of Aspects.
*
* @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
* @see com.google.devtools.build.lib.skyframe.AspectFunction
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectDescriptor.java b/src/main/java/com/google/devtools/build/lib/packages/AspectDescriptor.java
index f14ce6f..947b8d5 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectDescriptor.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectDescriptor.java
@@ -15,16 +15,13 @@
package com.google.devtools.build.lib.packages;
import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.protobuf.TextFormat;
import java.util.Map;
import java.util.Objects;
-import javax.annotation.Nullable;
/**
- * A wrapper for {@link AspectClass}, {@link AspectParameters}, {@code inheritedRequiredProviders}
- * and {@code inheritedAttributeAspects}
+ * A pair of {@link AspectClass} and {@link AspectParameters}.
*
* <p>Used for dependency resolution.
*/
@@ -33,59 +30,13 @@
private final AspectClass aspectClass;
private final AspectParameters aspectParameters;
- /**
- * Inherited required providers to enable aspects required by other aspects to be propagated along
- * with their main aspect until they can be applied. Null if the aspect does not inherit required
- * providers.
- */
- @Nullable private final RequiredProviders inheritedRequiredProviders;
-
- /**
- * Inherited required providers to enable aspects required by other aspects to be propagated along
- * with their main aspect based on its propagation attributes.
- */
- @Nullable private final ImmutableSet<String> inheritedAttributeAspects;
-
- /**
- * False if the inherited propagation information have no effect, i.e. {@code
- * inheritedRequiredProviders} accepts None and {@code inheritedAttributeAspects} is empty,
- * whether these values are actually inherited or not.
- */
- private final boolean inheritsPropagationInfo;
-
- public AspectDescriptor(
- AspectClass aspectClass,
- AspectParameters aspectParameters,
- RequiredProviders inheritedRequiredProviders,
- ImmutableSet<String> inheritedAttributeAspects) {
+ public AspectDescriptor(AspectClass aspectClass, AspectParameters aspectParameters) {
this.aspectClass = aspectClass;
this.aspectParameters = aspectParameters;
- if (isEmptyInheritedRequiredProviders(inheritedRequiredProviders)
- && isEmptyInheritedAttributeAspects(inheritedAttributeAspects)) {
- this.inheritsPropagationInfo = false;
- this.inheritedRequiredProviders = null;
- this.inheritedAttributeAspects = null;
- } else {
- this.inheritsPropagationInfo = true;
- this.inheritedRequiredProviders = inheritedRequiredProviders;
- this.inheritedAttributeAspects = inheritedAttributeAspects;
- }
- }
-
- public AspectDescriptor(AspectClass aspectClass, AspectParameters aspectParameters) {
- this(
- aspectClass,
- aspectParameters,
- /*inheritedRequiredProviders=*/ null,
- /*inheritedAttributeAspects=*/ null);
}
public AspectDescriptor(AspectClass aspectClass) {
- this(
- aspectClass,
- AspectParameters.EMPTY,
- /*inheritedRequiredProviders=*/ null,
- /*inheritedAttributeAspects=*/ null);
+ this(aspectClass, AspectParameters.EMPTY);
}
public AspectClass getAspectClass() {
@@ -96,42 +47,9 @@
return aspectParameters;
}
- @Nullable
- public RequiredProviders getInheritedRequiredProviders() {
- return inheritedRequiredProviders;
- }
-
- @Nullable
- public ImmutableSet<String> getInheritedAttributeAspects() {
- if (!inheritsPropagationInfo) {
- return ImmutableSet.of(); // because returnning null means propagate through all attr aspects
- }
- return inheritedAttributeAspects;
- }
-
- public boolean satisfiesInheritedRequiredProviders(AdvertisedProviderSet advertisedProviders) {
- if (!inheritsPropagationInfo) {
- return false;
- }
-
- return inheritedRequiredProviders.isSatisfiedBy(advertisedProviders);
- }
-
- public boolean inheritedPropagateAlong(String attributeName) {
- if (!inheritsPropagationInfo) {
- return false;
- }
-
- if (inheritedAttributeAspects != null) {
- return inheritedAttributeAspects.contains(attributeName);
- }
- return true;
- }
-
@Override
public int hashCode() {
- return Objects.hash(
- aspectClass, aspectParameters, inheritedRequiredProviders, inheritedAttributeAspects);
+ return Objects.hash(aspectClass, aspectParameters);
}
@Override
@@ -146,9 +64,7 @@
AspectDescriptor that = (AspectDescriptor) obj;
return Objects.equals(aspectClass, that.aspectClass)
- && Objects.equals(aspectParameters, that.aspectParameters)
- && Objects.equals(inheritedRequiredProviders, that.inheritedRequiredProviders)
- && Objects.equals(inheritedAttributeAspects, that.inheritedAttributeAspects);
+ && Objects.equals(aspectParameters, that.aspectParameters);
}
@Override
@@ -156,17 +72,6 @@
return getDescription();
}
- private static boolean isEmptyInheritedRequiredProviders(
- RequiredProviders inheritedRequiredProviders) {
- return (inheritedRequiredProviders == null
- || inheritedRequiredProviders.equals(RequiredProviders.acceptNoneBuilder().build()));
- }
-
- private static boolean isEmptyInheritedAttributeAspects(
- ImmutableSet<String> inheritedAttributeAspects) {
- return (inheritedAttributeAspects == null || inheritedAttributeAspects.isEmpty());
- }
-
/**
* Creates a presentable description of this aspect, available to Starlark via "Target.aspects".
*
@@ -174,36 +79,26 @@
* parseable.
*/
public String getDescription() {
+ if (aspectParameters.isEmpty()) {
+ return aspectClass.getName();
+ }
+
StringBuilder builder = new StringBuilder(aspectClass.getName());
- if (!aspectParameters.isEmpty()) {
- builder.append('[');
- ImmutableMultimap<String, String> attributes = aspectParameters.getAttributes();
- boolean first = true;
- for (Map.Entry<String, String> attribute : attributes.entries()) {
- if (!first) {
- builder.append(',');
- } else {
- first = false;
- }
- builder.append(attribute.getKey());
- builder.append("=\"");
- builder.append(TextFormat.escapeDoubleQuotesAndBackslashes(attribute.getValue()));
- builder.append("\"");
- }
- builder.append(']');
- }
-
- if (inheritsPropagationInfo) {
- if (inheritedAttributeAspects == null) {
- builder.append("[*]");
+ builder.append('[');
+ ImmutableMultimap<String, String> attributes = aspectParameters.getAttributes();
+ boolean first = true;
+ for (Map.Entry<String, String> attribute : attributes.entries()) {
+ if (!first) {
+ builder.append(',');
} else {
- builder.append(inheritedAttributeAspects);
+ first = false;
}
-
- builder.append('[');
- builder.append(inheritedRequiredProviders);
- builder.append(']');
+ builder.append(attribute.getKey());
+ builder.append("=\"");
+ builder.append(TextFormat.escapeDoubleQuotesAndBackslashes(attribute.getValue()));
+ builder.append("\"");
}
+ builder.append(']');
return builder.toString();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectsListBuilder.java b/src/main/java/com/google/devtools/build/lib/packages/AspectsListBuilder.java
index c5133e0..cd9f5e4 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectsListBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectsListBuilder.java
@@ -28,8 +28,7 @@
/**
* AspectsList represents the list of aspects specified via --aspects command line option or
* declared in attribute aspects list. The class is responsible for wrapping the information
- * necessary for constructing those aspects including the inherited information for aspects required
- * by other aspects via `requires` attribute.
+ * necessary for constructing those aspects.
*/
public final class AspectsListBuilder {
@@ -65,49 +64,23 @@
/** Wraps the information necessary to construct an Aspect. */
@VisibleForSerialization
abstract static class AspectDetails<C extends AspectClass> {
- private static final ImmutableList<String> ALL_ATTR_ASPECTS = ImmutableList.of("*");
-
final C aspectClass;
final Function<Rule, AspectParameters> parametersExtractor;
-
- String baseAspectName;
- ImmutableList.Builder<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders;
- ImmutableList.Builder<String> inheritedAttributeAspects;
- boolean inheritedAllProviders = false;
- boolean inheritedAllAttributes = false;
+ final String baseAspectName;
private AspectDetails(C aspectClass, Function<Rule, AspectParameters> parametersExtractor) {
this.aspectClass = aspectClass;
this.parametersExtractor = parametersExtractor;
- this.inheritedRequiredProviders = ImmutableList.builder();
- this.inheritedAttributeAspects = ImmutableList.builder();
+ this.baseAspectName = null;
}
private AspectDetails(
C aspectClass,
Function<Rule, AspectParameters> parametersExtractor,
- String baseAspectName,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders,
- ImmutableList<String> inheritedAttributeAspects) {
+ String baseAspectName) {
this.aspectClass = aspectClass;
this.parametersExtractor = parametersExtractor;
this.baseAspectName = baseAspectName;
- this.inheritedRequiredProviders = null;
- this.inheritedAttributeAspects = null;
- if (baseAspectName != null) {
- if (inheritedRequiredProviders == null) {
- // Should only happen during deserialization
- inheritedAllProviders = true;
- } else {
- updateInheritedRequiredProviders(inheritedRequiredProviders);
- }
- if (inheritedAttributeAspects == null) {
- // Should only happen during deserialization
- inheritedAllAttributes = true;
- } else {
- updateInheritedAttributeAspects(inheritedAttributeAspects);
- }
- }
}
String getName() {
@@ -123,73 +96,6 @@
C getAspectClass() {
return aspectClass;
}
-
- void updateInheritedRequiredProviders(
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> requiredProviders) {
- if (!inheritedAllProviders && !requiredProviders.isEmpty()) {
- if (inheritedRequiredProviders == null) {
- inheritedRequiredProviders = ImmutableList.builder();
- }
- inheritedRequiredProviders.addAll(requiredProviders);
- } else {
- inheritedAllProviders = true;
- inheritedRequiredProviders = null;
- }
- }
-
- void updateInheritedAttributeAspects(ImmutableList<String> attributeAspects) {
- if (!inheritedAllAttributes && !ALL_ATTR_ASPECTS.equals(attributeAspects)) {
- if (inheritedAttributeAspects == null) {
- inheritedAttributeAspects = ImmutableList.builder();
- }
- inheritedAttributeAspects.addAll(attributeAspects);
- } else {
- inheritedAllAttributes = true;
- inheritedAttributeAspects = null;
- }
- }
-
- RequiredProviders buildInheritedRequiredProviders() {
- if (baseAspectName == null) {
- return RequiredProviders.acceptNoneBuilder().build();
- } else if (inheritedAllProviders) {
- return RequiredProviders.acceptAnyBuilder().build();
- } else {
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProvidersList =
- inheritedRequiredProviders.build();
- RequiredProviders.Builder inheritedRequiredProvidersBuilder =
- RequiredProviders.acceptAnyBuilder();
- for (ImmutableSet<StarlarkProviderIdentifier> providerSet :
- inheritedRequiredProvidersList) {
- if (!providerSet.isEmpty()) {
- inheritedRequiredProvidersBuilder.addStarlarkSet(providerSet);
- }
- }
- return inheritedRequiredProvidersBuilder.build();
- }
- }
-
- @Nullable
- ImmutableSet<String> buildInheritedAttributeAspects() {
- if (baseAspectName == null) {
- return ImmutableSet.of();
- } else if (inheritedAllAttributes) {
- return null;
- } else {
- return ImmutableSet.copyOf(inheritedAttributeAspects.build());
- }
- }
-
- @VisibleForSerialization
- public ImmutableList<ImmutableSet<StarlarkProviderIdentifier>>
- getInheritedRequiredProvidersList() {
- return inheritedRequiredProviders == null ? null : inheritedRequiredProviders.build();
- }
-
- @VisibleForSerialization
- public ImmutableList<String> getInheritedAttributeAspectsList() {
- return inheritedAttributeAspects == null ? null : inheritedAttributeAspects.build();
- }
}
private static class NativeAspectDetails extends AspectDetails<NativeAspectClass> {
@@ -201,15 +107,8 @@
NativeAspectDetails(
NativeAspectClass aspectClass,
Function<Rule, AspectParameters> parametersExtractor,
- String baseAspectName,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProvidersList,
- ImmutableList<String> inheritedAttributeAspectsList) {
- super(
- aspectClass,
- parametersExtractor,
- baseAspectName,
- inheritedRequiredProvidersList,
- inheritedAttributeAspectsList);
+ String baseAspectName) {
+ super(aspectClass, parametersExtractor, baseAspectName);
}
@Override
@@ -220,13 +119,7 @@
} else {
params = parametersExtractor.apply(rule);
}
- return params == null
- ? null
- : Aspect.forNative(
- aspectClass,
- params,
- buildInheritedRequiredProviders(),
- buildInheritedAttributeAspects());
+ return params == null ? null : Aspect.forNative(aspectClass, params);
}
}
@@ -236,17 +129,8 @@
private final StarlarkDefinedAspect aspect;
@VisibleForSerialization
- StarlarkAspectDetails(
- StarlarkDefinedAspect aspect,
- String baseAspectName,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProvidersList,
- ImmutableList<String> inheritedAttributeAspectsList) {
- super(
- aspect.getAspectClass(),
- aspect.getDefaultParametersExtractor(),
- baseAspectName,
- inheritedRequiredProvidersList,
- inheritedAttributeAspectsList);
+ StarlarkAspectDetails(StarlarkDefinedAspect aspect, String baseAspectName) {
+ super(aspect.getAspectClass(), aspect.getDefaultParametersExtractor(), baseAspectName);
this.aspect = aspect;
}
@@ -263,12 +147,7 @@
} else {
params = parametersExtractor.apply(rule);
}
- return Aspect.forStarlark(
- aspectClass,
- aspect.getDefinition(params),
- params,
- buildInheritedRequiredProviders(),
- buildInheritedAttributeAspects());
+ return Aspect.forStarlark(aspectClass, aspect.getDefinition(params), params);
}
}
@@ -317,72 +196,36 @@
/**
* Adds a starlark defined aspect to the aspects list with its base aspect (the aspect that
- * required it), its inherited required providers and its inherited propagation atttributes if
- * any.
+ * required it).
*
* @param starlarkAspect the starlark defined aspect to be added
* @param baseAspectName is the name of the base aspect requiring this aspect, can be {@code null}
* if the aspect is directly listed in the aspects list
- * @param inheritedRequiredProviders is the list of required providers inherited from the aspect
- * parent aspects
- * @param inheritedAttributeAspects is the list of attribute aspects inherited from the aspect
- * parent aspects
*/
- public void addAspect(
- StarlarkDefinedAspect starlarkAspect,
- @Nullable String baseAspectName,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders,
- ImmutableList<String> inheritedAttributeAspects)
+ public void addAspect(StarlarkDefinedAspect starlarkAspect, @Nullable String baseAspectName)
throws EvalException {
- boolean needsToAdd =
- checkAndUpdateExistingAspects(
- starlarkAspect.getName(),
- baseAspectName,
- inheritedRequiredProviders,
- inheritedAttributeAspects);
+ boolean needsToAdd = checkAndUpdateExistingAspects(starlarkAspect.getName(), baseAspectName);
if (needsToAdd) {
StarlarkAspectDetails starlarkAspectDetails =
- new StarlarkAspectDetails(
- starlarkAspect,
- baseAspectName,
- inheritedRequiredProviders,
- inheritedAttributeAspects);
+ new StarlarkAspectDetails(starlarkAspect, baseAspectName);
this.aspects.put(starlarkAspect.getName(), starlarkAspectDetails);
}
}
/**
- * Adds a native aspect to the aspects list with its base aspect (the aspect that required it),
- * its inherited required providers and its inherited propagation atttributes if any.
+ * Adds a native aspect to the aspects list with its base aspect (the aspect that required it).
*
* @param nativeAspect the native aspect to be added
* @param baseAspectName is the name of the base aspect requiring this aspect, can be {@code null}
* if the aspect is directly listed in the aspects list
- * @param inheritedRequiredProviders is the list of required providers inherited from the aspect
- * parent aspects
- * @param inheritedAttributeAspects is the list of attribute aspects inherited from the aspect
- * parent aspects
*/
- public void addAspect(
- StarlarkNativeAspect nativeAspect,
- @Nullable String baseAspectName,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders,
- ImmutableList<String> inheritedAttributeAspects)
+ public void addAspect(StarlarkNativeAspect nativeAspect, @Nullable String baseAspectName)
throws EvalException {
- boolean needsToAdd =
- checkAndUpdateExistingAspects(
- nativeAspect.getName(),
- baseAspectName,
- inheritedRequiredProviders,
- inheritedAttributeAspects);
+ boolean needsToAdd = checkAndUpdateExistingAspects(nativeAspect.getName(), baseAspectName);
if (needsToAdd) {
NativeAspectDetails nativeAspectDetails =
new NativeAspectDetails(
- nativeAspect,
- nativeAspect.getDefaultParametersExtractor(),
- baseAspectName,
- inheritedRequiredProviders,
- inheritedAttributeAspects);
+ nativeAspect, nativeAspect.getDefaultParametersExtractor(), baseAspectName);
this.aspects.put(nativeAspect.getName(), nativeAspectDetails);
}
}
@@ -398,27 +241,18 @@
}
}
- private boolean checkAndUpdateExistingAspects(
- String aspectName,
- String baseAspectName,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders,
- ImmutableList<String> inheritedAttributeAspects)
+ private boolean checkAndUpdateExistingAspects(String aspectName, @Nullable String baseAspectName)
throws EvalException {
AspectDetails<?> oldAspect = this.aspects.get(aspectName);
if (oldAspect != null) {
- // If the aspect to be added is required by another aspect, i.e. {@code baseAspectName} is
- // not null, then we need to update its inherited required providers and propgation
- // attributes.
if (baseAspectName != null) {
- oldAspect.baseAspectName = baseAspectName;
- oldAspect.updateInheritedRequiredProviders(inheritedRequiredProviders);
- oldAspect.updateInheritedAttributeAspects(inheritedAttributeAspects);
- return false; // no need to add the new aspect
+ // If the aspect to be added already exists and it is required by another aspect, no need to
+ // add it again.
+ return false;
} else {
- // If the aspect to be added is not required by another aspect, then we
- // should throw an error
+ // If the aspect to be added is not required by another aspect, then we should throw error
String oldAspectBaseAspectName = oldAspect.baseAspectName;
if (oldAspectBaseAspectName != null) {
throw Starlark.errorf(
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkAspect.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkAspect.java
index e866bc7..7ed3abb 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkAspect.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.packages;
import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.starlarkbuildapi.StarlarkAspectApi;
import net.starlark.java.eval.EvalException;
@@ -26,31 +25,16 @@
/**
* Attaches this aspect and its required aspects to the given aspects list.
*
- * <p>Also pass the list of required_providers of the base aspect to its required aspects to
- * ensure that they will be propgataed to the same targets. But whether the required aspects will
- * run on these targets or not depends on their required providers.
- *
- * <p>The list of attr_aspects of the base aspects is also passed to its required aspects to
- * ensure that they will be propagated with it along the same attributes.
- *
* @param baseAspectName is the name of the base aspect requiring this aspect, can be {@code null}
* if the aspect is directly listed in the aspects list
* @param aspectsListBuilder is the list to add this aspect to
- * @param inheritedRequiredProviders is the list of required providers inherited from the aspect
- * parent aspects
- * @param inheritedAttributeAspects is the list of attribute aspects inherited from the aspect
- * parent aspects
* @param allowAspectsParameters if false an error will be reported if any aspect in the chain of
* required aspects has parameters. This is needed for top-level aspects that do not allow
* parameters at the moment.
* @throws EvalException if this aspect cannot be successfully added to the aspects list.
*/
void attachToAspectsList(
- String baseAspectName,
- AspectsListBuilder aspectsListBuilder,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders,
- ImmutableList<String> inheritedAttributeAspects,
- boolean allowAspectsParameters)
+ String baseAspectName, AspectsListBuilder aspectsListBuilder, boolean allowAspectsParameters)
throws EvalException;
/** Returns the aspect class for this aspect. */
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java
index 7a9a7d7..3f08e37 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java
@@ -269,11 +269,7 @@
@Override
public void attachToAspectsList(
- String baseAspectName,
- AspectsListBuilder aspectsList,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders,
- ImmutableList<String> inheritedAttributeAspects,
- boolean allowAspectsParameters)
+ String baseAspectName, AspectsListBuilder aspectsList, boolean allowAspectsParameters)
throws EvalException {
if (!this.isExported()) {
@@ -285,40 +281,11 @@
throw Starlark.errorf("Cannot use parameterized aspect %s at the top level.", this.getName());
}
- if (!this.requiredAspects.isEmpty()) {
- ImmutableList.Builder<ImmutableSet<StarlarkProviderIdentifier>>
- requiredAspectInheritedRequiredProviders = ImmutableList.builder();
- ImmutableList.Builder<String> requiredAspectInheritedAttributeAspects =
- ImmutableList.builder();
- if (baseAspectName == null) {
- requiredAspectInheritedRequiredProviders.addAll(this.requiredProviders);
- requiredAspectInheritedAttributeAspects.addAll(this.attributeAspects);
- } else {
- if (!requiredProviders.isEmpty() && !inheritedRequiredProviders.isEmpty()) {
- requiredAspectInheritedRequiredProviders.addAll(inheritedRequiredProviders);
- requiredAspectInheritedRequiredProviders.addAll(requiredProviders);
- }
- if (!ALL_ATTR_ASPECTS.equals(inheritedAttributeAspects)
- && !ALL_ATTR_ASPECTS.equals(attributeAspects)) {
- requiredAspectInheritedAttributeAspects.addAll(inheritedAttributeAspects);
- requiredAspectInheritedAttributeAspects.addAll(attributeAspects);
- } else {
- requiredAspectInheritedAttributeAspects.add("*");
- }
- }
-
- for (StarlarkAspect requiredAspect : requiredAspects) {
- requiredAspect.attachToAspectsList(
- this.getName(),
- aspectsList,
- requiredAspectInheritedRequiredProviders.build(),
- requiredAspectInheritedAttributeAspects.build(),
- allowAspectsParameters);
- }
+ for (StarlarkAspect requiredAspect : requiredAspects) {
+ requiredAspect.attachToAspectsList(this.getName(), aspectsList, allowAspectsParameters);
}
- aspectsList.addAspect(
- this, baseAspectName, inheritedRequiredProviders, inheritedAttributeAspects);
+ aspectsList.addAspect(this, baseAspectName);
}
public ImmutableSet<StarlarkAspect> getRequiredAspects() {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkNativeAspect.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkNativeAspect.java
index 3a495e0..6bdfa4c 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkNativeAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkNativeAspect.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.packages;
import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import net.starlark.java.eval.EvalException;
@@ -34,19 +33,14 @@
@Override
public void attachToAspectsList(
- String baseAspectName,
- AspectsListBuilder aspectsList,
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders,
- ImmutableList<String> inheritedAttributeAspects,
- boolean allowAspectsParameters)
+ String baseAspectName, AspectsListBuilder aspectsList, boolean allowAspectsParameters)
throws EvalException {
if (!allowAspectsParameters && !this.getParamAttributes().isEmpty()) {
throw Starlark.errorf("Cannot use parameterized aspect %s at the top level.", this.getName());
}
- aspectsList.addAspect(
- this, baseAspectName, inheritedRequiredProviders, inheritedAttributeAspects);
+ aspectsList.addAspect(this, baseAspectName);
}
@Override
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 6cd2826..d55c642 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
@@ -212,12 +212,7 @@
if (key.getAspectClass() instanceof NativeAspectClass) {
NativeAspectClass nativeAspectClass = (NativeAspectClass) key.getAspectClass();
aspectFactory = (ConfiguredAspectFactory) nativeAspectClass;
- aspect =
- Aspect.forNative(
- nativeAspectClass,
- key.getParameters(),
- key.getInheritedRequiredProviders(),
- key.getInheritedAttributeAspects());
+ aspect = Aspect.forNative(nativeAspectClass, key.getParameters());
} else if (key.getAspectClass() instanceof StarlarkAspectClass) {
StarlarkAspectClass starlarkAspectClass = (StarlarkAspectClass) key.getAspectClass();
StarlarkDefinedAspect starlarkAspect;
@@ -235,9 +230,7 @@
Aspect.forStarlark(
starlarkAspect.getAspectClass(),
starlarkAspect.getDefinition(key.getParameters()),
- key.getParameters(),
- key.getInheritedRequiredProviders(),
- key.getInheritedAttributeAspects());
+ key.getParameters());
} else {
throw new IllegalStateException();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectValueKey.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectValueKey.java
index 8ad02a8..0cfa231 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectValueKey.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectValueKey.java
@@ -15,7 +15,6 @@
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Interner;
import com.google.devtools.build.lib.actions.ActionLookupKey;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -24,7 +23,6 @@
import com.google.devtools.build.lib.packages.AspectClass;
import com.google.devtools.build.lib.packages.AspectDescriptor;
import com.google.devtools.build.lib.packages.AspectParameters;
-import com.google.devtools.build.lib.packages.RequiredProviders;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.skyframe.SkyFunctionName;
import javax.annotation.Nullable;
@@ -173,15 +171,6 @@
return aspectDescriptor.getParameters();
}
- public RequiredProviders getInheritedRequiredProviders() {
- return aspectDescriptor.getInheritedRequiredProviders();
- }
-
- @Nullable
- public ImmutableSet<String> getInheritedAttributeAspects() {
- return aspectDescriptor.getInheritedAttributeAspects();
- }
-
public AspectDescriptor getAspectDescriptor() {
return aspectDescriptor;
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BuildTopLevelAspectsDetailsFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BuildTopLevelAspectsDetailsFunction.java
index 48d99ad..c10a8fd 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BuildTopLevelAspectsDetailsFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BuildTopLevelAspectsDetailsFunction.java
@@ -208,10 +208,6 @@
/** baseAspectName= */
null,
aspectsList,
- /** inheritedRequiredProviders= */
- ImmutableList.of(),
- /** inheritedAttributeAspects= */
- ImmutableList.of(),
/** allowAspectsParameters= */
false);
} catch (EvalException | AspectCreationException e) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
index bd01c82..413987e 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
@@ -496,6 +496,7 @@
public AspectDefinition getDefinition(AspectParameters aspectParameters) {
AspectDefinition.Builder builder =
new AspectDefinition.Builder(STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
+ builder.requireProviders(RequiredProvider.class);
return builder.build();
}
@@ -506,7 +507,9 @@
AspectParameters parameters,
String toolsRepository)
throws ActionConflictException, InterruptedException {
- return new ConfiguredAspect.Builder(ruleContext).addProvider(new FooProvider()).build();
+ return new ConfiguredAspect.Builder(ruleContext)
+ .addStarlarkTransitiveInfo("native_aspect_prov", "native_aspect_val")
+ .build();
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/AttributeTest.java b/src/test/java/com/google/devtools/build/lib/packages/AttributeTest.java
index 6bce873..f244286 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/AttributeTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/AttributeTest.java
@@ -23,9 +23,7 @@
import static org.junit.Assert.assertThrows;
import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.BuildOptionsView;
import com.google.devtools.build.lib.analysis.config.HostTransition;
@@ -326,236 +324,4 @@
.build());
assertThat(e).hasMessageThat().contains("may not contain the same rule classes");
}
-
- private static final Label FAKE_LABEL = Label.parseAbsoluteUnchecked("//fake/label.bzl");
-
- private static final StarlarkProviderIdentifier STARLARK_P1 =
- StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, "STARLARK_P1"));
-
- private static final StarlarkProviderIdentifier STARLARK_P2 =
- StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, "STARLARK_P2"));
-
- private static final StarlarkProviderIdentifier STARLARK_P3 =
- StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, "STARLARK_P3"));
-
- private static final StarlarkProviderIdentifier STARLARK_P4 =
- StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, "STARLARK_P4"));
-
- @Test
- public void testAttrRequiredAspects_inheritAttrAspects() throws Exception {
- ImmutableList<String> inheritedAttributeAspects1 = ImmutableList.of("attr1", "attr2");
- ImmutableList<String> inheritedAttributeAspects2 = ImmutableList.of("attr3", "attr2");
-
- Attribute.Builder<Label> attrBuilder = attr("x", LABEL).allowedFileTypes();
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect_1",
- /** inheritedRequiredProviders= */
- ImmutableList.of(),
- inheritedAttributeAspects1);
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect_2",
- /** inheritedRequiredProviders= */
- ImmutableList.of(),
- inheritedAttributeAspects2);
- Attribute attr = attrBuilder.build();
-
- ImmutableList<Aspect> aspects = attr.getAspects(null);
- assertThat(aspects).hasSize(1);
- AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor();
- assertThat(aspectDescriptor.getInheritedAttributeAspects())
- .containsExactly("attr1", "attr2", "attr3");
- }
-
- @Test
- public void testAttrRequiredAspects_inheritRequiredProviders() throws Exception {
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders1 =
- ImmutableList.of(ImmutableSet.of(STARLARK_P1), ImmutableSet.of(STARLARK_P2, STARLARK_P3));
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders2 =
- ImmutableList.of(ImmutableSet.of(STARLARK_P4), ImmutableSet.of(STARLARK_P2, STARLARK_P3));
-
- Attribute.Builder<Label> attrBuilder = attr("x", LABEL).allowedFileTypes();
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect_1",
- inheritedRequiredProviders1,
- /** inheritedAttributeAspects= */
- ImmutableList.of());
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect_2",
- inheritedRequiredProviders2,
- /** inheritedAttributeAspects= */
- ImmutableList.of());
- Attribute attr = attrBuilder.build();
-
- ImmutableList<Aspect> aspects = attr.getAspects(null);
- assertThat(aspects).hasSize(1);
-
- RequiredProviders actualInheritedRequiredProviders =
- aspects.get(0).getDescriptor().getInheritedRequiredProviders();
- AdvertisedProviderSet expectedOkSet1 =
- AdvertisedProviderSet.builder().addStarlark(STARLARK_P1).build();
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet1)).isTrue();
-
- AdvertisedProviderSet expectedOkSet2 =
- AdvertisedProviderSet.builder().addStarlark(STARLARK_P4).build();
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet2)).isTrue();
-
- AdvertisedProviderSet expectedOkSet3 =
- AdvertisedProviderSet.builder().addStarlark(STARLARK_P2).addStarlark(STARLARK_P3).build();
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet3)).isTrue();
-
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY))
- .isFalse();
- }
-
- @Test
- public void testAttrRequiredAspects_aspectAlreadyExists_inheritAttrAspects() throws Exception {
- ImmutableList<String> inheritedAttributeAspects = ImmutableList.of("attr1", "attr2");
-
- Attribute.Builder<Label> attrBuilder =
- attr("x", LABEL).aspect(TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT).allowedFileTypes();
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect",
- /** inheritedRequiredProviders = */
- ImmutableList.of(),
- inheritedAttributeAspects);
- Attribute attr = attrBuilder.build();
-
- ImmutableList<Aspect> aspects = attr.getAspects(null);
- assertThat(aspects).hasSize(1);
- AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor();
- assertThat(aspectDescriptor.getInheritedAttributeAspects()).containsExactly("attr1", "attr2");
- }
-
- @Test
- public void testAttrRequiredAspects_aspectAlreadyExists_inheritRequiredProviders()
- throws Exception {
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders =
- ImmutableList.of(ImmutableSet.of(STARLARK_P1), ImmutableSet.of(STARLARK_P2, STARLARK_P3));
-
- Attribute.Builder<Label> attrBuilder =
- attr("x", LABEL).aspect(TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT).allowedFileTypes();
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect",
- inheritedRequiredProviders,
- /** inheritedAttributeAspects= */
- ImmutableList.of());
- Attribute attr = attrBuilder.build();
-
- ImmutableList<Aspect> aspects = attr.getAspects(null);
- assertThat(aspects).hasSize(1);
-
- RequiredProviders actualInheritedRequiredProviders =
- aspects.get(0).getDescriptor().getInheritedRequiredProviders();
- AdvertisedProviderSet expectedOkSet1 =
- AdvertisedProviderSet.builder().addStarlark(STARLARK_P1).build();
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet1)).isTrue();
-
- AdvertisedProviderSet expectedOkSet2 =
- AdvertisedProviderSet.builder().addStarlark(STARLARK_P4).build();
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet2)).isFalse();
-
- AdvertisedProviderSet expectedOkSet3 =
- AdvertisedProviderSet.builder().addStarlark(STARLARK_P2).addStarlark(STARLARK_P3).build();
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet3)).isTrue();
-
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
- assertThat(actualInheritedRequiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY))
- .isFalse();
- }
-
- @Test
- public void testAttrRequiredAspects_inheritAllAttrAspects() throws Exception {
- ImmutableList<String> inheritedAttributeAspects1 = ImmutableList.of("attr1", "attr2");
- ImmutableList<String> inheritedAttributeAspects2 = ImmutableList.of("*");
-
- Attribute.Builder<Label> attrBuilder =
- attr("x", LABEL).aspect(TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT).allowedFileTypes();
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect_1",
- /** inheritedRequiredProviders = */
- ImmutableList.of(),
- inheritedAttributeAspects1);
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect_2",
- /** inheritedRequiredProviders = */
- ImmutableList.of(),
- inheritedAttributeAspects2);
- Attribute attr = attrBuilder.build();
-
- ImmutableList<Aspect> aspects = attr.getAspects(null);
- assertThat(aspects).hasSize(1);
- AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor();
- assertThat(aspectDescriptor.getInheritedAttributeAspects()).isNull();
- }
-
- @Test
- public void testAttrRequiredAspects_inheritAllRequiredProviders() throws Exception {
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders1 =
- ImmutableList.of();
- ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders2 =
- ImmutableList.of(ImmutableSet.of(STARLARK_P4), ImmutableSet.of(STARLARK_P2, STARLARK_P3));
-
- Attribute.Builder<Label> attrBuilder =
- attr("x", LABEL).aspect(TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT).allowedFileTypes();
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect_1",
- inheritedRequiredProviders1,
- /** inheritedAttributeAspects= */
- ImmutableList.of());
- attrBuilder
- .getAspectsListBuilder()
- .addAspect(
- TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT,
- "base_aspect_2",
- inheritedRequiredProviders2,
- /** inheritedAttributeAspects= */
- ImmutableList.of());
- Attribute attr = attrBuilder.build();
-
- ImmutableList<Aspect> aspects = attr.getAspects(null);
- assertThat(aspects).hasSize(1);
- AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor();
- assertThat(aspectDescriptor.getInheritedRequiredProviders())
- .isEqualTo(RequiredProviders.acceptAnyBuilder().build());
- }
-
- @Test
- public void testAttrRequiredAspects_defaultInheritedRequiredProvidersAndAttrAspects()
- throws Exception {
- Attribute attr = attr("x", LABEL).aspect(TestAspects.SIMPLE_ASPECT).allowedFileTypes().build();
-
- ImmutableList<Aspect> aspects = attr.getAspects(null);
- assertThat(aspects).hasSize(1);
- AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor();
- assertThat(aspectDescriptor.getInheritedAttributeAspects()).isEmpty();
- assertThat(aspectDescriptor.getInheritedRequiredProviders()).isNull();
- }
}
diff --git a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkDefinedAspectsTest.java b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkDefinedAspectsTest.java
index 8c17986..00675d5 100644
--- a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkDefinedAspectsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkDefinedAspectsTest.java
@@ -41,8 +41,8 @@
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.packages.AspectClass;
import com.google.devtools.build.lib.packages.AspectDefinition;
-import com.google.devtools.build.lib.packages.RequiredProviders;
import com.google.devtools.build.lib.packages.StarlarkAspectClass;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
@@ -56,6 +56,7 @@
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.starlark.java.eval.Sequence;
@@ -2305,82 +2306,6 @@
+ "(when propagating to //test:r1)");
}
- @Test
- public void aspectRequiresAspectInconsistentVisibility() throws Exception {
- scratch.file(
- "test/aspect.bzl",
- "def _aspect_impl(target,ctx):",
- " return struct()",
- "a1 = aspect(_aspect_impl, attr_aspects = ['dep'])",
- "a2 = aspect(_aspect_impl, attr_aspects = ['dep'], requires = [a1])",
- "def _rule_impl(ctx):",
- " pass",
- "r1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1])})",
- "r2 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a2])})");
- scratch.file(
- "test/BUILD",
- "load(':aspect.bzl', 'r1', 'r2')",
- "r1(name = 'r0')",
- "r1(name = 'r1', dep = ':r0')",
- "r2(name = 'r2', dep = ':r1')",
- "r1(name = 'r1_1', dep = ':r2')",
- "r2(name = 'r2_1', dep = ':r1_1')");
- reporter.removeHandler(failFastHandler);
- useConfiguration("--experimental_required_aspects");
-
- // The call to `update` does not throw an exception when "--keep_going" is passed in the
- // WithKeepGoing test suite. Otherwise, it throws ViewCreationFailedException.
- if (keepGoing()) {
- AnalysisResult result = update("//test:r2_1");
- assertThat(result.hasError()).isTrue();
- } else {
- assertThrows(ViewCreationFailedException.class, () -> update("//test:r2_1"));
- }
- assertContainsEvent(
- "ERROR /workspace/test/BUILD:3:3: Aspect //test:aspect.bzl%a2 is"
- + " applied twice, both before and after aspect //test:aspect.bzl%a1 "
- + "(when propagating to //test:r1)");
- }
-
- @Test
- public void aspectRequiresAspectInconsistentVisibilityIndirect() throws Exception {
- scratch.file(
- "test/aspect.bzl",
- "def _aspect_impl(target,ctx):",
- " return struct()",
- "a1 = aspect(_aspect_impl, attr_aspects = ['dep'])",
- "a2 = aspect(_aspect_impl, attr_aspects = ['dep'], requires = [a1])",
- "def _rule_impl(ctx):",
- " pass",
- "r1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1])})",
- "r2 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a2])})",
- "r0 = rule(_rule_impl, attrs = { 'dep' : attr.label()})");
- scratch.file(
- "test/BUILD",
- "load(':aspect.bzl', 'r0', 'r1', 'r2')",
- "r0(name = 'r0')",
- "r1(name = 'r1', dep = ':r0')",
- "r2(name = 'r2', dep = ':r1')",
- "r1(name = 'r1_1', dep = ':r2')",
- "r2(name = 'r2_1', dep = ':r1_1')",
- "r0(name = 'r0_1', dep = ':r2_1')");
- reporter.removeHandler(failFastHandler);
- useConfiguration("--experimental_required_aspects");
-
- // The call to `update` does not throw an exception when "--keep_going" is passed in the
- // WithKeepGoing test suite. Otherwise, it throws ViewCreationFailedException.
- if (keepGoing()) {
- AnalysisResult result = update("//test:r0_1");
- assertThat(result.hasError()).isTrue();
- } else {
- assertThrows(ViewCreationFailedException.class, () -> update("//test:r0_1"));
- }
- assertContainsEvent(
- "ERROR /workspace/test/BUILD:3:3: Aspect //test:aspect.bzl%a2 is"
- + " applied twice, both before and after aspect //test:aspect.bzl%a1 "
- + "(when propagating to //test:r1)");
- }
-
/**
* Aspect a3 sees aspect a2, aspect a2 sees aspect a1, but a3 does not see a1. All three aspects
* should still propagate together.
@@ -3504,7 +3429,461 @@
}
@Test
+ public void testAspectRequiredByMultipleAspects_inheritsAttrAspects() throws Exception {
+ useConfiguration(
+ "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
+ scratch.file(
+ "test/defs.bzl",
+ "prov_a = provider()",
+ "prov_b = provider()",
+ "prov_c = provider()",
+ "",
+ "def _aspect_c_impl(target, ctx):",
+ " res = ['aspect_c runs on target {}'.format(target.label)]",
+ " return [prov_c(val = res)]",
+ "aspect_c = aspect(",
+ " implementation = _aspect_c_impl,",
+ ")",
+ "",
+ "def _aspect_b_impl(target, ctx):",
+ " res = []",
+ " res += target[prov_c].val",
+ " res += ['aspect_b runs on target {}'.format(target.label)]",
+ " if ctx.rule.attr.dep_b:",
+ " res += ctx.rule.attr.dep_b[prov_b].val",
+ " return [prov_b(val = res)]",
+ "aspect_b = aspect(",
+ " implementation = _aspect_b_impl,",
+ " attr_aspects = ['dep_b'],",
+ " requires = [aspect_c],",
+ ")",
+ "",
+ "def _aspect_a_impl(target, ctx):",
+ " res = []",
+ " res += target[prov_c].val",
+ " res += ['aspect_a runs on target {}'.format(target.label)]",
+ " if ctx.rule.attr.dep_a:",
+ " res += ctx.rule.attr.dep_a[prov_a].val",
+ " return [prov_a(val = res)]",
+ "aspect_a = aspect(",
+ " implementation = _aspect_a_impl,",
+ " attr_aspects = ['dep_a'],",
+ " requires = [aspect_c],",
+ ")",
+ "",
+ "def _my_rule_impl(ctx):",
+ " pass",
+ "",
+ "my_rule = rule(",
+ " implementation = _my_rule_impl,",
+ " attrs = {",
+ " 'dep_a': attr.label(),",
+ " 'dep_b': attr.label(),",
+ " },",
+ ")");
+ scratch.file(
+ "test/BUILD",
+ "load('//test:defs.bzl', 'my_rule')",
+ "my_rule(",
+ " name = 'main_target',",
+ " dep_a = ':dep_target_a',",
+ " dep_b = ':dep_target_b',",
+ ")",
+ "my_rule(",
+ " name = 'dep_target_a',",
+ ")",
+ "my_rule(",
+ " name = 'dep_target_b',",
+ ")");
+
+ AnalysisResult analysisResult =
+ update(
+ ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
+ "//test:main_target");
+
+ Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
+ // aspect_a should run on main_target and dep_target_a and can retrieve aspect_c provider value
+ // on both of them
+ ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
+ assertThat(aspectA).isNotNull();
+ StarlarkProvider.Key aResult =
+ new StarlarkProvider.Key(
+ Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "prov_a");
+ StructImpl aResultProvider = (StructImpl) aspectA.get(aResult);
+ assertThat((Sequence<?>) aResultProvider.getValue("val"))
+ .containsExactly(
+ "aspect_c runs on target //test:dep_target_a",
+ "aspect_a runs on target //test:dep_target_a",
+ "aspect_c runs on target //test:main_target",
+ "aspect_a runs on target //test:main_target");
+
+ // aspect_b should run on main_target and dep_target_b and can retrieve aspect_c provider value
+ // on both of them
+ ConfiguredAspect aspectB = getConfiguredAspect(configuredAspects, "aspect_b");
+ assertThat(aspectA).isNotNull();
+ StarlarkProvider.Key bResult =
+ new StarlarkProvider.Key(
+ Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "prov_b");
+ StructImpl bResultProvider = (StructImpl) aspectB.get(bResult);
+ assertThat((Sequence<?>) bResultProvider.getValue("val"))
+ .containsExactly(
+ "aspect_c runs on target //test:dep_target_b",
+ "aspect_b runs on target //test:dep_target_b",
+ "aspect_c runs on target //test:main_target",
+ "aspect_b runs on target //test:main_target");
+ }
+
+ @Test
+ public void testAspectRequiredByMultipleAspects_inheritsRequiredProviders() throws Exception {
+ useConfiguration(
+ "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
+ scratch.file(
+ "test/defs.bzl",
+ "aspect_prov_a = provider()",
+ "aspect_prov_b = provider()",
+ "aspect_prov_c = provider()",
+ "rule_prov_a = provider()",
+ "rule_prov_b = provider()",
+ "rule_prov_c = provider()",
+ "",
+ "def _aspect_c_impl(target, ctx):",
+ " res = ['aspect_c runs on target {}'.format(target.label)]",
+ " return [aspect_prov_c(val = res)]",
+ "aspect_c = aspect(",
+ " implementation = _aspect_c_impl,",
+ " required_providers = [rule_prov_c],",
+ ")",
+ "",
+ "def _aspect_b_impl(target, ctx):",
+ " res = []",
+ " if aspect_prov_c in target:",
+ " res += target[aspect_prov_c].val",
+ " res += ['aspect_b runs on target {}'.format(target.label)]",
+ " if ctx.rule.attr.deps:",
+ " for dep in ctx.rule.attr.deps:",
+ " if aspect_prov_b in dep:",
+ " res += dep[aspect_prov_b].val",
+ " return [aspect_prov_b(val = res)]",
+ "aspect_b = aspect(",
+ " implementation = _aspect_b_impl,",
+ " attr_aspects = ['deps'],",
+ " required_providers = [[rule_prov_b], [rule_prov_c]],",
+ " requires = [aspect_c],",
+ ")",
+ "",
+ "def _aspect_a_impl(target, ctx):",
+ " res = []",
+ " if aspect_prov_c in target:",
+ " res += target[aspect_prov_c].val",
+ " res += ['aspect_a runs on target {}'.format(target.label)]",
+ " if ctx.rule.attr.deps:",
+ " for dep in ctx.rule.attr.deps:",
+ " if aspect_prov_a in dep:",
+ " res += dep[aspect_prov_a].val",
+ " return [aspect_prov_a(val = res)]",
+ "aspect_a = aspect(",
+ " implementation = _aspect_a_impl,",
+ " attr_aspects = ['deps'],",
+ " required_providers = [[rule_prov_a], [rule_prov_c]],",
+ " requires = [aspect_c],",
+ ")",
+ "",
+ "def _my_rule_impl(ctx):",
+ " return [rule_prov_a(), rule_prov_b()]",
+ "",
+ "my_rule = rule(",
+ " implementation = _my_rule_impl,",
+ " attrs = {",
+ " 'deps': attr.label_list(),",
+ " },",
+ " provides = [rule_prov_a, rule_prov_b]",
+ ")",
+ "",
+ "def _rule_with_prov_a_impl(ctx):",
+ " return [rule_prov_a()]",
+ "",
+ "rule_with_prov_a = rule(",
+ " implementation = _rule_with_prov_a_impl,",
+ " attrs = {",
+ " 'deps': attr.label_list(),",
+ " },",
+ " provides = [rule_prov_a]",
+ ")",
+ "",
+ "def _rule_with_prov_b_impl(ctx):",
+ " return [rule_prov_b()]",
+ "",
+ "rule_with_prov_b = rule(",
+ " implementation = _rule_with_prov_b_impl,",
+ " attrs = {",
+ " 'deps': attr.label_list(),",
+ " },",
+ " provides = [rule_prov_b]",
+ ")",
+ "",
+ "def _rule_with_prov_c_impl(ctx):",
+ " return [rule_prov_c()]",
+ "rule_with_prov_c = rule(",
+ " implementation = _rule_with_prov_c_impl,",
+ " attrs = {",
+ " 'deps': attr.label_list(),",
+ " },",
+ " provides = [rule_prov_c]",
+ ")");
+ scratch.file(
+ "test/BUILD",
+ "load('//test:defs.bzl', 'my_rule', 'rule_with_prov_a',",
+ " 'rule_with_prov_b', 'rule_with_prov_c')",
+ "my_rule(",
+ " name = 'main_target',",
+ " deps = [':dep_target_with_prov_a', ':dep_target_with_prov_b']",
+ ")",
+ "rule_with_prov_a(",
+ " name = 'dep_target_with_prov_a',",
+ " deps = [':dep_target_with_prov_c'],",
+ ")",
+ "rule_with_prov_b(",
+ " name = 'dep_target_with_prov_b',",
+ " deps = [':dep_target_with_prov_c'],",
+ ")",
+ "rule_with_prov_c(",
+ " name = 'dep_target_with_prov_c',",
+ ")");
+
+ AnalysisResult analysisResult =
+ update(
+ ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
+ "//test:main_target");
+
+ Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
+ // aspect_a runs on main_target, dep_target_with_prov_a and dep_target_with_prov_c and it can
+ // only retrieve aspect_c provider value on dep_target_with_prov_c
+ ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
+ assertThat(aspectA).isNotNull();
+ StarlarkProvider.Key aResult =
+ new StarlarkProvider.Key(
+ Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "aspect_prov_a");
+ StructImpl aResultProvider = (StructImpl) aspectA.get(aResult);
+ assertThat((Sequence<?>) aResultProvider.getValue("val"))
+ .containsExactly(
+ "aspect_c runs on target //test:dep_target_with_prov_c",
+ "aspect_a runs on target //test:dep_target_with_prov_c",
+ "aspect_a runs on target //test:dep_target_with_prov_a",
+ "aspect_a runs on target //test:main_target");
+
+ // aspect_b runs on main_target, dep_target_with_prov_b and dep_target_with_prov_c and it can
+ // only retrieve aspect_c provider value on dep_target_with_prov_c
+ ConfiguredAspect aspectB = getConfiguredAspect(configuredAspects, "aspect_b");
+ assertThat(aspectA).isNotNull();
+ StarlarkProvider.Key bResult =
+ new StarlarkProvider.Key(
+ Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "aspect_prov_b");
+ StructImpl bResultProvider = (StructImpl) aspectB.get(bResult);
+ assertThat((Sequence<?>) bResultProvider.getValue("val"))
+ .containsExactly(
+ "aspect_c runs on target //test:dep_target_with_prov_c",
+ "aspect_b runs on target //test:dep_target_with_prov_c",
+ "aspect_b runs on target //test:dep_target_with_prov_b",
+ "aspect_b runs on target //test:main_target");
+ }
+
+ @Test
+ public void testAspectRequiredByMultipleAspects_withDifferentParametersValues() throws Exception {
+ useConfiguration(
+ "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
+ scratch.file(
+ "test/defs.bzl",
+ "prov_a = provider()",
+ "prov_b = provider()",
+ "prov_c = provider()",
+ "",
+ "def _aspect_c_impl(target, ctx):",
+ " res = ['aspect_c runs on target {} and param = {}'.format(target.label, ctx.attr.p)]",
+ " return [prov_c(val = res)]",
+ "aspect_c = aspect(",
+ " implementation = _aspect_c_impl,",
+ " attrs = {",
+ " 'p': attr.string(values=['rule_1_val', 'rule_2_val']),",
+ " },",
+ ")",
+ "",
+ "def _aspect_b_impl(target, ctx):",
+ " res = []",
+ " res += target[prov_c].val",
+ " res += ['aspect_b runs on target {}'.format(target.label)]",
+ " if ctx.rule.attr.dep:",
+ " res += ctx.rule.attr.dep[prov_b].val",
+ " return [prov_b(val = res)]",
+ "aspect_b = aspect(",
+ " implementation = _aspect_b_impl,",
+ " attr_aspects = ['dep'],",
+ " requires = [aspect_c],",
+ ")",
+ "",
+ "def _aspect_a_impl(target, ctx):",
+ " res = []",
+ " res += target[prov_c].val",
+ " res += ['aspect_a runs on target {}'.format(target.label)]",
+ " if ctx.rule.attr.dep:",
+ " res += ctx.rule.attr.dep[prov_a].val",
+ " return [prov_a(val = res)]",
+ "aspect_a = aspect(",
+ " implementation = _aspect_a_impl,",
+ " attr_aspects = ['dep'],",
+ " requires = [aspect_c],",
+ ")",
+ "",
+ "def _rule_1_impl(ctx):",
+ " return ctx.attr.dep[prov_a]",
+ "",
+ "rule_1 = rule(",
+ " implementation = _rule_1_impl,",
+ " attrs = {",
+ " 'dep': attr.label(aspects = [aspect_a]),",
+ " 'p': attr.string(values = ['rule_1_val', 'rule_2_val'])",
+ " },",
+ ")",
+ "",
+ "def _rule_2_impl(ctx):",
+ " return ctx.attr.dep[prov_b]",
+ "",
+ "rule_2 = rule(",
+ " implementation = _rule_2_impl,",
+ " attrs = {",
+ " 'dep': attr.label(aspects = [aspect_b]),",
+ " 'p': attr.string(values = ['rule_1_val', 'rule_2_val'])",
+ " },",
+ ")",
+ "",
+ "def _rule_3_impl(ctx):",
+ " pass",
+ "",
+ "rule_3 = rule(",
+ " implementation = _rule_3_impl,",
+ " attrs = {",
+ " 'dep': attr.label(),",
+ " },",
+ ")");
+ scratch.file(
+ "test/BUILD",
+ "load('//test:defs.bzl', 'rule_1', 'rule_2', 'rule_3')",
+ "rule_1(",
+ " name = 'target_1',",
+ " dep = ':dep_1',",
+ " p = 'rule_1_val'",
+ ")",
+ "rule_2(",
+ " name = 'target_2',",
+ " dep = ':dep_2',",
+ " p = 'rule_2_val'",
+ ")",
+ "rule_3(",
+ " name = 'dep_1',",
+ " dep = ':dep_3',",
+ ")",
+ "rule_3(",
+ " name = 'dep_2',",
+ " dep = ':dep_3',",
+ ")",
+ "rule_3(",
+ " name = 'dep_3',",
+ ")");
+
+ AnalysisResult analysisResult = update("//test:target_1", "//test:target_2");
+
+ Iterator<ConfiguredTarget> it = analysisResult.getTargetsToBuild().iterator();
+ // aspect_a runs on dep_1 and dep_3 and it can retrieve aspect_c provider value on them
+ // aspect_c here should get its parameter value from rule_2
+ ConfiguredTarget target1 = it.next();
+ StarlarkProvider.Key provAkey =
+ new StarlarkProvider.Key(
+ Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "prov_a");
+ StructImpl provA = (StructImpl) target1.get(provAkey);
+ assertThat((Sequence<?>) provA.getValue("val"))
+ .containsExactly(
+ "aspect_c runs on target //test:dep_1 and param = rule_1_val",
+ "aspect_a runs on target //test:dep_1",
+ "aspect_c runs on target //test:dep_3 and param = rule_1_val",
+ "aspect_a runs on target //test:dep_3");
+
+ // aspect_b runs on dep_2 and dep_3 and it can retrieve aspect_c provider value on them.
+ // aspect_c here should get its parameter value from rule_2
+ ConfiguredTarget target2 = it.next();
+ StarlarkProvider.Key provBkey =
+ new StarlarkProvider.Key(
+ Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "prov_b");
+ StructImpl provB = (StructImpl) target2.get(provBkey);
+ assertThat((Sequence<?>) provB.getValue("val"))
+ .containsExactly(
+ "aspect_c runs on target //test:dep_2 and param = rule_2_val",
+ "aspect_b runs on target //test:dep_2",
+ "aspect_c runs on target //test:dep_3 and param = rule_2_val",
+ "aspect_b runs on target //test:dep_3");
+ }
+
+ @Test
+ public void testAspectRequiresAspect_requireNativeAspect() throws Exception {
+ exposeNativeAspectToStarlark();
+ useConfiguration(
+ "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
+ scratch.file(
+ "test/defs.bzl",
+ "prov_a = provider()",
+ "def _impl(target, ctx):",
+ " res = 'aspect_a on target {} '.format(target.label)",
+ " if hasattr(target, 'native_aspect_prov'):",
+ " res += 'can see native aspect provider'",
+ " else:",
+ " res += 'cannot see native aspect provider'",
+ " complete_res = [res]",
+ " if hasattr(ctx.rule.attr, 'dep'):",
+ " complete_res += ctx.rule.attr.dep[prov_a].val",
+ " return [prov_a(val = complete_res)]",
+ "aspect_a = aspect(implementation = _impl,",
+ " requires = [starlark_native_aspect],",
+ " attr_aspects = ['dep'],)",
+ "",
+ "def _my_rule_impl(ctx):",
+ " pass",
+ "my_rule = rule(implementation = _my_rule_impl,",
+ " attrs = {'dep': attr.label()})");
+ scratch.file(
+ "test/BUILD",
+ "load('//test:defs.bzl', 'my_rule')",
+ "my_rule(",
+ " name = 'main_target',",
+ " dep = ':dep_1',",
+ ")",
+ "my_rule(",
+ " name = 'dep_1',",
+ " dep = ':dep_2',",
+ ")",
+ "honest(",
+ " name = 'dep_2',",
+ ")");
+
+ AnalysisResult analysisResult =
+ update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
+
+ Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
+ // aspect_a runs on main_target, dep_1 and dep_2 but it can only see the required native aspect
+ // run on dep_2 because its rule satisfies its required provider.
+ ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
+ assertThat(aspectA).isNotNull();
+ StarlarkProvider.Key aResult =
+ new StarlarkProvider.Key(
+ Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "prov_a");
+ StructImpl aResultProvider = (StructImpl) aspectA.get(aResult);
+ assertThat((Sequence<?>) aResultProvider.getValue("val"))
+ .containsExactly(
+ "aspect_a on target //test:main_target cannot see native aspect provider",
+ "aspect_a on target //test:dep_1 cannot see native aspect provider",
+ "aspect_a on target //test:dep_2 can see native aspect provider");
+ }
+
+ @Test
public void testAspectRequiresAspect_aspectsParameters() throws Exception {
+ useConfiguration("--experimental_required_aspects");
scratch.file(
"test/defs.bzl",
"RequiredAspectProv = provider()",
@@ -3565,7 +3944,6 @@
" name = 'dep_target',",
")");
- useConfiguration("--experimental_required_aspects");
AnalysisResult analysisResult = update("//test:main");
// Both base_aspect and required_aspect can get their parameters values from the base rule
@@ -3602,7 +3980,6 @@
" return [RequiredAspectProv(p_val = p_val)]",
"required_aspect = aspect(",
" implementation = _required_aspect_impl,",
- " attr_aspects = ['dep'],",
")",
"",
"def _base_aspect_impl(target, ctx):",
@@ -3668,9 +4045,8 @@
@Test
public void testAspectRequiresAspect_inheritPropagationAttributes() throws Exception {
// base_aspect propagates over base_dep attribute and requires first_required_aspect which
- // propagates
- // over first_dep attribute and requires second_required aspect which propagates over second_dep
- // attribute
+ // propagates over first_dep attribute and requires second_required aspect which propagates
+ // over second_dep attribute
scratch.file(
"test/defs.bzl",
"BaseAspectProv = provider()",
@@ -3801,6 +4177,7 @@
"aspect_c = aspect(",
" implementation = _aspect_c_impl,",
" required_providers = [Prov_C],",
+ " attr_aspects = ['dep'],",
")",
"",
"def _aspect_b_impl(target, ctx):",
@@ -3813,6 +4190,7 @@
" implementation = _aspect_b_impl,",
" required_providers = [Prov_B],",
" requires = [aspect_c],",
+ " attr_aspects = ['dep'],",
")",
"",
"def _aspect_a_impl(target, ctx):",
@@ -5782,424 +6160,6 @@
}
@Test
- public void testTopLevelAspectRequiresAspect_inheritDefaultValues() throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "def _impl(target, ctx):",
- " return []",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl, requires = [aspect_b])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- assertThat(configuredAspects).hasSize(2);
-
- // aspect_b inherits the required providers and propagation attributes from aspect_a
- AspectKey aspectB = getAspectKey(configuredAspects, "aspect_b");
- assertThat(aspectB).isNotNull();
- assertThat(aspectB.getInheritedRequiredProviders())
- .isEqualTo(RequiredProviders.acceptAnyBuilder().build());
- assertThat(aspectB.getInheritedAttributeAspects()).isEmpty();
-
- AspectKey aspectA = getAspectKey(configuredAspects, "aspect_a");
- assertThat(aspectA).isNotNull();
- assertThat(aspectA.getInheritedRequiredProviders()).isNull();
- assertThat(aspectA.getInheritedAttributeAspects()).isEmpty();
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritAttrAspectsFromSingleAspect()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "def _impl(target, ctx):",
- " return []",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl,",
- " attr_aspects = ['deps'],",
- " requires = [aspect_b])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectB = getAspectKey(configuredAspects, "aspect_b");
- assertThat(aspectB).isNotNull();
- assertThat(aspectB.getInheritedAttributeAspects()).containsExactly("deps");
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritRequiredProvidersFromSingleAspect()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " return []",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl,",
- " required_providers=[['java', cc], ['python']],",
- " requires = [aspect_b])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectB = getAspectKey(configuredAspects, "aspect_b");
- assertThat(aspectB).isNotNull();
- assertThat(aspectB.getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'cc'] or 'python'");
- }
-
- @Test
- public void testTopLevelAspectRequiresExistingAspect_inheritAttrAspectsFromSingleAspect()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "def _impl(target, ctx):",
- " return []",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl,",
- " attr_aspects = ['deps'],",
- " requires = [aspect_b])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%aspect_b", "test/defs.bzl%aspect_a"),
- "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectB = getAspectKey(configuredAspects, "aspect_b");
- assertThat(aspectB).isNotNull();
- assertThat(aspectB.getInheritedAttributeAspects()).containsExactly("deps");
- }
-
- @Test
- public void testTopLevelAspectRequiresExistingAspect_inheritRequiredProvidersFromSingleAspect()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " return []",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl,",
- " required_providers=[['java', cc], ['python']],",
- " requires = [aspect_b])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%aspect_b", "test/defs.bzl%aspect_a"),
- "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectB = getAspectKey(configuredAspects, "aspect_b");
- assertThat(aspectB).isNotNull();
- assertThat(aspectB.getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'cc'] or 'python'");
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritAttrAspectsFromMultipleAspects()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "def _impl(target, ctx):",
- " return []",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['extra_deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['deps'])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
- "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectC = getAspectKey(configuredAspects, "aspect_c");
- assertThat(aspectC).isNotNull();
- assertThat(aspectC.getInheritedAttributeAspects()).containsExactly("deps", "extra_deps");
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritRequiredProvidersFromMultipleAspects()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " return []",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=['go'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=[['java', cc], ['python']])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
- "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectC = getAspectKey(configuredAspects, "aspect_c");
- assertThat(aspectC).isNotNull();
- assertThat(aspectC.getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'cc'] or 'python' or 'go'");
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritAllAttrAspects() throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " return []",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['extra_deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['*'])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
- "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectC = getAspectKey(configuredAspects, "aspect_c");
- assertThat(aspectC).isNotNull();
- // propagate along all attributes '*'
- assertThat(aspectC.getInheritedAttributeAspects()).isNull();
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritAllRequiredProviders() throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " return []",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers = [])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=[['java', cc], ['python']])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
- "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectC = getAspectKey(configuredAspects, "aspect_c");
- assertThat(aspectC).isNotNull();
- assertThat(aspectC.getInheritedRequiredProviders())
- .isEqualTo(RequiredProviders.acceptAnyBuilder().build());
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritAttrAspectsFromAspectsStack()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "def _impl(target, ctx):",
- " return []",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['extra_deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " attr_aspects = ['deps'])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectC = getAspectKey(configuredAspects, "aspect_c");
- assertThat(aspectC).isNotNull();
- assertThat(aspectC.getInheritedAttributeAspects()).containsExactly("deps", "extra_deps");
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritRequiredProvidersFromAspectsStack()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " return []",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=['go'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " required_providers=[['java', cc], ['python']])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectC = getAspectKey(configuredAspects, "aspect_c");
- assertThat(aspectC).isNotNull();
- assertThat(aspectC.getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'cc'] or 'python' or 'go'");
- }
-
- @Test
- public void testTopLevelAspectRequiringAspect_inheritAllAttrAspectsFromAspectsStack()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "def _impl(target, ctx):",
- " return []",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['*'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " attr_aspects = ['deps'])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectC = getAspectKey(configuredAspects, "aspect_c");
- assertThat(aspectC).isNotNull();
- // propagate along all attributes '*'
- assertThat(aspectC.getInheritedAttributeAspects()).isNull();
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_inheritAllRequiredProvidersFromAspectsStack()
- throws Exception {
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " return []",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=[cc])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " required_providers=[])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey aspectC = getAspectKey(configuredAspects, "aspect_c");
- assertThat(aspectC).isNotNull();
- assertThat(aspectC.getInheritedRequiredProviders())
- .isEqualTo(RequiredProviders.acceptAnyBuilder().build());
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_requiredNativeAspect_inheritsAttrAspects()
- throws Exception {
- exposeNativeAspectToStarlark();
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "def _impl(target, ctx):",
- " return []",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [starlark_native_aspect],",
- " attr_aspects = ['deps'])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey nativeAspect = getAspectKey(configuredAspects, "StarlarkNativeAspectWithProvider");
- assertThat(nativeAspect).isNotNull();
- assertThat(nativeAspect.getInheritedAttributeAspects()).containsExactly("deps");
- }
-
- @Test
- public void testTopLevelAspectRequiresAspect_requiredNativeAspect_inheritsRequiredProviders()
- throws Exception {
- exposeNativeAspectToStarlark();
- useConfiguration(
- "--experimental_required_aspects", "--incompatible_top_level_aspects_dependency");
- scratch.file(
- "test/defs.bzl",
- "rule_prov = provider()",
- "def _impl(target, ctx):",
- " return []",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [starlark_native_aspect],",
- " required_providers = [['java', rule_prov], ['python']])");
- scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- AspectKey nativeAspect = getAspectKey(configuredAspects, "StarlarkNativeAspectWithProvider");
- assertThat(nativeAspect).isNotNull();
- assertThat(nativeAspect.getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'rule_prov'] or 'python'");
- }
-
- @Test
public void testTopLevelAspectRequiresAspect_requiredNativeAspect_parametersNotAllowed()
throws Exception {
exposeNativeAspectToStarlark();
@@ -6259,16 +6219,17 @@
"def _required_aspect_impl(target, ctx):",
" p_val = ['In required_aspect, p = {} on target {}'",
" .format(ctx.rule.attr.p, target.label)]",
- " if ctx.rule.attr.dep:",
+ " if ctx.rule.attr.dep and RequiredAspectProv in ctx.rule.attr.dep:",
" p_val += ctx.rule.attr.dep[RequiredAspectProv].p_val",
" return [RequiredAspectProv(p_val = p_val)]",
"required_aspect = aspect(",
" implementation = _required_aspect_impl,",
- " attr_aspects = ['dep'],",
")",
"",
"def _base_aspect_impl(target, ctx):",
- " p_val = ['In base_aspect, p = {} on target {}'.format(ctx.rule.attr.p, target.label)]",
+ " p_val = []",
+ " p_val += target[RequiredAspectProv].p_val",
+ " p_val += ['In base_aspect, p = {} on target {}'.format(ctx.rule.attr.p, target.label)]",
" if ctx.rule.attr.dep:",
" p_val += ctx.rule.attr.dep[BaseAspectProv].p_val",
" return [BaseAspectProv(p_val = p_val)]",
@@ -6304,7 +6265,8 @@
AnalysisResult analysisResult =
update(ImmutableList.of("test/defs.bzl%base_aspect"), "//test:main_target");
- // Both base_aspect and required_aspect can see the attributes of the target they run on
+ // required_aspect can only run on main_target when propagated alone since its attr_aspects is
+ // empty.
Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
ConfiguredAspect requiredAspect = getConfiguredAspect(configuredAspects, "required_aspect");
assertThat(requiredAspect).isNotNull();
@@ -6313,10 +6275,10 @@
Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "RequiredAspectProv");
StructImpl requiredAspectProvider = (StructImpl) requiredAspect.get(requiredAspectProv);
assertThat((Sequence<?>) requiredAspectProvider.getValue("p_val"))
- .containsExactly(
- "In required_aspect, p = dep_val on target //test:dep_target",
- "In required_aspect, p = main_val on target //test:main_target");
+ .containsExactly("In required_aspect, p = main_val on target //test:main_target");
+ // base_aspect can run on main_target and dep_target and it can also see the providers created
+ // by running required_target on them.
ConfiguredAspect baseAspect = getConfiguredAspect(configuredAspects, "base_aspect");
assertThat(baseAspect).isNotNull();
StarlarkProvider.Key baseAspectProv =
@@ -6326,7 +6288,9 @@
assertThat((Sequence<?>) baseAspectProvider.getValue("p_val"))
.containsExactly(
"In base_aspect, p = dep_val on target //test:dep_target",
- "In base_aspect, p = main_val on target //test:main_target");
+ "In base_aspect, p = main_val on target //test:main_target",
+ "In required_aspect, p = dep_val on target //test:dep_target",
+ "In required_aspect, p = main_val on target //test:main_target");
}
@Test
@@ -6456,6 +6420,7 @@
"aspect_c = aspect(",
" implementation = _aspect_c_impl,",
" required_providers = [Prov_C],",
+ " attr_aspects = ['dep'],",
")",
"",
"def _aspect_b_impl(target, ctx):",
@@ -6468,6 +6433,7 @@
" implementation = _aspect_b_impl,",
" required_providers = [Prov_B],",
" requires = [aspect_c],",
+ " attr_aspects = ['dep'],",
")",
"",
"def _aspect_a_impl(target, ctx):",
@@ -6840,10 +6806,12 @@
private ConfiguredAspect getConfiguredAspect(
Map<AspectKey, ConfiguredAspect> aspectsMap, String aspectName) {
for (Map.Entry<AspectKey, ConfiguredAspect> entry : aspectsMap.entrySet()) {
- String aspectExportedName =
- ((StarlarkAspectClass) entry.getKey().getAspectClass()).getExportedName();
- if (aspectExportedName.equals(aspectName)) {
- return entry.getValue();
+ AspectClass aspectClass = entry.getKey().getAspectClass();
+ if (aspectClass instanceof StarlarkAspectClass) {
+ String aspectExportedName = ((StarlarkAspectClass) aspectClass).getExportedName();
+ if (aspectExportedName.equals(aspectName)) {
+ return entry.getValue();
+ }
}
}
return null;
@@ -6852,21 +6820,13 @@
private ConfiguredAspect getConfiguredAspect(
Map<AspectKey, ConfiguredAspect> aspectsMap, String aspectName, String targetName) {
for (Map.Entry<AspectKey, ConfiguredAspect> entry : aspectsMap.entrySet()) {
- String aspectExportedName =
- ((StarlarkAspectClass) entry.getKey().getAspectClass()).getExportedName();
- String target = entry.getKey().getLabel().getName();
- if (aspectExportedName.equals(aspectName) && target.equals(targetName)) {
- return entry.getValue();
- }
- }
- return null;
- }
-
- private AspectKey getAspectKey(Map<AspectKey, ConfiguredAspect> aspectsMap, String aspectName) {
- for (Map.Entry<AspectKey, ConfiguredAspect> entry : aspectsMap.entrySet()) {
- String aspectExportedName = entry.getKey().getAspectClass().getName();
- if (aspectExportedName.contains(aspectName)) {
- return entry.getKey();
+ AspectClass aspectClass = entry.getKey().getAspectClass();
+ if (aspectClass instanceof StarlarkAspectClass) {
+ String aspectExportedName = ((StarlarkAspectClass) aspectClass).getExportedName();
+ String target = entry.getKey().getLabel().getName();
+ if (aspectExportedName.equals(aspectName) && target.equals(targetName)) {
+ return entry.getValue();
+ }
}
}
return null;
@@ -6882,6 +6842,8 @@
TestAspects.PARAMETRIZED_STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
builder.addNativeAspectClass(TestAspects.STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
builder.addNativeAspectClass(TestAspects.PARAMETRIZED_STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
+ builder.addRuleDefinition(TestAspects.BASE_RULE);
+ builder.addRuleDefinition(TestAspects.HONEST_RULE);
useRuleClassProvider(builder.build());
}
diff --git a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
index 3c23b61..4307678 100644
--- a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
@@ -551,754 +551,6 @@
}
@Test
- public void testAttrWithAspectRequiringAspects_inheritDefaultValues() throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "def _impl(target, ctx):",
- " pass",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl, requires = [aspect_b])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl, attrs={'a': attr.label_list(aspects = [aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- // aspect_b inherits the required providers and propagation attributes from aspect_a
- Aspect aspectB = aspects.get(0);
- assertThat(aspectB.getDescriptor().getInheritedRequiredProviders())
- .isEqualTo(RequiredProviders.acceptAnyBuilder().build());
- assertThat(aspectB.getDescriptor().getInheritedAttributeAspects()).isEmpty();
-
- // aspect_a is not required by any other aspect so its does not inherit anything
- Aspect aspectA = aspects.get(1);
- assertThat(aspectA.getDescriptor().getInheritedRequiredProviders()).isNull();
- assertThat(aspectA.getDescriptor().getInheritedAttributeAspects()).isEmpty();
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritAttrAspectsFromSingleAspect()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_b = aspect(implementation = _impl,",
- " attr_aspects = ['extra_deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " attr_aspects = ['deps'])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs = {'a': attr.label_list(aspects = [aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectB = aspects.get(0);
- assertThat(aspectB.getDescriptor().getInheritedAttributeAspects()).containsExactly("deps");
- assertThat(aspectB.getDefinition().getRestrictToAttributes()).containsExactly("extra_deps");
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritRequiredProvidersFromSingleAspect()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_b = aspect(implementation = _impl,",
- " required_providers= ['go'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " required_providers=[['java', cc], ['python']])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs = {'a': attr.label_list(aspects = [aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectB = aspects.get(0);
- assertThat(aspectB.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'cc'] or 'python'");
- assertThat(aspectB.getDefinition().getRequiredProviders().getDescription()).isEqualTo("'go'");
- }
-
- @Test
- public void testAttrWithAspectRequiringExistingAspect_inheritAttrAspectsFromSingleAspect()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl, requires = [aspect_b],",
- " attr_aspects = ['deps'])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs={'a': attr.label_list(aspects = [aspect_b, aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectB = aspects.get(0);
- assertThat(aspectB.getDescriptor().getInheritedAttributeAspects()).containsExactly("deps");
- }
-
- @Test
- public void testAttrWithAspectRequiringExistingAspect_inheritRequiredProvidersFromSingleAspect()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " required_providers=[['java', cc], ['python']])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl, attrs={'a': attr.label_list(aspects = [aspect_b, aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectB = aspects.get(0);
- assertThat(aspectB.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'cc'] or 'python'");
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritAttrAspectsFromMultipleAspects()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['extra_deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['deps'])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs={'a': attr.label_list(aspects = [aspect_a, aspect_b])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects())
- .containsExactly("deps", "extra_deps");
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritRequiredProvidersFromMultipleAspects()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=['go'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=[['java', cc], ['python']])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs={'a': attr.label_list(aspects = [aspect_a, aspect_b])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'cc'] or 'python' or 'go'");
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritAllAttrAspects() throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['extra_deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['*'])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl, attrs={'a': attr.label_list(aspects = [aspect_a, aspect_b])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects())
- .isNull(); // propagate along all attributes '*'
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritAllRequiredProviders() throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers = [])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=[['java', cc], ['python']])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl, attrs={'a': attr.label_list(aspects = [aspect_a, aspect_b])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders())
- .isEqualTo(RequiredProviders.acceptAnyBuilder().build());
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritAttrAspectsFromAspectsStack()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['extra_deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " attr_aspects = ['deps'])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl, attrs={'a': attr.label_list(aspects = [aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects())
- .containsExactly("deps", "extra_deps");
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritRequiredProvidersFromAspectsStack()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=['go'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " required_providers=[['java', cc], ['python']])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl, attrs={'a': attr.label_list(aspects = [aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['java', 'cc'] or 'python' or 'go'");
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritAllAttrAspectsFromAspectsStack()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['*'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " attr_aspects = ['deps'])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl, attrs={'a': attr.label_list(aspects = [aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects())
- .isNull(); // propagate along all attributes '*'
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_inheritAllRequiredProvidersFromAspectsStack()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "cc = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=[cc])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_b],",
- " required_providers=[])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl, attrs={'a': attr.label_list(aspects = [aspect_a])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute a = rule.getRuleClassObject().getAttributeByName("a");
- ImmutableList<Aspect> aspects = a.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders())
- .isEqualTo(RequiredProviders.acceptAnyBuilder().build());
- }
-
- /**
- * An aspect required by different aspects in different attributes inherits the correct
- * propagation attributes.
- */
- @Test
- public void testAttrWithAspectRequiringAspects_aspectRequiredInMultipleAttrs_inheritAttrAspects()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['extra_deps'])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs={'attr1': attr.label_list(aspects = [aspect_a]),",
- " 'attr2': attr.label_list(aspects = [aspect_b]),",
- " 'attr3': attr.label_list(aspects = [aspect_c])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute attr1 = rule.getRuleClassObject().getAttributeByName("attr1");
- ImmutableList<Aspect> aspects = attr1.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects())
- .containsExactly("extra_deps");
-
- Attribute attr2 = rule.getRuleClassObject().getAttributeByName("attr2");
- aspects = attr2.getAspects(rule);
- aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects()).containsExactly("deps");
-
- Attribute attr3 = rule.getRuleClassObject().getAttributeByName("attr3");
- aspects = attr3.getAspects(rule);
- aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects()).isEmpty();
- }
-
- /**
- * An aspect required by different aspects in different attributes inherits the correct required
- * providers.
- */
- @Test
- public void
- testAttrWithAspectRequiringAspects_aspectRequiredInMultipleAttrs_inheritRequiredProviders()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=['prov1', 'prov2'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=[['prov3', 'prov4'], ['prov2']])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs={'attr1': attr.label_list(aspects = [aspect_a]),",
- " 'attr2': attr.label_list(aspects = [aspect_b]),",
- " 'attr3': attr.label_list(aspects = [aspect_c])})");
- scratch.file("BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute attr1 = rule.getRuleClassObject().getAttributeByName("attr1");
- ImmutableList<Aspect> aspects = attr1.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['prov3', 'prov4'] or 'prov2'");
-
- Attribute attr2 = rule.getRuleClassObject().getAttributeByName("attr2");
- aspects = attr2.getAspects(rule);
- aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['prov1', 'prov2']");
-
- Attribute attr3 = rule.getRuleClassObject().getAttributeByName("attr3");
- aspects = attr3.getAspects(rule);
- aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders()).isNull();
- }
-
- /**
- * An aspect required by different aspects in different rules inherits the correct propagation
- * attributes.
- */
- @Test
- public void testAttrWithAspectRequiringAspects_aspectRequiredInMultipleRules_inheritAttrAspects()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['deps'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " attr_aspects = ['extra_deps'])",
- "def impl(ctx):",
- " return None",
- "rule_1 = rule(impl,",
- " attrs={'attr': attr.label_list(aspects = [aspect_a])})",
- "rule_2 = rule(impl,",
- " attrs={'attr': attr.label_list(aspects = [aspect_b])})");
- scratch.file(
- "BUILD",
- "load(':lib.bzl', 'rule_1', 'rule_2')",
- "rule_1(name = 't1')",
- "rule_2(name = 't2')");
-
- RuleContext ruleContext1 = createRuleContext("//:t1").getRuleContext();
- RuleContext ruleContext2 = createRuleContext("//:t2").getRuleContext();
-
- Rule rule = ruleContext1.getRule();
- Attribute attr = rule.getRuleClassObject().getAttributeByName("attr");
- ImmutableList<Aspect> aspects = attr.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects())
- .containsExactly("extra_deps");
-
- rule = ruleContext2.getRule();
- attr = rule.getRuleClassObject().getAttributeByName("attr");
- aspects = attr.getAspects(rule);
- aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedAttributeAspects()).containsExactly("deps");
- }
-
- /**
- * An aspect required by different aspects in different rules inherits the correct required
- * providers.
- */
- @Test
- public void
- testAttrWithAspectRequiringAspects_aspectRequiredInMultipleRules_inheritRequiredProviders()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl)",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=['prov1', 'prov2'])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c],",
- " required_providers=[['prov3', 'prov4'], ['prov2']])",
- "def impl(ctx):",
- " return None",
- "rule_1 = rule(impl,",
- " attrs={'attr': attr.label_list(aspects = [aspect_a])})",
- "rule_2 = rule(impl,",
- " attrs={'attr': attr.label_list(aspects = [aspect_b])})");
- scratch.file(
- "BUILD",
- "load(':lib.bzl', 'rule_1', 'rule_2')",
- "rule_1(name = 't1')",
- "rule_2(name = 't2')");
-
- RuleContext ruleContext1 = createRuleContext("//:t1").getRuleContext();
- RuleContext ruleContext2 = createRuleContext("//:t2").getRuleContext();
-
- Rule rule = ruleContext1.getRule();
- Attribute attr = rule.getRuleClassObject().getAttributeByName("attr");
- ImmutableList<Aspect> aspects = attr.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['prov3', 'prov4'] or 'prov2'");
-
- rule = ruleContext2.getRule();
- attr = rule.getRuleClassObject().getAttributeByName("attr");
- aspects = attr.getAspects(rule);
- aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['prov1', 'prov2']");
- }
-
- /**
- * An aspect required by different aspects in different rules gets the correct parameters values
- * from its base rule.
- */
- @Test
- public void testAttrWithAspectRequiringAspects_aspectRequiredInMultipleRules_getParametersValues()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "def _impl(target, ctx):",
- " pass",
- "aspect_c = aspect(implementation = _impl,",
- " attrs = {'param': attr.string(values = ['v1', 'v2', 'v3'])})",
- "aspect_b = aspect(implementation = _impl,",
- " requires = [aspect_c])",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [aspect_c])",
- "def impl(ctx):",
- " return None",
- "rule_1 = rule(impl,",
- " attrs={'attr': attr.label_list(aspects = [aspect_a]),",
- " 'param': attr.string()})",
- "rule_2 = rule(impl,",
- " attrs={'attr': attr.label_list(aspects = [aspect_b]),",
- " 'param': attr.string()})");
- scratch.file(
- "BUILD",
- "load(':lib.bzl', 'rule_1', 'rule_2')",
- "rule_1(name = 't1', param = 'v1')",
- "rule_2(name = 't2', param = 'v2')");
-
- RuleContext ruleContext1 = createRuleContext("//:t1").getRuleContext();
- RuleContext ruleContext2 = createRuleContext("//:t2").getRuleContext();
-
- Rule rule = ruleContext1.getRule();
- Attribute attr = rule.getRuleClassObject().getAttributeByName("attr");
- ImmutableList<Aspect> aspects = attr.getAspects(rule);
- Aspect aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDefinition().getAttributes().get("param").getDefaultValueUnchecked())
- .isEqualTo("v1");
-
- rule = ruleContext2.getRule();
- attr = rule.getRuleClassObject().getAttributeByName("attr");
- aspects = attr.getAspects(rule);
- aspectC = aspects.get(0);
- assertThat(aspectC.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_c");
- assertThat(aspectC.getDefinition().getAttributes().get("param").getDefaultValueUnchecked())
- .isEqualTo("v2");
- }
-
- /**
- * Using the same attribute in multiple rules should not change the required aspect inherited
- * propagation attributes.
- */
- @Test
- public void testAttrWithAspectRequiringAspects_sameAttrInMultipleRules_inheritSameAttrAspects()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "def _impl(target, ctx):",
- " pass",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl, requires = [aspect_b],",
- " attr_aspects = ['extra_deps'])",
- "my_attr = attr.label_list(aspects = [aspect_a])",
- "def impl(ctx):",
- " return None",
- "rule_1 = rule(impl,",
- " attrs={'attr': my_attr})",
- "rule_2 = rule(impl,",
- " attrs={'attr': my_attr})");
- scratch.file(
- "BUILD",
- "load(':lib.bzl', 'rule_1', 'rule_2')",
- "rule_1(name = 't1')",
- "rule_2(name = 't2')");
-
- RuleContext ruleContext1 = createRuleContext("//:t1").getRuleContext();
- RuleContext ruleContext2 = createRuleContext("//:t2").getRuleContext();
-
- Rule rule = ruleContext1.getRule();
- Attribute attr = rule.getRuleClassObject().getAttributeByName("attr");
- ImmutableList<Aspect> aspects = attr.getAspects(rule);
- Aspect aspectB = aspects.get(0);
- assertThat(aspectB.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_b");
- assertThat(aspectB.getDescriptor().getInheritedAttributeAspects())
- .containsExactly("extra_deps");
-
- rule = ruleContext2.getRule();
- attr = rule.getRuleClassObject().getAttributeByName("attr");
- aspects = attr.getAspects(rule);
- aspectB = aspects.get(0);
- assertThat(aspectB.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_b");
- assertThat(aspectB.getDescriptor().getInheritedAttributeAspects())
- .containsExactly("extra_deps");
- }
-
- /**
- * Using the same attribute in multiple rules should not change the required aspect inherited
- * required providers.
- */
- @Test
- public void
- testAttrWithAspectRequiringAspects_sameAttrInMultipleRules_inheritSameRequiredProviders()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "def _impl(target, ctx):",
- " pass",
- "aspect_b = aspect(implementation = _impl)",
- "aspect_a = aspect(implementation = _impl, requires = [aspect_b],",
- " required_providers=[['prov3', 'prov4'], ['prov2']])",
- "my_attr = attr.label_list(aspects = [aspect_a])",
- "def impl(ctx):",
- " return None",
- "rule_1 = rule(impl,",
- " attrs={'attr': my_attr})",
- "rule_2 = rule(impl,",
- " attrs={'attr': my_attr})");
- scratch.file(
- "BUILD",
- "load(':lib.bzl', 'rule_1', 'rule_2')",
- "rule_1(name = 't1')",
- "rule_2(name = 't2')");
-
- RuleContext ruleContext1 = createRuleContext("//:t1").getRuleContext();
- RuleContext ruleContext2 = createRuleContext("//:t2").getRuleContext();
-
- Rule rule = ruleContext1.getRule();
- Attribute attr = rule.getRuleClassObject().getAttributeByName("attr");
- ImmutableList<Aspect> aspects = attr.getAspects(rule);
- Aspect aspectB = aspects.get(0);
- assertThat(aspectB.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_b");
- assertThat(aspectB.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['prov3', 'prov4'] or 'prov2'");
-
- rule = ruleContext2.getRule();
- attr = rule.getRuleClassObject().getAttributeByName("attr");
- aspects = attr.getAspects(rule);
- aspectB = aspects.get(0);
- assertThat(aspectB.getAspectClass().getName()).isEqualTo("//:lib.bzl%aspect_b");
- assertThat(aspectB.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("['prov3', 'prov4'] or 'prov2'");
- }
-
- @Test
public void testAspectExtraDeps() throws Exception {
evalAndExport(
ev,
@@ -3101,7 +2353,7 @@
}
@Test
- public void testAttrWithAspectRequiringAspects_requiredNativeAspect_getsParamsFromFromBaseRules()
+ public void testAttrWithAspectRequiringAspects_requiredNativeAspect_getsParamsFromBaseRules()
throws Exception {
setBuildLanguageOptions("--experimental_required_aspects=true");
scratch.file(
@@ -3137,71 +2389,4 @@
.getDefaultValueUnchecked())
.isEqualTo("v1");
}
-
- @Test
- public void testAttrWithAspectRequiringAspects_requiredNativeAspect_inheritsAttrAspects()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "rule_prov = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [parametrized_native_aspect],",
- " attr_aspects = ['deps'],",
- " required_providers = [rule_prov])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs={'deps': attr.label_list(aspects = [aspect_a]),",
- " 'aspect_attr': attr.string()})");
- scratch.file(
- "BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main', aspect_attr = 'v1')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute attr = rule.getRuleClassObject().getAttributeByName("deps");
- ImmutableList<Aspect> aspects = attr.getAspects(rule);
- Aspect requiredNativeAspect = aspects.get(0);
- assertThat(requiredNativeAspect.getAspectClass().getName())
- .isEqualTo("ParametrizedAspectWithProvider");
- assertThat(requiredNativeAspect.getDescriptor().getInheritedAttributeAspects())
- .containsExactly("deps");
- }
-
- @Test
- public void testAttrWithAspectRequiringAspects_requiredNativeAspect_inheritsRequiredProviders()
- throws Exception {
- setBuildLanguageOptions("--experimental_required_aspects=true");
- scratch.file(
- "lib.bzl",
- "rule_prov = provider()",
- "def _impl(target, ctx):",
- " pass",
- "aspect_a = aspect(implementation = _impl,",
- " requires = [parametrized_native_aspect],",
- " attr_aspects = ['deps'],",
- " required_providers = [rule_prov])",
- "def impl(ctx):",
- " return None",
- "my_rule = rule(impl,",
- " attrs={'deps': attr.label_list(aspects = [aspect_a]),",
- " 'aspect_attr': attr.string()})");
- scratch.file(
- "BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main', aspect_attr = 'v1')");
-
- RuleContext ruleContext = createRuleContext("//:main").getRuleContext();
-
- Rule rule = ruleContext.getRule();
- Attribute attr = rule.getRuleClassObject().getAttributeByName("deps");
- ImmutableList<Aspect> aspects = attr.getAspects(rule);
- Aspect requiredNativeAspect = aspects.get(0);
- assertThat(requiredNativeAspect.getAspectClass().getName())
- .isEqualTo("ParametrizedAspectWithProvider");
- assertThat(
- requiredNativeAspect.getDescriptor().getInheritedRequiredProviders().getDescription())
- .isEqualTo("'rule_prov'");
- }
}
diff --git a/src/test/shell/integration/action_aspect_test.sh b/src/test/shell/integration/action_aspect_test.sh
index 8291db6..3b48ba3 100755
--- a/src/test/shell/integration/action_aspect_test.sh
+++ b/src/test/shell/integration/action_aspect_test.sh
@@ -346,4 +346,113 @@
EOF
}
+function test_aspect_requires_aspect_no_action_conflict() {
+ local package="test"
+ mkdir -p "${package}"
+
+ cat > "${package}/write.sh" <<EOF
+#!/bin/bash
+output_file=\$1
+unused_file=\$2
+
+echo 'output' > \$output_file
+echo 'unused' > \$unused_file
+EOF
+
+ chmod 755 "${package}/write.sh"
+
+ cat > "${package}/defs.bzl" <<EOF
+def _aspect_b_impl(target, ctx):
+ file = ctx.actions.declare_file('{}_aspect_b_file.txt'.format(target.label.name))
+ unused_file = ctx.actions.declare_file('{}.unused'.format(target.label.name))
+ args = ctx.actions.args()
+ args.add(file.path)
+ args.add(unused_file.path)
+ ctx.actions.run(
+ executable = ctx.executable._write,
+ outputs = [file, unused_file],
+ arguments = [args],
+ # Adding unused_inputs_list just to make this action not shareable
+ unused_inputs_list = unused_file,
+ )
+ return [OutputGroupInfo(aspect_b_out = [file])]
+
+aspect_b = aspect(
+ implementation = _aspect_b_impl,
+ attrs = {
+ "_write": attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ executable = True,
+ default = "//${package}:write.sh")
+ }
+)
+
+def _aspect_a_impl(target, ctx):
+ print(['aspect_a can see file ' +
+ f.path.split('/')[-1] for f in target[OutputGroupInfo].aspect_b_out.to_list()])
+ files = target[OutputGroupInfo].aspect_b_out.to_list()
+ return [OutputGroupInfo(aspect_a_out = files)]
+
+aspect_a = aspect(
+ implementation = _aspect_a_impl,
+ requires = [aspect_b],
+ attr_aspects = ['dep_2'],
+)
+
+def _rule_1_impl(ctx):
+ files = []
+ if ctx.attr.dep_1:
+ files += ctx.attr.dep_1[OutputGroupInfo].rule_2_out.to_list()
+ if ctx.attr.dep_2:
+ files += ctx.attr.dep_2[OutputGroupInfo].aspect_a_out.to_list()
+ return [DefaultInfo(files=depset(files))]
+
+rule_1 = rule(
+ implementation = _rule_1_impl,
+ attrs = {
+ 'dep_1': attr.label(),
+ 'dep_2': attr.label(aspects = [aspect_a]),
+ }
+)
+
+def _rule_2_impl(ctx):
+ files = []
+ if ctx.attr.dep:
+ print([ctx.label.name +
+ ' can see file ' +
+ f.path.split('/')[-1] for f in ctx.attr.dep[OutputGroupInfo].aspect_b_out.to_list()])
+ files += ctx.attr.dep[OutputGroupInfo].aspect_b_out.to_list()
+ return [OutputGroupInfo(rule_2_out = files)]
+
+rule_2 = rule(
+ implementation = _rule_2_impl,
+ attrs = {
+ 'dep': attr.label(aspects = [aspect_b]),
+ }
+)
+EOF
+
+ cat > "${package}/BUILD" <<EOF
+load('//${package}:defs.bzl', 'rule_1', 'rule_2')
+exports_files(["write.sh"])
+rule_1(
+ name = 'main_target',
+ dep_1 = ':dep_target_1',
+ dep_2 = ':dep_target_2',
+)
+rule_2(
+ name = 'dep_target_1',
+ dep = ':dep_target_2',
+)
+rule_2(name = 'dep_target_2')
+EOF
+
+ bazel build "//${package}:main_target"\
+ --experimental_required_aspects &> $TEST_log || fail "Build failed"
+
+ expect_log "aspect_a can see file dep_target_2_aspect_b_file.txt"
+ expect_log "dep_target_1 can see file dep_target_2_aspect_b_file.txt"
+}
+
run_suite "Tests Starlark API pertaining to action inspection via aspect"
diff --git a/src/test/shell/integration/aspect_test.sh b/src/test/shell/integration/aspect_test.sh
index bdd6430..254a03a 100755
--- a/src/test/shell/integration/aspect_test.sh
+++ b/src/test/shell/integration/aspect_test.sh
@@ -827,4 +827,164 @@
expect_log "Cannot instantiate parameterized aspect .* at the top level"
}
+function test_aspect_requires_aspect_no_providers_duplicates() {
+ local package="test"
+ mkdir -p "${package}"
+
+ cat > "${package}/defs.bzl" <<EOF
+prov_a = provider()
+prov_b = provider()
+
+def _aspect_b_impl(target, ctx):
+ res = "aspect_b run on target {}".format(target.label.name)
+ print(res)
+ return [prov_b(value = res)]
+
+aspect_b = aspect(
+ implementation = _aspect_b_impl,
+)
+
+def _aspect_a_impl(target, ctx):
+ res = "aspect_a run on target {}".format(target.label.name)
+ print(res)
+ return [prov_a(value = res)]
+
+aspect_a = aspect(
+ implementation = _aspect_a_impl,
+ requires = [aspect_b],
+ attr_aspects = ['dep'],
+)
+
+def _rule_1_impl(ctx):
+ pass
+
+rule_1 = rule(
+ implementation = _rule_1_impl,
+ attrs = {
+ 'dep': attr.label(aspects = [aspect_a]),
+ }
+)
+
+def _rule_2_impl(ctx):
+ pass
+
+rule_2 = rule(
+ implementation = _rule_2_impl,
+ attrs = {
+ 'dep': attr.label(aspects = [aspect_b]),
+ }
+)
+EOF
+
+ cat > "${package}/BUILD" <<EOF
+load('//${package}:defs.bzl', 'rule_1', 'rule_2')
+exports_files(["write.sh"])
+rule_1(
+ name = 't1',
+ dep = ':t2',
+)
+rule_2(
+ name = 't2',
+ dep = ':t3',
+)
+rule_2(
+ name = 't3',
+)
+EOF
+
+ bazel build "//${package}:t1"\
+ --experimental_required_aspects &> $TEST_log || fail "Build failed"
+
+ expect_log "aspect_a run on target t3"
+ expect_log "aspect_b run on target t3"
+ expect_log "aspect_a run on target t2"
+ expect_log "aspect_b run on target t2"
+}
+
+# test that although a required aspect runs once on a target, it can still keep
+# propagating while inheriting its main aspect attr_aspects
+function test_aspect_requires_aspect_no_providers_duplicates_2() {
+ local package="test"
+ mkdir -p "${package}"
+
+ cat > "${package}/defs.bzl" <<EOF
+prov_a = provider()
+prov_b = provider()
+
+def _aspect_b_impl(target, ctx):
+ res = "aspect_b run on target {}".format(target.label.name)
+ print(res)
+ return [prov_b(value = res)]
+
+aspect_b = aspect(
+ implementation = _aspect_b_impl,
+)
+
+def _aspect_a_impl(target, ctx):
+ res = "aspect_a run on target {}".format(target.label.name)
+ print(res)
+ return [prov_a(value = res)]
+
+aspect_a = aspect(
+ implementation = _aspect_a_impl,
+ requires = [aspect_b],
+ attr_aspects = ['dep_1', 'dep_2'],
+)
+
+def _empty_impl(ctx):
+ pass
+
+rule_1 = rule(
+ implementation = _empty_impl,
+ attrs = {
+ 'dep_1': attr.label(aspects = [aspect_a]),
+ }
+)
+
+rule_2 = rule(
+ implementation = _empty_impl,
+ attrs = {
+ 'dep_1': attr.label(aspects = [aspect_b]),
+ }
+)
+
+rule_3 = rule(
+ implementation = _empty_impl,
+ attrs = {
+ 'dep_2': attr.label(),
+ }
+)
+EOF
+
+ cat > "${package}/BUILD" <<EOF
+load('//${package}:defs.bzl', 'rule_1', 'rule_2', 'rule_3')
+exports_files(["write.sh"])
+rule_1(
+ name = 't1',
+ dep_1 = ':t2',
+)
+rule_2(
+ name = 't2',
+ dep_1 = ':t3',
+)
+rule_3(
+ name = 't3',
+ dep_2 = ':t4',
+)
+rule_3(
+ name = 't4',
+)
+EOF
+
+ bazel build "//${package}:t1"\
+ --experimental_required_aspects &> $TEST_log || fail "Build failed"
+
+ expect_log "aspect_a run on target t4"
+ expect_log "aspect_b run on target t4"
+ expect_log "aspect_a run on target t3"
+ expect_log "aspect_b run on target t3"
+ expect_log "aspect_a run on target t2"
+ expect_log "aspect_b run on target t2"
+}
+
run_suite "Tests for aspects"