Automated rollback of commit 943c83aa58731c4f9561d79c458f254427a8f24c.
*** Reason for rollback ***
This CL causes memory regression for single top-level aspect described in
b/193314770
*** Original change description ***
Command line aspect-on-aspect
This CL supports aspect-on-aspect for command line aspects. Command line aspects specified via `--aspects` option will support a top-level aspect requiring aspect providers via `required_aspect_providers` to get their values from other top-level aspects advertising it that come before it in the `--aspects` list.
PiperOrigin-RevId: 384430487
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
index 2a8445a..1e8a0ef 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
@@ -30,7 +30,7 @@
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
+import com.google.devtools.build.lib.skyframe.AspectValueKey;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import java.util.Collection;
import javax.annotation.Nullable;
@@ -40,7 +40,7 @@
* target cannot be completed because of an error in one of its dependencies.
*/
public class AnalysisFailureEvent implements BuildEvent {
- @Nullable private final AspectKey failedAspect;
+ @Nullable private final AspectValueKey failedAspect;
private final ConfiguredTargetKey failedTarget;
private final BuildEventId configuration;
private final NestedSet<Cause> rootCauses;
@@ -48,12 +48,12 @@
public AnalysisFailureEvent(
ActionLookupKey failedTarget, BuildEventId configuration, NestedSet<Cause> rootCauses) {
Preconditions.checkArgument(
- failedTarget instanceof ConfiguredTargetKey || failedTarget instanceof AspectKey);
+ failedTarget instanceof ConfiguredTargetKey || failedTarget instanceof AspectValueKey);
if (failedTarget instanceof ConfiguredTargetKey) {
this.failedAspect = null;
this.failedTarget = (ConfiguredTargetKey) failedTarget;
} else {
- this.failedAspect = (AspectKey) failedTarget;
+ this.failedAspect = (AspectValueKey) failedTarget;
this.failedTarget = failedAspect.getBaseConfiguredTargetKey();
}
if (configuration != null) {
@@ -65,7 +65,7 @@
}
public AnalysisFailureEvent(
- AspectKey failedAspect, BuildEventId configuration, NestedSet<Cause> rootCauses) {
+ AspectValueKey failedAspect, BuildEventId configuration, NestedSet<Cause> rootCauses) {
this.failedAspect = failedAspect;
this.failedTarget = failedAspect.getBaseConfiguredTargetKey();
if (configuration != null) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
index f835927..bec43a1 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
@@ -55,12 +55,13 @@
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
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.Attribute;
import com.google.devtools.build.lib.packages.NativeAspectClass;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.StarlarkAspectClass;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.pkgcache.PackageManager;
@@ -74,7 +75,6 @@
import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns.Code;
import com.google.devtools.build.lib.skyframe.AspectValueKey;
import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
-import com.google.devtools.build.lib.skyframe.AspectValueKey.TopLevelAspectsKey;
import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.CoverageReportValue;
@@ -86,6 +86,7 @@
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.RegexFilter;
import com.google.devtools.build.skyframe.WalkableGraph;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -274,7 +275,10 @@
.map(TargetAndConfiguration::getConfiguredTargetKey)
.collect(Collectors.toList());
- ImmutableList.Builder<AspectClass> aspectClassesBuilder = ImmutableList.builder();
+ Multimap<Pair<Label, String>, BuildConfiguration> aspectConfigurations =
+ ArrayListMultimap.create();
+
+ List<AspectValueKey> aspectKeys = new ArrayList<>();
for (String aspect : aspects) {
// Syntax: label%aspect
int delimiterPosition = aspect.indexOf('%');
@@ -314,14 +318,38 @@
createFailureDetail(errorMessage, Analysis.Code.ASPECT_LABEL_SYNTAX_ERROR),
e);
}
+
String starlarkFunctionName = aspect.substring(delimiterPosition + 1);
- aspectClassesBuilder.add(new StarlarkAspectClass(starlarkFileLabel, starlarkFunctionName));
+ for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
+ aspectConfigurations.put(
+ Pair.of(targetSpec.getLabel(), aspect), targetSpec.getConfiguration());
+ aspectKeys.add(
+ AspectValueKey.createStarlarkAspectKey(
+ targetSpec.getLabel(),
+ // For invoking top-level aspects, use the top-level configuration for both the
+ // aspect and the base target while the top-level configuration is untrimmed.
+ targetSpec.getConfiguration(),
+ targetSpec.getConfiguration(),
+ starlarkFileLabel,
+ starlarkFunctionName));
+ }
} else {
final NativeAspectClass aspectFactoryClass =
ruleClassProvider.getNativeAspectClassMap().get(aspect);
if (aspectFactoryClass != null) {
- aspectClassesBuilder.add(aspectFactoryClass);
+ for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
+ // For invoking top-level aspects, use the top-level configuration for both the
+ // aspect and the base target while the top-level configuration is untrimmed.
+ BuildConfiguration configuration = targetSpec.getConfiguration();
+ aspectConfigurations.put(Pair.of(targetSpec.getLabel(), aspect), configuration);
+ aspectKeys.add(
+ AspectValueKey.createAspectKey(
+ targetSpec.getLabel(),
+ configuration,
+ new AspectDescriptor(aspectFactoryClass, AspectParameters.EMPTY),
+ configuration));
+ }
} else {
String errorMessage = "Aspect '" + aspect + "' is unknown";
throw new ViewCreationFailedException(
@@ -330,25 +358,6 @@
}
}
- Multimap<Pair<Label, String>, BuildConfiguration> aspectConfigurations =
- ArrayListMultimap.create();
- ImmutableList<AspectClass> aspectClasses = aspectClassesBuilder.build();
- ImmutableList.Builder<TopLevelAspectsKey> aspectsKeys = ImmutableList.builder();
- for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
- BuildConfiguration configuration = targetSpec.getConfiguration();
- for (AspectClass aspectClass : aspectClasses) {
- aspectConfigurations.put(
- Pair.of(targetSpec.getLabel(), aspectClass.getName()), configuration);
- }
- // For invoking top-level aspects, use the top-level configuration for both the
- // aspect and the base target while the top-level configuration is untrimmed.
- if (!aspectClasses.isEmpty()) {
- aspectsKeys.add(
- AspectValueKey.createTopLevelAspectsKey(
- aspectClasses, targetSpec.getLabel(), configuration));
- }
- }
-
for (Pair<Label, String> target : aspectConfigurations.keys()) {
eventBus.post(
new AspectConfiguredEvent(
@@ -373,7 +382,7 @@
skyframeBuildView.configureTargets(
eventHandler,
topLevelCtKeys,
- aspectsKeys.build(),
+ aspectKeys,
Suppliers.memoize(configurationLookupSupplier),
topLevelOptions,
eventBus,
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java
index c35d8dd..5dcd758 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java
@@ -297,18 +297,11 @@
effectTags = {OptionEffectTag.UNKNOWN},
allowMultiple = true,
help =
- "Comma-separated list of aspects to be applied to top-level targets. All aspects are"
- + " applied to all top-level targets. If aspect <code>some_aspect</code> specifies"
- + " required aspect providers via <code>required_aspect_providers</code>,"
- + " <code>some_aspect</code> will run after every aspect that was mentioned before it"
- + " in the aspects list and whose advertised providers satisfy"
- + " <code>some_aspect</code> required aspect providers. <code>some_aspect</code> will"
- + " then have access to the values of those aspects' providers. Aspects that do not"
- + " have such dependency will run independently on the top-level targets."
- + ""
- + " Aspects are specified in the form <bzl-file-label>%<aspect_name>, for example"
- + " '//tools:my_def.bzl%my_aspect', where 'my_aspect' is a top-level value from a"
- + " file tools/my_def.bzl")
+ "Comma-separated list of aspects to be applied to top-level targets. All aspects "
+ + "are applied to all top-level targets independently. Aspects are specified in "
+ + "the form <bzl-file-label>%<aspect_name>, "
+ + "for example '//tools:my_def.bzl%my_aspect', where 'my_aspect' is a top-level "
+ + "value from from a file tools/my_def.bzl")
public List<String> aspects;
public BuildRequestOptions() throws OptionsParsingException {}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkAspectClass.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkAspectClass.java
index bf0b414..2b9f2a3 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkAspectClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkAspectClass.java
@@ -64,9 +64,4 @@
public int hashCode() {
return Objects.hash(extensionLabel, exportedName);
}
-
- @Override
- public String toString() {
- return getName();
- }
}
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 f97e08d..04c15bd 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
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -29,15 +30,29 @@
import com.google.devtools.build.skyframe.SkyFunctionName;
import javax.annotation.Nullable;
-/** A wrapper class for sky keys needed to compute sky values for aspects. */
-public final class AspectValueKey {
-
- private AspectValueKey() {}
+/** A base class for keys that have AspectValue as a Sky value. */
+public abstract class AspectValueKey implements ActionLookupKey {
private static final Interner<AspectKey> aspectKeyInterner = BlazeInterners.newWeakInterner();
- private static final Interner<TopLevelAspectsKey> topLevelAspectsKeyInterner =
+ private static final Interner<StarlarkAspectLoadingKey> starlarkAspectKeyInterner =
BlazeInterners.newWeakInterner();
+ /**
+ * Gets the name of the aspect that would be returned by the corresponding value's {@code
+ * aspectValue.getAspect().getAspectClass().getName()}, if the value could be produced.
+ *
+ * <p>Only needed for reporting errors in BEP when the key's AspectValue fails evaluation.
+ */
+ public abstract String getAspectName();
+
+ public abstract String getDescription();
+
+ @Nullable
+ abstract BuildConfigurationValue.Key getAspectConfigurationKey();
+
+ /** Returns the key for the base configured target for this aspect. */
+ public abstract ConfiguredTargetKey getBaseConfiguredTargetKey();
+
public static AspectKey createAspectKey(
Label label,
@Nullable BuildConfiguration baseConfiguration,
@@ -72,48 +87,33 @@
aspectConfiguration == null ? null : BuildConfigurationValue.key(aspectConfiguration));
}
- public static TopLevelAspectsKey createTopLevelAspectsKey(
- ImmutableList<AspectClass> topLevelAspectsClasses,
+ public static StarlarkAspectLoadingKey createStarlarkAspectKey(
Label targetLabel,
- @Nullable BuildConfiguration configuration) {
- return TopLevelAspectsKey.createInternal(
- topLevelAspectsClasses,
+ @Nullable BuildConfiguration aspectConfiguration,
+ @Nullable BuildConfiguration targetConfiguration,
+ Label starlarkFileLabel,
+ String starlarkExportName) {
+ return StarlarkAspectLoadingKey.createInternal(
targetLabel,
+ aspectConfiguration == null ? null : BuildConfigurationValue.key(aspectConfiguration),
ConfiguredTargetKey.builder()
.setLabel(targetLabel)
- .setConfiguration(configuration)
- .build());
- }
-
- /** Common superclass for {@link AspectKey} and {@link TopLevelAspectsKey}. */
- public abstract static class AspectBaseKey implements ActionLookupKey {
- private final ConfiguredTargetKey baseConfiguredTargetKey;
- private final int hashCode;
-
- private AspectBaseKey(ConfiguredTargetKey baseConfiguredTargetKey, int hashCode) {
- this.baseConfiguredTargetKey = baseConfiguredTargetKey;
- this.hashCode = hashCode;
- }
-
- /** Returns the key for the base configured target for this aspect. */
- public final ConfiguredTargetKey getBaseConfiguredTargetKey() {
- return baseConfiguredTargetKey;
- }
-
- @Override
- public final int hashCode() {
- return hashCode;
- }
+ .setConfiguration(targetConfiguration)
+ .build(),
+ starlarkFileLabel,
+ starlarkExportName);
}
// Specific subtypes of aspect keys.
/** Represents an aspect applied to a particular target. */
@AutoCodec
- public static final class AspectKey extends AspectBaseKey {
+ public static final class AspectKey extends AspectValueKey {
+ private final ConfiguredTargetKey baseConfiguredTargetKey;
private final ImmutableList<AspectKey> baseKeys;
@Nullable private final BuildConfigurationValue.Key aspectConfigurationKey;
private final AspectDescriptor aspectDescriptor;
+ private final int hashCode;
private AspectKey(
ConfiguredTargetKey baseConfiguredTargetKey,
@@ -121,10 +121,11 @@
AspectDescriptor aspectDescriptor,
@Nullable BuildConfigurationValue.Key aspectConfigurationKey,
int hashCode) {
- super(baseConfiguredTargetKey, hashCode);
this.baseKeys = baseKeys;
this.aspectConfigurationKey = aspectConfigurationKey;
+ this.baseConfiguredTargetKey = baseConfiguredTargetKey;
this.aspectDescriptor = aspectDescriptor;
+ this.hashCode = hashCode;
}
@AutoCodec.VisibleForSerialization
@@ -149,19 +150,14 @@
return SkyFunctions.ASPECT;
}
- /**
- * Gets the name of the aspect that would be returned by the corresponding value's {@code
- * aspectValue.getAspect().getAspectClass().getName()}, if the value could be produced.
- *
- * <p>Only needed for reporting errors in BEP when the key's AspectValue fails evaluation.
- */
+ @Override
public String getAspectName() {
return aspectDescriptor.getDescription();
}
@Override
public Label getLabel() {
- return getBaseConfiguredTargetKey().getLabel();
+ return baseConfiguredTargetKey.getLabel();
}
public AspectClass getAspectClass() {
@@ -191,9 +187,11 @@
return baseKeys;
}
+ @Override
public String getDescription() {
if (baseKeys.isEmpty()) {
- return String.format("%s of %s", aspectDescriptor.getAspectClass().getName(), getLabel());
+ return String.format("%s of %s",
+ aspectDescriptor.getAspectClass().getName(), getLabel());
} else {
return String.format(
"%s on top of %s", aspectDescriptor.getAspectClass().getName(), baseKeys);
@@ -218,10 +216,22 @@
* base target's configuration.
*/
@Nullable
+ @Override
BuildConfigurationValue.Key getAspectConfigurationKey() {
return aspectConfigurationKey;
}
+ /** Returns the key for the base configured target for this aspect. */
+ @Override
+ public ConfiguredTargetKey getBaseConfiguredTargetKey() {
+ return baseConfiguredTargetKey;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
@Override
public boolean equals(Object other) {
if (this == other) {
@@ -231,10 +241,10 @@
return false;
}
AspectKey that = (AspectKey) other;
- return hashCode() == that.hashCode()
+ return hashCode == that.hashCode
&& Objects.equal(baseKeys, that.baseKeys)
&& Objects.equal(aspectConfigurationKey, that.aspectConfigurationKey)
- && Objects.equal(getBaseConfiguredTargetKey(), that.getBaseConfiguredTargetKey())
+ && Objects.equal(baseConfiguredTargetKey, that.baseConfiguredTargetKey)
&& Objects.equal(aspectDescriptor, that.aspectDescriptor);
}
@@ -257,7 +267,7 @@
+ " "
+ aspectConfigurationKey
+ " "
- + getBaseConfiguredTargetKey()
+ + baseConfiguredTargetKey
+ " "
+ aspectDescriptor.getParameters();
}
@@ -271,7 +281,7 @@
return createAspectKey(
ConfiguredTargetKey.builder()
.setLabel(label)
- .setConfigurationKey(getBaseConfiguredTargetKey().getConfigurationKey())
+ .setConfigurationKey(baseConfiguredTargetKey.getConfigurationKey())
.build(),
newBaseKeys.build(),
aspectDescriptor,
@@ -279,43 +289,70 @@
}
}
- /** The key for top level aspects specified by --aspects option on a top level target. */
+ /** The key for a Starlark aspect. */
@AutoCodec
- public static final class TopLevelAspectsKey extends AspectBaseKey {
- private final ImmutableList<AspectClass> topLevelAspectsClasses;
+ public static final class StarlarkAspectLoadingKey extends AspectValueKey {
private final Label targetLabel;
+ private final BuildConfigurationValue.Key aspectConfigurationKey;
+ private final ConfiguredTargetKey baseConfiguredTargetKey;
+ private final Label starlarkFileLabel;
+ private final String starlarkValueName;
+ private final int hashCode;
@AutoCodec.Instantiator
@AutoCodec.VisibleForSerialization
- static TopLevelAspectsKey createInternal(
- ImmutableList<AspectClass> topLevelAspectsClasses,
+ static StarlarkAspectLoadingKey createInternal(
Label targetLabel,
- ConfiguredTargetKey baseConfiguredTargetKey) {
- return topLevelAspectsKeyInterner.intern(
- new TopLevelAspectsKey(
- topLevelAspectsClasses,
+ BuildConfigurationValue.Key aspectConfigurationKey,
+ ConfiguredTargetKey baseConfiguredTargetKey,
+ Label starlarkFileLabel,
+ String starlarkValueName) {
+ return starlarkAspectKeyInterner.intern(
+ new StarlarkAspectLoadingKey(
targetLabel,
+ aspectConfigurationKey,
baseConfiguredTargetKey,
- Objects.hashCode(topLevelAspectsClasses, targetLabel, baseConfiguredTargetKey)));
+ starlarkFileLabel,
+ starlarkValueName,
+ Objects.hashCode(
+ targetLabel,
+ aspectConfigurationKey,
+ baseConfiguredTargetKey,
+ starlarkFileLabel,
+ starlarkValueName)));
}
- private TopLevelAspectsKey(
- ImmutableList<AspectClass> topLevelAspectsClasses,
+ private StarlarkAspectLoadingKey(
Label targetLabel,
+ BuildConfigurationValue.Key aspectConfigurationKey,
ConfiguredTargetKey baseConfiguredTargetKey,
+ Label starlarkFileLabel,
+ String starlarkValueName,
int hashCode) {
- super(baseConfiguredTargetKey, hashCode);
- this.topLevelAspectsClasses = topLevelAspectsClasses;
this.targetLabel = targetLabel;
+ this.aspectConfigurationKey = aspectConfigurationKey;
+ this.baseConfiguredTargetKey = baseConfiguredTargetKey;
+ this.starlarkFileLabel = starlarkFileLabel;
+ this.starlarkValueName = starlarkValueName;
+ this.hashCode = hashCode;
}
@Override
public SkyFunctionName functionName() {
- return SkyFunctions.TOP_LEVEL_ASPECTS;
+ return SkyFunctions.LOAD_STARLARK_ASPECT;
}
- ImmutableList<AspectClass> getTopLevelAspectsClasses() {
- return topLevelAspectsClasses;
+ String getStarlarkValueName() {
+ return starlarkValueName;
+ }
+
+ Label getStarlarkFileLabel() {
+ return starlarkFileLabel;
+ }
+
+ @Override
+ public String getAspectName() {
+ return String.format("%s%%%s", starlarkFileLabel, starlarkValueName);
}
@Override
@@ -323,8 +360,27 @@
return targetLabel;
}
- String getDescription() {
- return topLevelAspectsClasses + " on " + getLabel();
+ @Override
+ public String getDescription() {
+ // Starlark aspects are referred to on command line with <file>%<value ame>
+ return String.format("%s%%%s of %s", starlarkFileLabel, starlarkValueName, targetLabel);
+ }
+
+ @Nullable
+ @Override
+ BuildConfigurationValue.Key getAspectConfigurationKey() {
+ return aspectConfigurationKey;
+ }
+
+ /** Returns the key for the base configured target for this aspect. */
+ @Override
+ public ConfiguredTargetKey getBaseConfiguredTargetKey() {
+ return baseConfiguredTargetKey;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
}
@Override
@@ -332,14 +388,35 @@
if (o == this) {
return true;
}
- if (!(o instanceof TopLevelAspectsKey)) {
+ if (!(o instanceof StarlarkAspectLoadingKey)) {
return false;
}
- TopLevelAspectsKey that = (TopLevelAspectsKey) o;
- return hashCode() == that.hashCode()
+ StarlarkAspectLoadingKey that = (StarlarkAspectLoadingKey) o;
+ return hashCode == that.hashCode
&& Objects.equal(targetLabel, that.targetLabel)
- && Objects.equal(getBaseConfiguredTargetKey(), that.getBaseConfiguredTargetKey())
- && Objects.equal(topLevelAspectsClasses, that.topLevelAspectsClasses);
+ && Objects.equal(aspectConfigurationKey, that.aspectConfigurationKey)
+ && Objects.equal(baseConfiguredTargetKey, that.baseConfiguredTargetKey)
+ && Objects.equal(starlarkFileLabel, that.starlarkFileLabel)
+ && Objects.equal(starlarkValueName, that.starlarkValueName);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("targetLabel", targetLabel)
+ .add("aspectConfigurationKey", aspectConfigurationKey)
+ .add("baseConfiguredTargetKey", baseConfiguredTargetKey)
+ .add("starlarkFileLabel", starlarkFileLabel)
+ .add("starlarkValueName", starlarkValueName)
+ .toString();
+ }
+
+ AspectKey toAspectKey(AspectClass aspectClass) {
+ return AspectKey.createAspectKey(
+ baseConfiguredTargetKey,
+ ImmutableList.of(),
+ new AspectDescriptor(aspectClass, AspectParameters.EMPTY),
+ aspectConfigurationKey);
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
index 9e9a99a..15222d2 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -38,7 +38,6 @@
"ExternalFilesHelper.java",
"ExternalPackageFunction.java",
"FileStateFunction.java",
- "LoadStarlarkAspectFunction.java",
"LocalRepositoryLookupFunction.java",
"NonRuleConfiguredTargetValue.java",
"PackageFunction.java",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/LoadStarlarkAspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/LoadStarlarkAspectFunction.java
deleted file mode 100644
index 4d81910..0000000
--- a/src/main/java/com/google/devtools/build/lib/skyframe/LoadStarlarkAspectFunction.java
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2021 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.skyframe;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.Interner;
-import com.google.devtools.build.lib.causes.LabelCause;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.concurrent.BlazeInterners;
-import com.google.devtools.build.lib.packages.StarlarkAspect;
-import com.google.devtools.build.lib.packages.StarlarkAspectClass;
-import com.google.devtools.build.lib.server.FailureDetails.Analysis;
-import com.google.devtools.build.lib.server.FailureDetails.Analysis.Code;
-import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
-import com.google.devtools.build.lib.util.DetailedExitCode;
-import com.google.devtools.build.skyframe.SkyFunction;
-import com.google.devtools.build.skyframe.SkyFunctionException;
-import com.google.devtools.build.skyframe.SkyFunctionName;
-import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.SkyValue;
-import javax.annotation.Nullable;
-
-/**
- * SkyFunction to load aspects from Starlark extensions and return StarlarkAspect.
- *
- * <p>Used for loading top-level aspects. At top level, in {@link
- * com.google.devtools.build.lib.analysis.BuildView}, we cannot invoke two SkyFunctions one after
- * another, so BuildView calls this function to do the work.
- */
-public class LoadStarlarkAspectFunction implements SkyFunction {
- private static final Interner<StarlarkAspectLoadingKey> starlarkAspectLoadingKeyInterner =
- BlazeInterners.newWeakInterner();
-
- LoadStarlarkAspectFunction() {}
-
- @Nullable
- @Override
- public SkyValue compute(SkyKey skyKey, Environment env)
- throws LoadStarlarkAspectFunctionException, InterruptedException {
- StarlarkAspectLoadingKey aspectLoadingKey = (StarlarkAspectLoadingKey) skyKey.argument();
-
- Label extensionLabel = aspectLoadingKey.getAspectClass().getExtensionLabel();
- String exportedName = aspectLoadingKey.getAspectClass().getExportedName();
- StarlarkAspect starlarkAspect;
- try {
- starlarkAspect = AspectFunction.loadStarlarkAspect(env, extensionLabel, exportedName);
- if (starlarkAspect == null) {
- return null;
- }
- if (!starlarkAspect.getParamAttributes().isEmpty()) {
- String msg =
- String.format(
- "Cannot instantiate parameterized aspect %s at the top level.",
- starlarkAspect.getName());
- throw new AspectCreationException(
- msg,
- new LabelCause(
- extensionLabel,
- createDetailedCode(msg, Code.PARAMETERIZED_TOP_LEVEL_ASPECT_INVALID)));
- }
- } catch (AspectCreationException e) {
- throw new LoadStarlarkAspectFunctionException(e);
- }
-
- return new StarlarkAspectLoadingValue(starlarkAspect);
- }
-
- @Nullable
- @Override
- public String extractTag(SkyKey skyKey) {
- return null;
- }
-
- private static DetailedExitCode createDetailedCode(String msg, Code code) {
- return DetailedExitCode.of(
- FailureDetail.newBuilder()
- .setMessage(msg)
- .setAnalysis(Analysis.newBuilder().setCode(code))
- .build());
- }
-
- /** Exceptions thrown from LoadStarlarkAspectFunction. */
- public static class LoadStarlarkAspectFunctionException extends SkyFunctionException {
- public LoadStarlarkAspectFunctionException(AspectCreationException cause) {
- super(cause, Transience.PERSISTENT);
- }
- }
-
- public static StarlarkAspectLoadingKey createStarlarkAspectLoadingKey(
- StarlarkAspectClass aspectClass) {
- return StarlarkAspectLoadingKey.createInternal(aspectClass);
- }
-
- /** Skykey for loading Starlark aspect. */
- @AutoCodec
- public static final class StarlarkAspectLoadingKey implements SkyKey {
- private final StarlarkAspectClass aspectClass;
- private final int hashCode;
-
- @AutoCodec.Instantiator
- @AutoCodec.VisibleForSerialization
- static StarlarkAspectLoadingKey createInternal(StarlarkAspectClass aspectClass) {
- return starlarkAspectLoadingKeyInterner.intern(
- new StarlarkAspectLoadingKey(aspectClass, java.util.Objects.hashCode(aspectClass)));
- }
-
- private StarlarkAspectLoadingKey(StarlarkAspectClass aspectClass, int hashCode) {
- this.aspectClass = aspectClass;
- this.hashCode = hashCode;
- }
-
- @Override
- public SkyFunctionName functionName() {
- return SkyFunctions.LOAD_STARLARK_ASPECT;
- }
-
- StarlarkAspectClass getAspectClass() {
- return aspectClass;
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof StarlarkAspectLoadingKey)) {
- return false;
- }
- StarlarkAspectLoadingKey that = (StarlarkAspectLoadingKey) o;
- return hashCode == that.hashCode && Objects.equal(aspectClass, that.aspectClass);
- }
-
- @Override
- public String toString() {
- return aspectClass.toString();
- }
- }
-
- /** SkyValue for {@code StarlarkAspectLoadingKey} holds the loaded {@code StarlarkAspect}. */
- public static class StarlarkAspectLoadingValue implements SkyValue {
- private final StarlarkAspect starlarkAspect;
-
- public StarlarkAspectLoadingValue(StarlarkAspect starlarkAspect) {
- this.starlarkAspect = starlarkAspect;
- }
-
- public StarlarkAspect getAspect() {
- return starlarkAspect;
- }
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
index 46443e4..cb07796 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -88,8 +88,6 @@
public static final SkyFunctionName ASPECT = SkyFunctionName.createHermetic("ASPECT");
static final SkyFunctionName LOAD_STARLARK_ASPECT =
SkyFunctionName.createHermetic("LOAD_STARLARK_ASPECT");
- static final SkyFunctionName TOP_LEVEL_ASPECTS =
- SkyFunctionName.createHermetic("TOP_LEVEL_ASPECTS");
public static final SkyFunctionName TARGET_COMPLETION =
SkyFunctionName.create(
"TARGET_COMPLETION", ShareabilityOfValue.NEVER, FunctionHermeticity.HERMETIC);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
index 792dc66..c718762 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
@@ -88,9 +88,7 @@
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.skyframe.ArtifactConflictFinder.ConflictException;
import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
-import com.google.devtools.build.lib.skyframe.AspectValueKey.TopLevelAspectsKey;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor.TopLevelActionConflictReport;
-import com.google.devtools.build.lib.skyframe.ToplevelStarlarkAspectFunction.TopLevelAspectsValue;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
import com.google.devtools.build.lib.util.Pair;
@@ -382,7 +380,7 @@
public SkyframeAnalysisResult configureTargets(
ExtendedEventHandler eventHandler,
List<ConfiguredTargetKey> ctKeys,
- ImmutableList<TopLevelAspectsKey> topLevelAspectsKey,
+ List<AspectValueKey> aspectKeys,
Supplier<Map<BuildConfigurationValue.Key, BuildConfiguration>> configurationLookupSupplier,
TopLevelArtifactContext topLevelArtifactContextForConflictPruning,
EventBus eventBus,
@@ -399,7 +397,7 @@
skyframeExecutor.configureTargets(
eventHandler,
ctKeys,
- topLevelAspectsKey,
+ aspectKeys,
keepGoing,
numThreads,
cpuHeavySkyKeysThreadPoolSize);
@@ -407,33 +405,21 @@
enableAnalysis(false);
}
- int numOfAspects = 0;
- if (!topLevelAspectsKey.isEmpty()) {
- numOfAspects =
- topLevelAspectsKey.size() * topLevelAspectsKey.get(0).getTopLevelAspectsClasses().size();
- }
- Map<AspectKey, ConfiguredAspect> aspects = Maps.newHashMapWithExpectedSize(numOfAspects);
+ Map<AspectKey, ConfiguredAspect> aspects = Maps.newHashMapWithExpectedSize(aspectKeys.size());
Root singleSourceRoot = skyframeExecutor.getForcedSingleSourceRootIfNoExecrootSymlinkCreation();
NestedSetBuilder<Package> packages =
singleSourceRoot == null ? NestedSetBuilder.stableOrder() : null;
- ImmutableList.Builder<AspectKey> aspectKeysBuilder = ImmutableList.builder();
-
- for (TopLevelAspectsKey key : topLevelAspectsKey) {
- TopLevelAspectsValue value = (TopLevelAspectsValue) result.get(key);
+ for (AspectValueKey aspectKey : aspectKeys) {
+ AspectValue value = (AspectValue) result.get(aspectKey);
if (value == null) {
// Skip aspects that couldn't be applied to targets.
continue;
}
- for (SkyValue val : value.getTopLevelAspectsValues()) {
- AspectValue aspectValue = (AspectValue) val;
- aspects.put(aspectValue.getKey(), aspectValue.getConfiguredAspect());
- if (packages != null) {
- packages.addTransitive(aspectValue.getTransitivePackagesForPackageRootResolution());
- }
- aspectKeysBuilder.add(aspectValue.getKey());
+ aspects.put(value.getKey(), value.getConfiguredAspect());
+ if (packages != null) {
+ packages.addTransitive(value.getTransitivePackagesForPackageRootResolution());
}
}
- ImmutableList<AspectKey> aspectKeys = aspectKeysBuilder.build();
Collection<ConfiguredTarget> cts = Lists.newArrayListWithCapacity(ctKeys.size());
for (ConfiguredTargetKey value : ctKeys) {
@@ -575,7 +561,7 @@
BuildConfigurationValue.Key configKey =
ctKey instanceof ConfiguredTargetKey
? ((ConfiguredTargetKey) ctKey).getConfigurationKey()
- : ((AspectKey) ctKey).getAspectConfigurationKey();
+ : ((AspectValueKey) ctKey).getAspectConfigurationKey();
eventBus.post(
new AnalysisFailureEvent(
ctKey,
@@ -611,9 +597,13 @@
.collect(toImmutableList());
aspects =
- aspects.entrySet().stream()
- .filter(e -> topLevelActionConflictReport.isErrorFree(e.getKey()))
- .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
+ aspectKeys.stream()
+ .filter(topLevelActionConflictReport::isErrorFree)
+ .map(result::get)
+ .map(AspectValue.class::cast)
+ .collect(
+ ImmutableMap.toImmutableMap(
+ AspectValue::getKey, AspectValue::getConfiguredAspect));
}
return new SkyframeAnalysisResult(
@@ -755,15 +745,17 @@
.reportCycles(errorInfo.getCycleInfo(), errorKey, eventHandler);
Exception cause = errorInfo.getException();
Preconditions.checkState(cause != null || !errorInfo.getCycleInfo().isEmpty(), errorInfo);
- if (errorKey.argument() instanceof TopLevelAspectsKey) {
+
+ if (errorKey.argument() instanceof AspectValueKey) {
// We skip Aspects in the keepGoing case; the failures should already have been reported to
// the event handler.
if (!keepGoing && noKeepGoingException == null) {
- TopLevelAspectsKey aspectKey = (TopLevelAspectsKey) errorKey.argument();
+ AspectValueKey aspectKey = (AspectValueKey) errorKey.argument();
failedAspectLabel = aspectKey.getBaseConfiguredTargetKey();
+
String errorMsg =
String.format(
- "Analysis of aspects '%s' failed; build aborted", aspectKey.getDescription());
+ "Analysis of aspect '%s' failed; build aborted", aspectKey.getDescription());
noKeepGoingException = createViewCreationFailedException(cause, errorMsg);
}
continue;
@@ -784,7 +776,7 @@
}
Preconditions.checkState(
errorKey.argument() instanceof ConfiguredTargetKey,
- "expected '%s' to be a TopLevelAspectsKey or ConfiguredTargetKey",
+ "expected '%s' to be a AspectValueKey or ConfiguredTargetKey",
errorKey.argument());
ConfiguredTargetKey label = (ConfiguredTargetKey) errorKey.argument();
Label topLevelLabel = label.getLabel();
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 780cdce..af7eb27 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -162,7 +162,6 @@
import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns;
import com.google.devtools.build.lib.skyframe.ArtifactConflictFinder.ConflictException;
import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
-import com.google.devtools.build.lib.skyframe.AspectValueKey.TopLevelAspectsKey;
import com.google.devtools.build.lib.skyframe.DirtinessCheckerUtils.FileDirtinessChecker;
import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
import com.google.devtools.build.lib.skyframe.MetadataConsumerForMetrics.FilesMetricConsumer;
@@ -575,8 +574,7 @@
new BuildViewProvider(),
ruleClassProvider,
shouldStoreTransitivePackagesInLoadingAndAnalysis()));
- map.put(SkyFunctions.LOAD_STARLARK_ASPECT, new LoadStarlarkAspectFunction());
- map.put(SkyFunctions.TOP_LEVEL_ASPECTS, new ToplevelStarlarkAspectFunction());
+ map.put(SkyFunctions.LOAD_STARLARK_ASPECT, new ToplevelStarlarkAspectFunction());
map.put(SkyFunctions.ACTION_LOOKUP_CONFLICT_FINDING, new ActionLookupConflictFindingFunction());
map.put(
SkyFunctions.TOP_LEVEL_ACTION_LOOKUP_CONFLICT_FINDING,
@@ -2334,7 +2332,7 @@
EvaluationResult<ActionLookupValue> configureTargets(
ExtendedEventHandler eventHandler,
List<ConfiguredTargetKey> values,
- ImmutableList<TopLevelAspectsKey> aspectKeys,
+ List<AspectValueKey> aspectKeys,
boolean keepGoing,
int numThreads,
int cpuHeavySkyKeysThreadPoolSize)
@@ -3071,7 +3069,7 @@
}
final AnalysisTraversalResult getActionLookupValuesInBuild(
- List<ConfiguredTargetKey> topLevelCtKeys, ImmutableList<AspectKey> aspectKeys)
+ List<ConfiguredTargetKey> topLevelCtKeys, List<AspectValueKey> aspectKeys)
throws InterruptedException {
AnalysisTraversalResult result = new AnalysisTraversalResult();
if (!isAnalysisIncremental()) {
@@ -3091,7 +3089,7 @@
for (ConfiguredTargetKey key : topLevelCtKeys) {
findActionsRecursively(walkableGraph, key, seen, result);
}
- for (AspectKey key : aspectKeys) {
+ for (AspectValueKey key : aspectKeys) {
findActionsRecursively(walkableGraph, key, seen, result);
}
return result;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetCycleReporter.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetCycleReporter.java
index 693bde7..cf8f828 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetCycleReporter.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetCycleReporter.java
@@ -39,7 +39,7 @@
Predicates.or(
SkyFunctions.isSkyFunction(SkyFunctions.CONFIGURED_TARGET),
SkyFunctions.isSkyFunction(SkyFunctions.ASPECT),
- SkyFunctions.isSkyFunction(SkyFunctions.TOP_LEVEL_ASPECTS),
+ SkyFunctions.isSkyFunction(SkyFunctions.LOAD_STARLARK_ASPECT),
SkyFunctions.isSkyFunction(TransitiveTargetKey.NAME),
SkyFunctions.isSkyFunction(SkyFunctions.PREPARE_ANALYSIS_PHASE));
@@ -65,6 +65,8 @@
return ((ConfiguredTargetKey) key.argument()).prettyPrint();
} else if (key instanceof AspectKey) {
return ((AspectKey) key.argument()).prettyPrint();
+ } else if (key instanceof AspectValueKey) {
+ return ((AspectValueKey) key).getDescription();
} else {
return getLabel(key).toString();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelStarlarkAspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelStarlarkAspectFunction.java
index 5638d8e..a858e35 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelStarlarkAspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelStarlarkAspectFunction.java
@@ -14,36 +14,22 @@
package com.google.devtools.build.lib.skyframe;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
-import com.google.devtools.build.lib.actions.ActionLookupValue;
-import com.google.devtools.build.lib.analysis.AspectCollection;
-import com.google.devtools.build.lib.analysis.AspectCollection.AspectCycleOnPathException;
-import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.packages.Aspect;
-import com.google.devtools.build.lib.packages.AspectClass;
-import com.google.devtools.build.lib.packages.AspectDescriptor;
-import com.google.devtools.build.lib.packages.AspectsListBuilder;
-import com.google.devtools.build.lib.packages.NativeAspectClass;
+import com.google.devtools.build.lib.causes.LabelCause;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.StarlarkAspect;
-import com.google.devtools.build.lib.packages.StarlarkAspectClass;
-import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
-import com.google.devtools.build.lib.skyframe.AspectValueKey.TopLevelAspectsKey;
-import com.google.devtools.build.lib.skyframe.LoadStarlarkAspectFunction.StarlarkAspectLoadingKey;
-import com.google.devtools.build.lib.skyframe.LoadStarlarkAspectFunction.StarlarkAspectLoadingValue;
+import com.google.devtools.build.lib.server.FailureDetails.Analysis;
+import com.google.devtools.build.lib.server.FailureDetails.Analysis.Code;
+import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
+import com.google.devtools.build.lib.skyframe.AspectValueKey.StarlarkAspectLoadingKey;
+import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
-import java.util.HashMap;
-import java.util.Map;
import javax.annotation.Nullable;
-import net.starlark.java.eval.EvalException;
/**
- * SkyFunction to load top level aspects, build the dependency relation between them based on the
- * providers they advertise and provide using {@link AspectCollection} and runs the obtained aspects
- * path on the top level target.
+ * SkyFunction to load aspects from Starlark extensions and calculate their values.
*
* <p>Used for loading top-level aspects. At top level, in {@link
* com.google.devtools.build.lib.analysis.BuildView}, we cannot invoke two SkyFunctions one after
@@ -55,40 +41,34 @@
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env)
- throws TopLevelStarlarkAspectFunctionException, InterruptedException {
- TopLevelAspectsKey topLevelAspectsKey = (TopLevelAspectsKey) skyKey.argument();
+ throws LoadStarlarkAspectFunctionException, InterruptedException {
+ StarlarkAspectLoadingKey aspectLoadingKey = (StarlarkAspectLoadingKey) skyKey.argument();
+ String starlarkValueName = aspectLoadingKey.getStarlarkValueName();
+ Label starlarkFileLabel = aspectLoadingKey.getStarlarkFileLabel();
- ImmutableList<Aspect> topLevelAspects;
+ StarlarkAspect starlarkAspect;
try {
- topLevelAspects = getTopLevelAspects(env, topLevelAspectsKey.getTopLevelAspectsClasses());
- } catch (EvalException e) {
- env.getListener().handle(Event.error(e.getMessage()));
- throw new TopLevelStarlarkAspectFunctionException(
- new AspectCreationException(e.getMessage(), topLevelAspectsKey.getLabel()));
+ starlarkAspect = AspectFunction.loadStarlarkAspect(env, starlarkFileLabel, starlarkValueName);
+ if (starlarkAspect == null) {
+ return null;
+ }
+ if (!starlarkAspect.getParamAttributes().isEmpty()) {
+ String msg =
+ String.format(
+ "Cannot instantiate parameterized aspect %s at the top level.",
+ starlarkAspect.getName());
+ throw new AspectCreationException(
+ msg,
+ new LabelCause(
+ starlarkFileLabel,
+ createDetailedCode(msg, Code.PARAMETERIZED_TOP_LEVEL_ASPECT_INVALID)));
+ }
+ } catch (AspectCreationException e) {
+ throw new LoadStarlarkAspectFunctionException(e);
}
+ SkyKey aspectKey = aspectLoadingKey.toAspectKey(starlarkAspect.getAspectClass());
- if (topLevelAspects == null) {
- return null; // some aspects are not loaded
- }
-
- AspectCollection aspectCollection;
- try {
- aspectCollection = AspectCollection.create(topLevelAspects);
- } catch (AspectCycleOnPathException e) {
- env.getListener().handle(Event.error(e.getMessage()));
- throw new TopLevelStarlarkAspectFunctionException(
- new AspectCreationException(e.getMessage(), topLevelAspectsKey.getLabel()));
- }
-
- ImmutableList<AspectKey> aspectKeys =
- getTopLevelAspectsKeys(aspectCollection, topLevelAspectsKey.getBaseConfiguredTargetKey());
-
- Map<SkyKey, SkyValue> result = env.getValues(aspectKeys);
- if (env.valuesMissing()) {
- return null; // some aspects keys are not evaluated
- }
-
- return new TopLevelAspectsValue(result);
+ return env.getValue(aspectKey);
}
@Nullable
@@ -97,112 +77,18 @@
return null;
}
- @Nullable
- private static ImmutableList<Aspect> getTopLevelAspects(
- Environment env, ImmutableList<AspectClass> topLevelAspectsClasses)
- throws InterruptedException, EvalException {
- AspectsListBuilder aspectsList = new AspectsListBuilder();
-
- ImmutableList.Builder<StarlarkAspectLoadingKey> aspectLoadingKeys = ImmutableList.builder();
- for (AspectClass aspectClass : topLevelAspectsClasses) {
- if (aspectClass instanceof StarlarkAspectClass) {
- aspectLoadingKeys.add(
- LoadStarlarkAspectFunction.createStarlarkAspectLoadingKey(
- (StarlarkAspectClass) aspectClass));
- }
- }
-
- Map<SkyKey, SkyValue> loadedAspects = env.getValues(aspectLoadingKeys.build());
- if (env.valuesMissing()) {
- return null;
- }
-
- for (AspectClass aspectClass : topLevelAspectsClasses) {
- if (aspectClass instanceof StarlarkAspectClass) {
- StarlarkAspectLoadingValue aspectLoadingValue =
- (StarlarkAspectLoadingValue)
- loadedAspects.get(
- LoadStarlarkAspectFunction.createStarlarkAspectLoadingKey(
- (StarlarkAspectClass) aspectClass));
- StarlarkAspect starlarkAspect = aspectLoadingValue.getAspect();
- starlarkAspect.attachToAspectsList(
- /** baseAspectName= */
- null,
- aspectsList,
- /** inheritedRequiredProviders= */
- ImmutableList.of(),
- /** inheritedAttributeAspects= */
- ImmutableList.of());
- } else {
- aspectsList.addAspect((NativeAspectClass) aspectClass);
- }
- }
-
- return aspectsList.buildAspects();
- }
-
- private static ImmutableList<AspectKey> getTopLevelAspectsKeys(
- AspectCollection aspectCollection, ConfiguredTargetKey topLevelTargetKey) {
- Map<AspectDescriptor, AspectKey> result = new HashMap<>();
- for (AspectCollection.AspectDeps aspectDeps : aspectCollection.getUsedAspects()) {
- buildAspectKey(aspectDeps, result, topLevelTargetKey);
- }
- return ImmutableList.copyOf(result.values());
- }
-
- private static AspectKey buildAspectKey(
- AspectCollection.AspectDeps aspectDeps,
- Map<AspectDescriptor, AspectKey> result,
- ConfiguredTargetKey topLevelTargetKey) {
- if (result.containsKey(aspectDeps.getAspect())) {
- return result.get(aspectDeps.getAspect());
- }
-
- ImmutableList.Builder<AspectKey> dependentAspects = ImmutableList.builder();
- for (AspectCollection.AspectDeps path : aspectDeps.getUsedAspects()) {
- dependentAspects.add(buildAspectKey(path, result, topLevelTargetKey));
- }
-
- AspectKey aspectKey =
- AspectValueKey.createAspectKey(
- aspectDeps.getAspect(),
- dependentAspects.build(),
- topLevelTargetKey.getConfigurationKey(),
- topLevelTargetKey);
- result.put(aspectKey.getAspectDescriptor(), aspectKey);
- return aspectKey;
+ private static DetailedExitCode createDetailedCode(String msg, Code code) {
+ return DetailedExitCode.of(
+ FailureDetail.newBuilder()
+ .setMessage(msg)
+ .setAnalysis(Analysis.newBuilder().setCode(code))
+ .build());
}
/** Exceptions thrown from ToplevelStarlarkAspectFunction. */
- public static class TopLevelStarlarkAspectFunctionException extends SkyFunctionException {
- public TopLevelStarlarkAspectFunctionException(AspectCreationException cause) {
+ public static class LoadStarlarkAspectFunctionException extends SkyFunctionException {
+ public LoadStarlarkAspectFunctionException(AspectCreationException cause) {
super(cause, Transience.PERSISTENT);
}
}
-
- /**
- * SkyValue for {@code TopLevelAspectsKey} wraps a list of the {@code AspectValue} of the top
- * level aspects applied on the same top level target.
- */
- public static class TopLevelAspectsValue implements ActionLookupValue {
- private final Map<SkyKey, SkyValue> topLevelAspectsMap;
-
- public TopLevelAspectsValue(Map<SkyKey, SkyValue> topLevelAspectsMap) {
- this.topLevelAspectsMap = topLevelAspectsMap;
- }
-
- public ImmutableList<SkyValue> getTopLevelAspectsValues() {
- return ImmutableList.copyOf(topLevelAspectsMap.values());
- }
-
- public SkyValue get(SkyKey skyKey) {
- return topLevelAspectsMap.get(skyKey);
- }
-
- @Override
- public ImmutableList<ActionAnalysisMetadata> getActions() {
- // return topLevelAspectsMap.values().stream().
- return ImmutableList.of();
- }
- }
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
index e6e5929..e39c708 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
@@ -875,25 +875,20 @@
}
@Test
- public void duplicateAspectsFailed() throws Exception {
+ public void duplicateAspectsDeduped() throws Exception {
AspectApplyingToFiles aspectApplyingToFiles = new AspectApplyingToFiles();
setRulesAndAspectsAvailableInTests(ImmutableList.of(aspectApplyingToFiles), ImmutableList.of());
pkg("a", "java_binary(name = 'x', main_class = 'x.FooBar', srcs = ['x.java'])");
- reporter.removeHandler(failFastHandler);
- AssertionError exception =
- assertThrows(
- AssertionError.class,
- () ->
- update(
- new EventBus(),
- defaultFlags(),
- ImmutableList.of(
- aspectApplyingToFiles.getName(), aspectApplyingToFiles.getName()),
- "//a:x_deploy.jar"));
-
- assertThat(exception)
- .hasMessageThat()
- .containsMatch("Aspect AspectApplyingToFiles has already been added");
+ AnalysisResult analysisResult =
+ update(
+ new EventBus(),
+ defaultFlags(),
+ ImmutableList.of(aspectApplyingToFiles.getName(), aspectApplyingToFiles.getName()),
+ "//a:x_deploy.jar");
+ ConfiguredAspect aspect = Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
+ AspectApplyingToFiles.Provider provider =
+ aspect.getProvider(AspectApplyingToFiles.Provider.class);
+ assertThat(provider.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//a:x_deploy.jar"));
}
@Test
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TargetCycleReporterTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TargetCycleReporterTest.java
index f491bea..17ec740 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TargetCycleReporterTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TargetCycleReporterTest.java
@@ -18,7 +18,6 @@
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.StarlarkAspectClass;
import com.google.devtools.build.skyframe.CycleInfo;
import com.google.devtools.build.skyframe.SkyKey;
import org.junit.Test;
@@ -71,12 +70,12 @@
+ "target //foo:c");
SkyKey starlarkAspectKey =
- AspectValueKey.createTopLevelAspectsKey(
- ImmutableList.of(
- new StarlarkAspectClass(
- Label.parseAbsoluteUnchecked("//foo:b"), "my Starlark key")),
+ AspectValueKey.createStarlarkAspectKey(
Label.parseAbsoluteUnchecked("//foo:a"),
- targetConfig);
+ targetConfig,
+ targetConfig,
+ Label.parseAbsoluteUnchecked("//foo:b"),
+ "my Starlark key");
assertThat(cycleReporter.getAdditionalMessageAboutCycle(reporter, starlarkAspectKey, cycle))
.contains(
"The cycle is caused by a visibility edge from //foo:b to the non-package_group "
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 375e8a8..e74bb4d 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
@@ -40,7 +40,6 @@
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.AspectDefinition;
-import com.google.devtools.build.lib.packages.StarlarkAspectClass;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
@@ -53,7 +52,6 @@
import com.google.devtools.build.lib.vfs.Path;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkInt;
@@ -4197,1287 +4195,6 @@
assertThat(aspectBResult).isEqualTo("aspect_b on target //test:dep_target cannot find prov_b");
}
- /**
- * --aspects = a3, a2, a1: aspect a1 requires provider a1p, aspect a2 requires provider a2p and
- * provides a1p and aspect a3 provides a2p. The three aspects will propagate together but aspect
- * a1 will only see a1p and aspect a2 will only see a2p.
- */
- @Test
- public void testTopLevelAspectOnAspect_stackOfAspects() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a1p = provider()",
- "a2p = provider()",
- "a1_result = provider()",
- "a2_result = provider()",
- "a3_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " if a2p in target:",
- " result += ' and sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' and cannot see a2p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a1_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['dep'],",
- " required_aspect_providers = [a1p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " result = 'aspect a2 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " if a2p in target:",
- " result += ' and sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' and cannot see a2p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a2_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a2_result(value = complete_result), a1p(value = 'a1p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a1p],",
- " required_aspect_providers = [a2p],",
- ")",
- "",
- "def _a3_impl(target, ctx):",
- " result = 'aspect a3 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " if a2p in target:",
- " result += ' and sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' and cannot see a2p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a3_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a3_result(value = complete_result), a2p(value = 'a2p_val')]",
- "a3 = aspect(",
- " implementation = _a3_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a2p],",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'dep': attr.label(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " dep = ':dep_target',",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
- "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a3 = getConfiguredAspect(configuredAspects, "a3");
- assertThat(a3).isNotNull();
- StarlarkProvider.Key a3Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a3_result");
- StructImpl a3ResultProvider = (StructImpl) a3.get(a3Result);
- assertThat((Sequence<?>) a3ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a3 on target //test:dep_target cannot see a1p and cannot see a2p",
- "aspect a3 on target //test:main cannot see a1p and cannot see a2p");
-
- ConfiguredAspect a2 = getConfiguredAspect(configuredAspects, "a2");
- assertThat(a2).isNotNull();
- StarlarkProvider.Key a2Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a2_result");
- StructImpl a2ResultProvider = (StructImpl) a2.get(a2Result);
- assertThat((Sequence<?>) a2ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a2 on target //test:dep_target cannot see a1p and sees a2p = a2p_val",
- "aspect a2 on target //test:main cannot see a1p and sees a2p = a2p_val");
-
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target sees a1p = a1p_val and cannot see a2p",
- "aspect a1 on target //test:main sees a1p = a1p_val and cannot see a2p");
- }
-
- /**
- * --aspects = a3, a2, a1: aspect a1 requires provider a1p, aspect a2 and aspect a3 provides a1p.
- * This should fail because provider a1p is provided twice.
- */
- @Test
- public void testTopLevelAspectOnAspect_requiredProviderProvidedTwiceFailed() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a1p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a1_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['dep'],",
- " required_aspect_providers = [a1p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a1p(value = 'a1p_a2_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a1p],",
- ")",
- "",
- "def _a3_impl(target, ctx):",
- " return [a1p(value = 'a1p_a3_val')]",
- "a3 = aspect(",
- " implementation = _a3_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a1p],",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'dep': attr.label(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " dep = ':dep_target',",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
- reporter.removeHandler(failFastHandler);
-
- // 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(
- ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
- "//test:main");
- assertThat(result.hasError()).isTrue();
- } else {
- assertThrows(
- ViewCreationFailedException.class,
- () ->
- update(
- ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
- "//test:main"));
- }
- assertContainsEvent("ERROR /workspace/test/BUILD:2:12: Provider a1p provided twice");
- }
-
- /**
- * --aspects = a3, a1, a2: aspect a1 requires provider a1p, aspect a2 and aspect a3 provide a1p.
- * a1 should see the value provided by a3 because a3 is listed before a1.
- */
- @Test
- public void testTopLevelAspectOnAspect_requiredProviderProvidedTwicePassed() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a1p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a1_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['dep'],",
- " required_aspect_providers = [a1p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a1p(value = 'a1p_a2_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a1p],",
- ")",
- "",
- "def _a3_impl(target, ctx):",
- " return [a1p(value = 'a1p_a3_val')]",
- "a3 = aspect(",
- " implementation = _a3_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a1p],",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'dep': attr.label(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " dep = ':dep_target',",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a1", "test/defs.bzl%a2"),
- "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target sees a1p = a1p_a3_val",
- "aspect a1 on target //test:main sees a1p = a1p_a3_val");
- }
-
- @Test
- public void testTopLevelAspectOnAspect_requiredProviderNotProvided() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a1p = provider()",
- "a2p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a1_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['dep'],",
- " required_aspect_providers = [a1p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a2p(value = 'a2p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a2p],",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'dep': attr.label(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " dep = ':dep_target',",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%a2", "test/defs.bzl%a1"), "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target cannot see a1p",
- "aspect a1 on target //test:main cannot see a1p");
- }
-
- /**
- * --aspects = a1, a2: aspect a1 requires provider a1p, aspect a2 provides a1p but it was listed
- * after a1 so aspect a1 cannot see a1p value.
- */
- @Test
- public void testTopLevelAspectOnAspect_requiredProviderProvidedAfterTheAspect() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a1p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a1_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['dep'],",
- " required_aspect_providers = [a1p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a1p(value = 'a1p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a1p],",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'dep': attr.label(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " dep = ':dep_target',",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2"), "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target cannot see a1p",
- "aspect a1 on target //test:main cannot see a1p");
- }
-
- /**
- * --aspects = a2, a1: aspect a1 requires provider a1p, aspect a2 provides a1p. But aspect a2
- * propagates along different attr_aspects from a1 so a1 cannot get a1p on all dependency targets.
- */
- @Test
- public void testTopLevelAspectOnAspect_differentAttrAspects() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a1p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result += ctx.rule.attr.dep[a1_result].value",
- " if ctx.rule.attr.extra_dep:",
- " complete_result += ctx.rule.attr.extra_dep[a1_result].value",
- " complete_result += [result]",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['dep', 'extra_dep'],",
- " required_aspect_providers = [a1p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a1p(value = 'a1p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a1p],",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'dep': attr.label(),",
- " 'extra_dep': attr.label(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " dep = ':dep_target',",
- " extra_dep = ':extra_dep_target',",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")",
- "simple_rule(",
- " name = 'extra_dep_target',",
- ")");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%a2", "test/defs.bzl%a1"), "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target sees a1p = a1p_val",
- "aspect a1 on target //test:extra_dep_target cannot see a1p",
- "aspect a1 on target //test:main sees a1p = a1p_val");
- }
-
- /**
- * --aspects = a2, a1: aspect a1 requires provider a1p, aspect a2 provides a1p. But aspect a2
- * propagates along different required_providers from a1 so a1 cannot get a1p on all dependency
- * targets.
- */
- @Test
- public void testTopLevelAspectOnAspect_differentRequiredRuleProviders() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a1p = provider()",
- "a1_result = provider()",
- "rule_prov_a = provider()",
- "rule_prov_b = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " complete_result = []",
- " if hasattr(ctx.rule.attr, 'deps'):",
- " for dep in ctx.rule.attr.deps:",
- " complete_result += dep[a1_result].value",
- " complete_result += [result]",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['deps'],",
- " required_aspect_providers = [a1p],",
- " required_providers = [[rule_prov_a], [rule_prov_b]],",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a1p(value = 'a1p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['deps'],",
- " provides = [a1p],",
- " required_providers = [rule_prov_a],",
- ")",
- "",
- "def _main_rule_impl(ctx):",
- " return [rule_prov_a(), rule_prov_b()]",
- "main_rule = rule(",
- " implementation = _main_rule_impl,",
- " attrs = {",
- " 'deps': attr.label_list(),",
- " },",
- ")",
- "",
- "def _rule_with_prov_a_impl(ctx):",
- " return [rule_prov_a()]",
- "rule_with_prov_a = rule(",
- " implementation = _rule_with_prov_a_impl,",
- " 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,",
- " provides = [rule_prov_b]",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'main_rule', 'rule_with_prov_a', 'rule_with_prov_b')",
- "main_rule(",
- " name = 'main',",
- " deps = [':target_with_prov_a', ':target_with_prov_b'],",
- ")",
- "rule_with_prov_a(",
- " name = 'target_with_prov_a',",
- ")",
- "rule_with_prov_b(",
- " name = 'target_with_prov_b',",
- ")");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%a2", "test/defs.bzl%a1"), "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:target_with_prov_a sees a1p = a1p_val",
- "aspect a1 on target //test:target_with_prov_b cannot see a1p",
- "aspect a1 on target //test:main sees a1p = a1p_val");
- }
-
- /**
- * --aspects = a3, a2, a1: both aspects a1 and a2 require provider a3p, aspect a3 provides a3p. a1
- * and a2 should be able to read a3p.
- */
- @Test
- public void testTopLevelAspectOnAspect_providerRequiredByMultipleAspects() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a3p = provider()",
- "a1_result = provider()",
- "a2_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a3p in target:",
- " result += ' sees a3p = {}'.format(target[a3p].value)",
- " else:",
- " result += ' cannot see a3p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a1_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['dep'],",
- " required_aspect_providers = [a3p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " result = 'aspect a2 on target {}'.format(target.label)",
- " if a3p in target:",
- " result += ' sees a3p = {}'.format(target[a3p].value)",
- " else:",
- " result += ' cannot see a3p'",
- " complete_result = []",
- " if ctx.rule.attr.dep:",
- " complete_result = ctx.rule.attr.dep[a2_result].value + [result]",
- " else:",
- " complete_result = [result]",
- " return [a2_result(value = complete_result)]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['dep'],",
- " required_aspect_providers = [a3p]",
- ")",
- "",
- "def _a3_impl(target, ctx):",
- " return [a3p(value = 'a3p_val')]",
- "a3 = aspect(",
- " implementation = _a3_impl,",
- " attr_aspects = ['dep'],",
- " provides = [a3p],",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'dep': attr.label(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " dep = ':dep_target',",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
- "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a2 = getConfiguredAspect(configuredAspects, "a2");
- assertThat(a2).isNotNull();
- StarlarkProvider.Key a2Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a2_result");
- StructImpl a2ResultProvider = (StructImpl) a2.get(a2Result);
- assertThat((Sequence<?>) a2ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a2 on target //test:dep_target sees a3p = a3p_val",
- "aspect a2 on target //test:main sees a3p = a3p_val");
-
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target sees a3p = a3p_val",
- "aspect a1 on target //test:main sees a3p = a3p_val");
- }
-
- /**
- * --aspects = a1, a2, a3: aspect a3 requires a1p and a2p, a1 provides a1p and a2 provides a2p.
- *
- * <p>top level target (main) has two dependencies t1 and t2. Aspects a1 and a3 can propagate to
- * t1 and aspects a2 and a3 can propagate to t2. Both t1 and t2 have t0 as dependency, aspect a3
- * will run twice on t0 once with aspects path (a1, a3) and the other with (a2, a3).
- */
- @Test
- public void testTopLevelAspectOnAspect_diamondCase() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a1p = provider()",
- "a2p = provider()",
- "a3_result = provider()",
- "",
- "r1p = provider()",
- "r2p = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " return [a1p(value = 'a1p_val')]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['deps'],",
- " required_providers = [r1p],",
- " provides = [a1p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a2p(value = 'a2p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['deps'],",
- " required_providers = [r2p],",
- " provides = [a2p]",
- ")",
- "",
- "def _a3_impl(target, ctx):",
- " result = 'aspect a3 on target {}'.format(target.label)",
- " if a1p in target:",
- " result += ' sees a1p = {}'.format(target[a1p].value)",
- " else:",
- " result += ' cannot see a1p'",
- " if a2p in target:",
- " result += ' and sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' and cannot see a2p'",
- " complete_result = []",
- " if ctx.rule.attr.deps:",
- " for dep in ctx.rule.attr.deps:",
- " complete_result.extend(dep[a3_result].value)",
- " complete_result.append(result)",
- " return [a3_result(value = complete_result)]",
- "a3 = aspect(",
- " implementation = _a3_impl,",
- " attr_aspects = ['deps'],",
- " required_aspect_providers = [[a1p], [a2p]],",
- ")",
- "",
- "def _r0_impl(ctx):",
- " return [r1p(), r2p()]",
- "r0 = rule(",
- " implementation = _r0_impl,",
- " attrs = {",
- " 'deps': attr.label_list(),",
- " },",
- " provides = [r1p, r2p]",
- ")",
- "def _r1_impl(ctx):",
- " return [r1p()]",
- "r1 = rule(",
- " implementation = _r1_impl,",
- " attrs = {",
- " 'deps': attr.label_list(),",
- " },",
- " provides = [r1p]",
- ")",
- "def _r2_impl(ctx):",
- " return [r2p()]",
- "r2 = rule(",
- " implementation = _r2_impl,",
- " attrs = {",
- " 'deps': attr.label_list(),",
- " },",
- " provides = [r2p]",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'r0', 'r1', 'r2')",
- "r0(",
- " name = 'main',",
- " deps = [':t1', ':t2'],",
- ")",
- "r1(",
- " name = 't1',",
- " deps = [':t0'],",
- ")",
- "r2(",
- " name = 't2',",
- " deps = [':t0'],",
- ")",
- "r0(",
- " name = 't0',",
- ")");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2", "test/defs.bzl%a3"),
- "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a3 = getConfiguredAspect(configuredAspects, "a3");
- assertThat(a3).isNotNull();
- StarlarkProvider.Key a3Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a3_result");
- StructImpl a3ResultProvider = (StructImpl) a3.get(a3Result);
- assertThat((Sequence<?>) a3ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a3 on target //test:t0 sees a1p = a1p_val and cannot see a2p",
- "aspect a3 on target //test:t0 cannot see a1p and sees a2p = a2p_val",
- "aspect a3 on target //test:t1 sees a1p = a1p_val and cannot see a2p",
- "aspect a3 on target //test:t2 cannot see a1p and sees a2p = a2p_val",
- "aspect a3 on target //test:main sees a1p = a1p_val and sees a2p = a2p_val");
- }
-
- @Test
- public void testTopLevelAspectOnAspect_duplicateAspectsFailed() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a2p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a2p in target:",
- " result += ' sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' cannot see a2p'",
- " complete_result = []",
- " if ctx.rule.attr.deps:",
- " for dep in ctx.rule.attr.deps:",
- " complete_result.extend(dep[a1_result].value)",
- " complete_result.append(result)",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['deps'],",
- " required_aspect_providers = [a2p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a2p(value = 'a2p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['deps'],",
- " provides = [a2p]",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'deps': attr.label_list(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " deps = [':dep_target'],",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
- reporter.removeHandler(failFastHandler);
-
- // 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(
- ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2", "test/defs.bzl%a1"),
- "//test:main");
- assertThat(result.hasError()).isTrue();
- } else {
- assertThrows(
- ViewCreationFailedException.class,
- () ->
- update(
- ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2", "test/defs.bzl%a1"),
- "//test:main"));
- }
- assertContainsEvent("aspect //test:defs.bzl%a1 added more than once");
- }
-
- /**
- * --aspects = a1 requires provider a2p provided by aspect a2. a1 is applied on top level target
- * `main` whose rule propagates aspect a2 to its `deps`. So a1 on `main` cannot see a2p but it can
- * see a2p on `main` deps.
- */
- @Test
- public void testTopLevelAspectOnAspect_requiredAspectProviderOnlyAvailableOnDep()
- throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a2p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a2p in target:",
- " result += ' sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' cannot see a2p'",
- " complete_result = []",
- " if ctx.rule.attr.deps:",
- " for dep in ctx.rule.attr.deps:",
- " complete_result.extend(dep[a1_result].value)",
- " complete_result.append(result)",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['deps'],",
- " required_aspect_providers = [a2p]",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a2p(value = 'a2p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['deps'],",
- " provides = [a2p]",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'deps': attr.label_list(aspects=[a2]),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " deps = [':dep_target'],",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
-
- AnalysisResult analysisResult = update(ImmutableList.of("test/defs.bzl%a1"), "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target sees a2p = a2p_val",
- "aspect a1 on target //test:main cannot see a2p");
- }
-
- @Test
- public void testTopLevelAspectOnAspect_multipleTopLevelTargets() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a2p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a2p in target:",
- " result += ' sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' cannot see a2p'",
- " complete_result = []",
- " if ctx.rule.attr.deps:",
- " for dep in ctx.rule.attr.deps:",
- " complete_result.extend(dep[a1_result].value)",
- " complete_result.append(result)",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['deps'],",
- " required_aspect_providers = [a2p],",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a2p(value = 'a2p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['deps'],",
- " provides = [a2p]",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'deps': attr.label_list(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 't1',",
- ")",
- "simple_rule(",
- " name = 't2',",
- ")");
-
- AnalysisResult analysisResult =
- update(ImmutableList.of("test/defs.bzl%a2", "test/defs.bzl%a1"), "//test:t2", "//test:t1");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1Ont1 = getConfiguredAspect(configuredAspects, "a1", "t1");
- assertThat(a1Ont1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1Ont1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly("aspect a1 on target //test:t1 sees a2p = a2p_val");
-
- ConfiguredAspect a1Ont2 = getConfiguredAspect(configuredAspects, "a1", "t2");
- assertThat(a1Ont2).isNotNull();
- a1ResultProvider = (StructImpl) a1Ont2.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly("aspect a1 on target //test:t2 sees a2p = a2p_val");
- }
-
- @Test
- public void testTopLevelAspectOnAspect_multipleRequiredProviders() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a2p = provider()",
- "a3p = provider()",
- "a1_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a2p in target:",
- " result += ' sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' cannot see a2p'",
- " if a3p in target:",
- " result += ' and sees a3p = {}'.format(target[a3p].value)",
- " else:",
- " result += ' and cannot see a3p'",
- " complete_result = []",
- " if ctx.rule.attr.deps:",
- " for dep in ctx.rule.attr.deps:",
- " complete_result.extend(dep[a1_result].value)",
- " complete_result.append(result)",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['deps'],",
- " required_aspect_providers = [[a2p], [a3p]],",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " return [a2p(value = 'a2p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['deps'],",
- " provides = [a2p]",
- ")",
- "",
- "def _a3_impl(target, ctx):",
- " return [a3p(value = 'a3p_val')]",
- "a3 = aspect(",
- " implementation = _a3_impl,",
- " attr_aspects = ['deps'],",
- " provides = [a3p]",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'deps': attr.label_list(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " deps = [':dep_target'],",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
- "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target sees a2p = a2p_val and sees a3p = a3p_val",
- "aspect a1 on target //test:main sees a2p = a2p_val and sees a3p = a3p_val");
- }
-
- @Test
- public void testTopLevelAspectOnAspect_multipleRequiredProviders2() throws Exception {
- scratch.file(
- "test/defs.bzl",
- "a2p = provider()",
- "a3p = provider()",
- "a1_result = provider()",
- "a2_result = provider()",
- "",
- "def _a1_impl(target, ctx):",
- " result = 'aspect a1 on target {}'.format(target.label)",
- " if a2p in target:",
- " result += ' sees a2p = {}'.format(target[a2p].value)",
- " else:",
- " result += ' cannot see a2p'",
- " if a3p in target:",
- " result += ' and sees a3p = {}'.format(target[a3p].value)",
- " else:",
- " result += ' and cannot see a3p'",
- " complete_result = []",
- " if ctx.rule.attr.deps:",
- " for dep in ctx.rule.attr.deps:",
- " complete_result.extend(dep[a1_result].value)",
- " complete_result.append(result)",
- " return [a1_result(value = complete_result)]",
- "a1 = aspect(",
- " implementation = _a1_impl,",
- " attr_aspects = ['deps'],",
- " required_aspect_providers = [[a2p], [a3p]],",
- ")",
- "",
- "def _a2_impl(target, ctx):",
- " result = 'aspect a2 on target {}'.format(target.label)",
- " if a3p in target:",
- " result += ' sees a3p = {}'.format(target[a3p].value)",
- " else:",
- " result += ' cannot see a3p'",
- " complete_result = []",
- " if ctx.rule.attr.deps:",
- " for dep in ctx.rule.attr.deps:",
- " complete_result.extend(dep[a2_result].value)",
- " complete_result.append(result)",
- " return [a2_result(value = complete_result), a2p(value = 'a2p_val')]",
- "a2 = aspect(",
- " implementation = _a2_impl,",
- " attr_aspects = ['deps'],",
- " provides = [a2p],",
- " required_aspect_providers = [a3p]",
- ")",
- "",
- "def _a3_impl(target, ctx):",
- " return [a3p(value = 'a3p_val')]",
- "a3 = aspect(",
- " implementation = _a3_impl,",
- " attr_aspects = ['deps'],",
- " provides = [a3p]",
- ")",
- "",
- "def _simple_rule_impl(ctx):",
- " pass",
- "simple_rule = rule(",
- " implementation = _simple_rule_impl,",
- " attrs = {",
- " 'deps': attr.label_list(),",
- " },",
- ")");
- scratch.file(
- "test/BUILD",
- "load('//test:defs.bzl', 'simple_rule')",
- "simple_rule(",
- " name = 'main',",
- " deps = [':dep_target'],",
- ")",
- "simple_rule(",
- " name = 'dep_target',",
- ")");
-
- AnalysisResult analysisResult =
- update(
- ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
- "//test:main");
-
- Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
- ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
- assertThat(a1).isNotNull();
- StarlarkProvider.Key a1Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a1_result");
- StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
- assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a1 on target //test:dep_target sees a2p = a2p_val and sees a3p = a3p_val",
- "aspect a1 on target //test:main sees a2p = a2p_val and sees a3p = a3p_val");
-
- ConfiguredAspect a2 = getConfiguredAspect(configuredAspects, "a2");
- assertThat(a2).isNotNull();
- StarlarkProvider.Key a2Result =
- new StarlarkProvider.Key(
- Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "a2_result");
- StructImpl a2ResultProvider = (StructImpl) a2.get(a2Result);
- assertThat((Sequence<?>) a2ResultProvider.getValue("value"))
- .containsExactly(
- "aspect a2 on target //test:dep_target sees a3p = a3p_val",
- "aspect a2 on target //test:main sees a3p = a3p_val");
- }
-
- 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();
- }
- }
- return null;
- }
-
- 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;
- }
-
/** StarlarkAspectTest with "keep going" flag */
@RunWith(JUnit4.class)
public static final class WithKeepGoing extends StarlarkDefinedAspectsTest {