Parametrize aspect definition with AspectParameters.

--
MOS_MIGRATED_REVID=106848269
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AspectDefinitionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AspectDefinitionTest.java
index b81f2f2..973a469 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AspectDefinitionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AspectDefinitionTest.java
@@ -52,7 +52,7 @@
     }
 
     @Override
-    public AspectDefinition getDefinition() {
+    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
       return definition;
     }
   }
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 1fee104..33881a8 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
@@ -104,6 +104,28 @@
   }
 
   @Test
+  public void aspectWithParametrizedDefinition() throws Exception {
+    setRules(
+        new TestAspects.BaseRule(),
+        new TestAspects.HonestRule(),
+        new TestAspects.ParametrizedDefinitionAspectRule());
+
+    pkg(
+        "a",
+        "honest(name='q', foo=[])",
+        "parametrized_definition_aspect(name='a', foo=[':b'], baz='//a:q')",
+        "honest(name='c', foo=[])",
+        "honest(name='b', foo=[':c'])");
+
+    ConfiguredTarget a = getConfiguredTarget("//a:a");
+    assertThat(a.getProvider(TestAspects.RuleInfo.class).getData())
+        .containsExactly(
+            "rule //a:a",
+            "aspect //a:b data //a:q $dep:[ //a:q]",
+            "aspect //a:c data //a:q $dep:[ //a:q]");
+  }
+
+  @Test
   public void aspectInError() throws Exception {
     setRules(new TestAspects.BaseRule(), new TestAspects.ErrorAspectRule(),
         new TestAspects.SimpleRule());
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java b/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java
index 1a7a24c..5a190d5 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java
@@ -26,8 +26,7 @@
 import com.google.devtools.build.lib.analysis.util.TestAspects;
 import com.google.devtools.build.lib.analysis.util.TestAspects.AspectRequiringRule;
 import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.AspectDefinition;
-import com.google.devtools.build.lib.packages.AspectParameters;
+import com.google.devtools.build.lib.packages.AspectWithParameters;
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.NativeAspectClass;
 import com.google.devtools.build.lib.packages.NoSuchThingException;
@@ -107,16 +106,14 @@
     update();
   }
 
