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: 381862973
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 1e8a0ef..2a8445a 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;
+import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
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 AspectValueKey failedAspect;
+ @Nullable private final AspectKey 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 AspectValueKey);
+ failedTarget instanceof ConfiguredTargetKey || failedTarget instanceof AspectKey);
if (failedTarget instanceof ConfiguredTargetKey) {
this.failedAspect = null;
this.failedTarget = (ConfiguredTargetKey) failedTarget;
} else {
- this.failedAspect = (AspectValueKey) failedTarget;
+ this.failedAspect = (AspectKey) failedTarget;
this.failedTarget = failedAspect.getBaseConfiguredTargetKey();
}
if (configuration != null) {
@@ -65,7 +65,7 @@
}
public AnalysisFailureEvent(
- AspectValueKey failedAspect, BuildEventId configuration, NestedSet<Cause> rootCauses) {
+ AspectKey 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 bec43a1..f835927 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,13 +55,12 @@
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;
@@ -75,6 +74,7 @@
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,7 +86,6 @@
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;
@@ -275,10 +274,7 @@
.map(TargetAndConfiguration::getConfiguredTargetKey)
.collect(Collectors.toList());
- Multimap<Pair<Label, String>, BuildConfiguration> aspectConfigurations =
- ArrayListMultimap.create();
-
- List<AspectValueKey> aspectKeys = new ArrayList<>();
+ ImmutableList.Builder<AspectClass> aspectClassesBuilder = ImmutableList.builder();
for (String aspect : aspects) {
// Syntax: label%aspect
int delimiterPosition = aspect.indexOf('%');
@@ -318,38 +314,14 @@
createFailureDetail(errorMessage, Analysis.Code.ASPECT_LABEL_SYNTAX_ERROR),
e);
}
-
String starlarkFunctionName = aspect.substring(delimiterPosition + 1);
- 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));
- }
+ aspectClassesBuilder.add(new StarlarkAspectClass(starlarkFileLabel, starlarkFunctionName));
} else {
final NativeAspectClass aspectFactoryClass =
ruleClassProvider.getNativeAspectClassMap().get(aspect);
if (aspectFactoryClass != null) {
- 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));
- }
+ aspectClassesBuilder.add(aspectFactoryClass);
} else {
String errorMessage = "Aspect '" + aspect + "' is unknown";
throw new ViewCreationFailedException(
@@ -358,6 +330,25 @@
}
}
+ 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(
@@ -382,7 +373,7 @@
skyframeBuildView.configureTargets(
eventHandler,
topLevelCtKeys,
- aspectKeys,
+ aspectsKeys.build(),
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 5e1c1ce..d39d604 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,11 +297,18 @@
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 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")
+ "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")
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 cb0678d..9bde830 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,4 +64,9 @@
public final int hashCode() {
return Objects.hash(getExtensionLabel(), getExportedName());
}
+
+ @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 f6ecb9c..fddca3f 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,7 +13,6 @@
// 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;
@@ -30,29 +29,15 @@
import com.google.devtools.build.skyframe.SkyFunctionName;
import javax.annotation.Nullable;
-/** A base class for keys that have AspectValue as a Sky value. */
-public abstract class AspectValueKey implements ActionLookupKey {
+/** A wrapper class for sky keys needed to compute sky values for aspects. */
+public final class AspectValueKey {
+
+ private AspectValueKey() {}
private static final Interner<AspectKey> aspectKeyInterner = BlazeInterners.newWeakInterner();
- private static final Interner<StarlarkAspectLoadingKey> starlarkAspectKeyInterner =
+ private static final Interner<TopLevelAspectsKey> topLevelAspectsKeyInterner =
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,
@@ -67,6 +52,15 @@
}
public static AspectKey createAspectKey(
+ AspectDescriptor aspectDescriptor,
+ ImmutableList<AspectKey> baseKeys,
+ BuildConfigurationValue.Key aspectConfigurationKey,
+ ConfiguredTargetKey baseConfiguredTargetKey) {
+ return AspectKey.createAspectKey(
+ baseConfiguredTargetKey, baseKeys, aspectDescriptor, aspectConfigurationKey);
+ }
+
+ public static AspectKey createAspectKey(
Label label,
@Nullable BuildConfiguration baseConfiguration,
AspectDescriptor aspectDescriptor,
@@ -78,28 +72,24 @@
aspectConfiguration == null ? null : BuildConfigurationValue.key(aspectConfiguration));
}
- public static StarlarkAspectLoadingKey createStarlarkAspectKey(
+ public static TopLevelAspectsKey createTopLevelAspectsKey(
+ ImmutableList<AspectClass> topLevelAspectsClasses,
Label targetLabel,
- @Nullable BuildConfiguration aspectConfiguration,
- @Nullable BuildConfiguration targetConfiguration,
- Label starlarkFileLabel,
- String starlarkExportName) {
- return StarlarkAspectLoadingKey.createInternal(
+ @Nullable BuildConfiguration configuration) {
+ return TopLevelAspectsKey.createInternal(
+ topLevelAspectsClasses,
targetLabel,
- aspectConfiguration == null ? null : BuildConfigurationValue.key(aspectConfiguration),
ConfiguredTargetKey.builder()
.setLabel(targetLabel)
- .setConfiguration(targetConfiguration)
- .build(),
- starlarkFileLabel,
- starlarkExportName);
+ .setConfiguration(configuration)
+ .build());
}
// Specific subtypes of aspect keys.
/** Represents an aspect applied to a particular target. */
@AutoCodec
- public static final class AspectKey extends AspectValueKey {
+ public static final class AspectKey implements ActionLookupKey {
private final ConfiguredTargetKey baseConfiguredTargetKey;
private final ImmutableList<AspectKey> baseKeys;
@Nullable private final BuildConfigurationValue.Key aspectConfigurationKey;
@@ -141,7 +131,12 @@
return SkyFunctions.ASPECT;
}
- @Override
+ /**
+ * 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 String getAspectName() {
return aspectDescriptor.getDescription();
}
@@ -178,11 +173,9 @@
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);
@@ -207,13 +200,11 @@
* 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;
}
@@ -280,70 +271,46 @@
}
}
- /** The key for a Starlark aspect. */
+ /** The key for top level aspects specified by --aspects option on a top level target. */
@AutoCodec
- public static final class StarlarkAspectLoadingKey extends AspectValueKey {
+ public static final class TopLevelAspectsKey implements ActionLookupKey {
+ private final ImmutableList<AspectClass> topLevelAspectsClasses;
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 StarlarkAspectLoadingKey createInternal(
+ static TopLevelAspectsKey createInternal(
+ ImmutableList<AspectClass> topLevelAspectsClasses,
Label targetLabel,
- BuildConfigurationValue.Key aspectConfigurationKey,
- ConfiguredTargetKey baseConfiguredTargetKey,
- Label starlarkFileLabel,
- String starlarkValueName) {
- return starlarkAspectKeyInterner.intern(
- new StarlarkAspectLoadingKey(
+ ConfiguredTargetKey baseConfiguredTargetKey) {
+ return topLevelAspectsKeyInterner.intern(
+ new TopLevelAspectsKey(
+ topLevelAspectsClasses,
targetLabel,
- aspectConfigurationKey,
baseConfiguredTargetKey,
- starlarkFileLabel,
- starlarkValueName,
- Objects.hashCode(
- targetLabel,
- aspectConfigurationKey,
- baseConfiguredTargetKey,
- starlarkFileLabel,
- starlarkValueName)));
+ Objects.hashCode(topLevelAspectsClasses, targetLabel, baseConfiguredTargetKey)));
}
- private StarlarkAspectLoadingKey(
+ private TopLevelAspectsKey(
+ ImmutableList<AspectClass> topLevelAspectsClasses,
Label targetLabel,
- BuildConfigurationValue.Key aspectConfigurationKey,
ConfiguredTargetKey baseConfiguredTargetKey,
- Label starlarkFileLabel,
- String starlarkValueName,
int 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.LOAD_STARLARK_ASPECT;
+ return SkyFunctions.TOP_LEVEL_ASPECTS;
}
- String getStarlarkValueName() {
- return starlarkValueName;
- }
-
- Label getStarlarkFileLabel() {
- return starlarkFileLabel;
- }
-
- @Override
- public String getAspectName() {
- return String.format("%s%%%s", starlarkFileLabel, starlarkValueName);
+ ImmutableList<AspectClass> getTopLevelAspectsClasses() {
+ return topLevelAspectsClasses;
}
@Override
@@ -351,24 +318,14 @@
return targetLabel;
}
- @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() {
+ ConfiguredTargetKey getBaseConfiguredTargetKey() {
return baseConfiguredTargetKey;
}
+ String getDescription() {
+ return topLevelAspectsClasses + " on " + getLabel();
+ }
+
@Override
public int hashCode() {
return hashCode;
@@ -379,35 +336,14 @@
if (o == this) {
return true;
}
- if (!(o instanceof StarlarkAspectLoadingKey)) {
+ if (!(o instanceof TopLevelAspectsKey)) {
return false;
}
- StarlarkAspectLoadingKey that = (StarlarkAspectLoadingKey) o;
+ TopLevelAspectsKey that = (TopLevelAspectsKey) o;
return hashCode == that.hashCode
&& Objects.equal(targetLabel, that.targetLabel)
- && 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);
+ && Objects.equal(topLevelAspectsClasses, that.topLevelAspectsClasses);
}
}
}
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 33006ba..52c40f2 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -37,6 +37,7 @@
"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
new file mode 100644
index 0000000..4d81910
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/LoadStarlarkAspectFunction.java
@@ -0,0 +1,169 @@
+// 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 cb07796..46443e4 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,6 +88,8 @@
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 7b4007d..c6d559b 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,7 +88,9 @@
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;
@@ -380,7 +382,7 @@
public SkyframeAnalysisResult configureTargets(
ExtendedEventHandler eventHandler,
List<ConfiguredTargetKey> ctKeys,
- List<AspectValueKey> aspectKeys,
+ ImmutableList<TopLevelAspectsKey> topLevelAspectsKey,
Supplier<Map<BuildConfigurationValue.Key, BuildConfiguration>> configurationLookupSupplier,
TopLevelArtifactContext topLevelArtifactContextForConflictPruning,
EventBus eventBus,
@@ -397,7 +399,7 @@
skyframeExecutor.configureTargets(
eventHandler,
ctKeys,
- aspectKeys,
+ topLevelAspectsKey,
keepGoing,
numThreads,
cpuHeavySkyKeysThreadPoolSize);
@@ -405,21 +407,33 @@
enableAnalysis(false);
}
- Map<AspectKey, ConfiguredAspect> aspects = Maps.newHashMapWithExpectedSize(aspectKeys.size());
+ int numOfAspects = 0;
+ if (!topLevelAspectsKey.isEmpty()) {
+ numOfAspects =
+ topLevelAspectsKey.size() * topLevelAspectsKey.get(0).getTopLevelAspectsClasses().size();
+ }
+ Map<AspectKey, ConfiguredAspect> aspects = Maps.newHashMapWithExpectedSize(numOfAspects);
Root singleSourceRoot = skyframeExecutor.getForcedSingleSourceRootIfNoExecrootSymlinkCreation();
NestedSetBuilder<Package> packages =
singleSourceRoot == null ? NestedSetBuilder.stableOrder() : null;
- for (AspectValueKey aspectKey : aspectKeys) {
- AspectValue value = (AspectValue) result.get(aspectKey);
+ ImmutableList.Builder<AspectKey> aspectKeysBuilder = ImmutableList.builder();
+
+ for (TopLevelAspectsKey key : topLevelAspectsKey) {
+ TopLevelAspectsValue value = (TopLevelAspectsValue) result.get(key);
if (value == null) {
// Skip aspects that couldn't be applied to targets.
continue;
}
- aspects.put(value.getKey(), value.getConfiguredAspect());
- if (packages != null) {
- packages.addTransitive(value.getTransitivePackagesForPackageRootResolution());
+ 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());
}
}
+ ImmutableList<AspectKey> aspectKeys = aspectKeysBuilder.build();
Collection<ConfiguredTarget> cts = Lists.newArrayListWithCapacity(ctKeys.size());
for (ConfiguredTargetKey value : ctKeys) {
@@ -561,7 +575,7 @@
BuildConfigurationValue.Key configKey =
ctKey instanceof ConfiguredTargetKey
? ((ConfiguredTargetKey) ctKey).getConfigurationKey()
- : ((AspectValueKey) ctKey).getAspectConfigurationKey();
+ : ((AspectKey) ctKey).getAspectConfigurationKey();
eventBus.post(
new AnalysisFailureEvent(
ctKey,
@@ -597,13 +611,9 @@
.collect(toImmutableList());
aspects =
- aspectKeys.stream()
- .filter(topLevelActionConflictReport::isErrorFree)
- .map(result::get)
- .map(AspectValue.class::cast)
- .collect(
- ImmutableMap.toImmutableMap(
- AspectValue::getKey, AspectValue::getConfiguredAspect));
+ aspects.entrySet().stream()
+ .filter(e -> topLevelActionConflictReport.isErrorFree(e.getKey()))
+ .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
}
return new SkyframeAnalysisResult(
@@ -744,15 +754,14 @@
.reportCycles(errorInfo.getCycleInfo(), errorKey, eventHandler);
Exception cause = errorInfo.getException();
Preconditions.checkState(cause != null || !errorInfo.getCycleInfo().isEmpty(), errorInfo);
-
- if (errorKey.argument() instanceof AspectValueKey) {
+ if (errorKey.argument() instanceof TopLevelAspectsKey) {
// We skip Aspects in the keepGoing case; the failures should already have been reported to
// the event handler.
if (!keepGoing && noKeepGoingException == null) {
- AspectValueKey aspectKey = (AspectValueKey) errorKey.argument();
+ TopLevelAspectsKey aspectKey = (TopLevelAspectsKey) errorKey.argument();
String errorMsg =
String.format(
- "Analysis of aspect '%s' failed; build aborted", aspectKey.getDescription());
+ "Analysis of aspects '%s' failed; build aborted", aspectKey.getDescription());
noKeepGoingException = createViewCreationFailedException(cause, errorMsg);
}
continue;
@@ -773,7 +782,7 @@
}
Preconditions.checkState(
errorKey.argument() instanceof ConfiguredTargetKey,
- "expected '%s' to be a AspectValueKey or ConfiguredTargetKey",
+ "expected '%s' to be a TopLevelAspectsKey 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 3ef335b..8219b72 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
@@ -159,6 +159,7 @@
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;
@@ -565,7 +566,8 @@
new BuildViewProvider(),
ruleClassProvider,
shouldStoreTransitivePackagesInLoadingAndAnalysis()));
- map.put(SkyFunctions.LOAD_STARLARK_ASPECT, new ToplevelStarlarkAspectFunction());
+ map.put(SkyFunctions.LOAD_STARLARK_ASPECT, new LoadStarlarkAspectFunction());
+ map.put(SkyFunctions.TOP_LEVEL_ASPECTS, new ToplevelStarlarkAspectFunction());
map.put(SkyFunctions.ACTION_LOOKUP_CONFLICT_FINDING, new ActionLookupConflictFindingFunction());
map.put(
SkyFunctions.TOP_LEVEL_ACTION_LOOKUP_CONFLICT_FINDING,
@@ -2319,7 +2321,7 @@
EvaluationResult<ActionLookupValue> configureTargets(
ExtendedEventHandler eventHandler,
List<ConfiguredTargetKey> values,
- List<AspectValueKey> aspectKeys,
+ ImmutableList<TopLevelAspectsKey> aspectKeys,
boolean keepGoing,
int numThreads,
int cpuHeavySkyKeysThreadPoolSize)
@@ -3054,7 +3056,7 @@
}
final AnalysisTraversalResult getActionLookupValuesInBuild(
- List<ConfiguredTargetKey> topLevelCtKeys, List<AspectValueKey> aspectKeys)
+ List<ConfiguredTargetKey> topLevelCtKeys, ImmutableList<AspectKey> aspectKeys)
throws InterruptedException {
AnalysisTraversalResult result = new AnalysisTraversalResult();
if (!isAnalysisIncremental()) {
@@ -3074,7 +3076,7 @@
for (ConfiguredTargetKey key : topLevelCtKeys) {
findActionsRecursively(walkableGraph, key, seen, result);
}
- for (AspectValueKey key : aspectKeys) {
+ for (AspectKey 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 cf8f828..693bde7 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.LOAD_STARLARK_ASPECT),
+ SkyFunctions.isSkyFunction(SkyFunctions.TOP_LEVEL_ASPECTS),
SkyFunctions.isSkyFunction(TransitiveTargetKey.NAME),
SkyFunctions.isSkyFunction(SkyFunctions.PREPARE_ANALYSIS_PHASE));
@@ -65,8 +65,6 @@
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 a858e35..d230637 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,22 +14,37 @@
package com.google.devtools.build.lib.skyframe;
-import com.google.devtools.build.lib.causes.LabelCause;
-import com.google.devtools.build.lib.cmdline.Label;
+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.AspectParameters;
+import com.google.devtools.build.lib.packages.NativeAspectClass;
import com.google.devtools.build.lib.packages.StarlarkAspect;
-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.lib.packages.StarlarkAspectClass;
+import com.google.devtools.build.lib.packages.StarlarkDefinedAspect;
+import com.google.devtools.build.lib.packages.StarlarkNativeAspect;
+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.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;
/**
- * SkyFunction to load aspects from Starlark extensions and calculate their values.
+ * 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.
*
* <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
@@ -41,34 +56,33 @@
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env)
- throws LoadStarlarkAspectFunctionException, InterruptedException {
- StarlarkAspectLoadingKey aspectLoadingKey = (StarlarkAspectLoadingKey) skyKey.argument();
- String starlarkValueName = aspectLoadingKey.getStarlarkValueName();
- Label starlarkFileLabel = aspectLoadingKey.getStarlarkFileLabel();
+ throws TopLevelStarlarkAspectFunctionException, InterruptedException {
+ TopLevelAspectsKey topLevelAspectsKey = (TopLevelAspectsKey) skyKey.argument();
- StarlarkAspect starlarkAspect;
- try {
- 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);
+ ImmutableList<Aspect> topLevelAspects =
+ getTopLevelAspects(env, topLevelAspectsKey.getTopLevelAspectsClasses());
+ if (topLevelAspects == null) {
+ return null; // some aspects are not loaded
}
- SkyKey aspectKey = aspectLoadingKey.toAspectKey(starlarkAspect.getAspectClass());
- return env.getValue(aspectKey);
+ 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);
}
@Nullable
@@ -77,18 +91,118 @@
return null;
}
- private static DetailedExitCode createDetailedCode(String msg, Code code) {
- return DetailedExitCode.of(
- FailureDetail.newBuilder()
- .setMessage(msg)
- .setAnalysis(Analysis.newBuilder().setCode(code))
- .build());
+ @Nullable
+ private static ImmutableList<Aspect> getTopLevelAspects(
+ Environment env, ImmutableList<AspectClass> topLevelAspectsClasses)
+ throws InterruptedException {
+ ImmutableList.Builder<Aspect> topLevelAspects = ImmutableList.builder();
+
+ 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();
+ if (starlarkAspect instanceof StarlarkDefinedAspect) {
+ StarlarkDefinedAspect starlarkDefinedAspect = (StarlarkDefinedAspect) starlarkAspect;
+ topLevelAspects.add(
+ Aspect.forStarlark(
+ starlarkDefinedAspect.getAspectClass(),
+ starlarkDefinedAspect.getDefinition(AspectParameters.EMPTY),
+ AspectParameters.EMPTY,
+ /** inheritedRequiredProviders = */
+ null,
+ /** inheritedAttributeAspects = */
+ null));
+ } else {
+ topLevelAspects.add(Aspect.forNative(((StarlarkNativeAspect) starlarkAspect)));
+ }
+ } else {
+ topLevelAspects.add(Aspect.forNative((NativeAspectClass) aspectClass));
+ }
+ }
+
+ return topLevelAspects.build();
+ }
+
+ 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;
}
/** Exceptions thrown from ToplevelStarlarkAspectFunction. */
- public static class LoadStarlarkAspectFunctionException extends SkyFunctionException {
- public LoadStarlarkAspectFunctionException(AspectCreationException cause) {
+ public static class TopLevelStarlarkAspectFunctionException extends SkyFunctionException {
+ public TopLevelStarlarkAspectFunctionException(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();
+ }
+ }
}