Optionally propagate aspects through rule output dependencies

Starlark-defined aspects can opt into this new feature by being defined with a new parameter on the aspect() function, "apply_to_generating_rules".
This behavior is guarded by a new experimental flag, --experimental_aspect_output_propagation.

RELNOTES: None.
PiperOrigin-RevId: 269571978
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index f6f3554..c11a748 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -53,6 +53,7 @@
 import com.google.devtools.build.lib.packages.NativeAspectClass;
 import com.google.devtools.build.lib.packages.NoSuchTargetException;
 import com.google.devtools.build.lib.packages.NoSuchThingException;
+import com.google.devtools.build.lib.packages.OutputFile;
 import com.google.devtools.build.lib.packages.Package;
 import com.google.devtools.build.lib.packages.RuleClassProvider;
 import com.google.devtools.build.lib.packages.SkylarkAspect;
@@ -582,6 +583,16 @@
     // the real configured target.
     Label aliasLabel = aliasChain.size() > 1 ? aliasChain.get(1) : configuredTarget.getLabel();
 
+    return createAliasAspect(env, originalTarget, aspect, originalKey, aliasLabel);
+  }
+
+  private AspectValue createAliasAspect(
+      Environment env,
+      Target originalTarget,
+      Aspect aspect,
+      AspectKey originalKey,
+      Label aliasLabel)
+      throws InterruptedException {
     SkyKey depKey = originalKey.withLabel(aliasLabel);
 
     // Compute the AspectValue of the target the alias refers to (which can itself be either an
@@ -623,7 +634,6 @@
       OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> directDeps,
       @Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution)
       throws AspectFunctionException, InterruptedException {
-
     SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
 
     StoredEventHandler events = new StoredEventHandler();
@@ -634,7 +644,12 @@
     }
 
     ConfiguredAspect configuredAspect;
-    if (AspectResolver.aspectMatchesConfiguredTarget(associatedTarget, aspect)) {
+    if (aspect.getDefinition().applyToGeneratingRules()
+        && associatedTarget.getTarget() instanceof OutputFile) {
+      OutputFile outputFile = (OutputFile) associatedTarget.getTarget();
+      Label label = outputFile.getGeneratingRule().getLabel();
+      return createAliasAspect(env, associatedTarget.getTarget(), aspect, key, label);
+    } else if (AspectResolver.aspectMatchesConfiguredTarget(associatedTarget, aspect)) {
       try {
         CurrentRuleTracker.beginConfiguredAspect(aspect.getAspectClass());
         configuredAspect =