-  private ListMultimap<Attribute, Dependency> dependentNodeMap(
-      String targetName, Class<? extends ConfiguredAspectFactory> aspect) throws Exception {
-    AspectDefinition aspectDefinition =
-        aspect == null ? null : new NativeAspectClass(aspect).getDefinition();
+  private <T extends ConfiguredNativeAspectFactory>
+    ListMultimap<Attribute, Dependency> dependentNodeMap(
+      String targetName, Class<T> aspect) throws Exception {
     Target target = packageManager.getTarget(reporter, Label.parseAbsolute(targetName));
     return dependencyResolver.dependentNodeMap(
         new TargetAndConfiguration(target, getTargetConfiguration()),
         getHostConfiguration(),
-        aspectDefinition,
-        AspectParameters.EMPTY,
+        aspect != null ? new AspectWithParameters(new NativeAspectClass<T>(aspect)) : null,
         ImmutableSet.<ConfigMatchingProvider>of());
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
index 1b2ffbb..0551f11 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
@@ -23,6 +23,7 @@
 import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
 
 import com.google.common.base.Function;
+import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.Aspect;
@@ -35,20 +36,25 @@
 import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
 import com.google.devtools.build.lib.analysis.Runfiles;
 import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.packages.AspectDefinition;
 import com.google.devtools.build.lib.packages.AspectParameters;
+import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.Rule;
 import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleClass.Builder;
 import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
 import com.google.devtools.build.lib.util.FileTypeSet;
 
+import java.util.List;
+
 /**
  * Various rule and aspect classes that aid in testing the aspect machinery.
  *
@@ -157,7 +163,7 @@
    */
   public static class SimpleAspect extends BaseAspect {
     @Override
-    public AspectDefinition getDefinition() {
+    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
       return SIMPLE_ASPECT;
     }
   }
@@ -178,7 +184,7 @@
    */
   public static class ExtraAttributeAspect extends BaseAspect {
     @Override
-    public AspectDefinition getDefinition() {
+    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
       return EXTRA_ATTRIBUTE_ASPECT;
     }
   }
@@ -192,7 +198,7 @@
    */
   public static class AttributeAspect extends BaseAspect {
     @Override
-    public AspectDefinition getDefinition() {
+    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
       return ATTRIBUTE_ASPECT;
     }
   }
@@ -202,18 +208,64 @@
    */
   public static class ExtraAttributeAspectRequiringProvider extends BaseAspect {
     @Override
-    public AspectDefinition getDefinition() {
+    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
       return EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER;
     }
   }
 
   public static class AspectRequiringProvider extends BaseAspect {
     @Override
-    public AspectDefinition getDefinition() {
+    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
       return ASPECT_REQUIRING_PROVIDER;
     }
   }
 
+  /**
+   * An aspect that has a definition depending on parameters provided by originating rule.
+   */
+  public static class ParametrizedDefinitionAspect implements ConfiguredNativeAspectFactory {
+
+    @Override
+    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
+      AspectDefinition.Builder builder =
+          new AspectDefinition.Builder("parametrized_definition_aspect")
+              .attributeAspect("foo", ParametrizedDefinitionAspect.class);
+      ImmutableCollection<String> baz = aspectParameters.getAttribute("baz");
+      if (baz != null) {
+        try {
+          builder.add(
+              Attribute.attr("$dep", LABEL).value(Label.parseAbsolute(baz.iterator().next())));
+        } catch (LabelSyntaxException e) {
+          throw new IllegalStateException();
+        }
+      }
+      return builder.build();
+    }
+
+    public Aspect create(
+        ConfiguredTarget base, RuleContext ruleContext, AspectParameters parameters) {
+      StringBuilder information = new StringBuilder("aspect " + ruleContext.getLabel());
+      if (!parameters.isEmpty()) {
+        information.append(" data " + Iterables.getFirst(parameters.getAttribute("baz"), null));
+        information.append(" ");
+      }
+      List<? extends TransitiveInfoCollection> deps =
+          ruleContext.getPrerequisites("$dep", Mode.TARGET);
+      information.append("$dep:[");
+      for (TransitiveInfoCollection dep : deps) {
+        information.append(" ");
+        information.append(dep.getLabel());
+      }
+      information.append("]");
+      return new Aspect.Builder(getClass().getName())
+          .addProvider(
+              AspectInfo.class,
+              new AspectInfo(collectAspectData(information.toString(), ruleContext)))
+          .build();
+    }
+  }
+
+
   private static final AspectDefinition ASPECT_REQUIRING_PROVIDER =
       new AspectDefinition.Builder("requiring_provider")
           .requireProvider(RequiredProvider.class)
@@ -231,7 +283,7 @@
     }
 
     @Override
-    public AspectDefinition getDefinition() {
+    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
       return ERROR_ASPECT;
     }
   }
@@ -337,6 +389,46 @@
   }
 
   /**
+   * A rule that defines an {@link ParametrizedDefinitionAspect} on one of its attributes.
+   */
+  public static class ParametrizedDefinitionAspectRule implements RuleDefinition {
+
+    private static final class TestAspectParametersExtractor
+        implements Function<Rule, AspectParameters> {
+      @Override
+      public AspectParameters apply(Rule rule) {
+        if (rule.isAttrDefined("baz", STRING)) {
+          String value = rule.getAttributeContainer().getAttr("baz").toString();
+          if (!value.equals("")) {
+            return new AspectParameters.Builder().addAttribute("baz", value).build();
+          }
+        }
+        return AspectParameters.EMPTY;
+      }
+    }
+
+    @Override
+    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
+      return builder
+          .add(
+              attr("foo", LABEL_LIST)
+                  .allowedFileTypes(FileTypeSet.ANY_FILE)
+                  .aspect(ParametrizedDefinitionAspect.class, new TestAspectParametersExtractor()))
+          .add(attr("baz", STRING))
+          .build();
+    }
+
+    @Override
+    public Metadata getMetadata() {
+      return RuleDefinition.Metadata.builder()
+          .name("parametrized_definition_aspect")
+          .factoryClass(DummyRuleFactory.class)
+          .ancestors(BaseRule.class)
+          .build();
+    }
+  }
+
+  /**
    * A rule that defines an {@link ExtraAttributeAspectRequiringProvider} on one of its attributes.
    */
   public static class ExtraAttributeAspectRequiringProviderRule implements RuleDefinition {