Aspects can get information from their base rule.

--
MOS_MIGRATED_REVID=102126786
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 b4b055a..461738e 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
@@ -17,6 +17,7 @@
 import static org.junit.Assert.fail;
 
 import com.google.devtools.build.lib.packages.AspectDefinition;
+import com.google.devtools.build.lib.packages.AspectParameters;
 import com.google.devtools.build.lib.packages.Type;
 import com.google.devtools.build.lib.syntax.Label;
 
@@ -46,7 +47,7 @@
     }
 
     @Override
-    public Aspect create(ConfiguredTarget base, RuleContext context) {
+    public Aspect create(ConfiguredTarget base, RuleContext context, AspectParameters parameters) {
       throw new IllegalStateException();
     }
 
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 7d17a98..02b4f3e 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
@@ -137,4 +137,18 @@
     assertThat(a.getProvider(TestAspects.RuleInfo.class).getData())
         .containsExactly("aspect //a:b", "rule //a:a");
   }
+
+  @Test
+  public void informationFromBaseRulePassedToAspect() throws Exception {
+    setRules(new TestAspects.BaseRule(), new TestAspects.HonestRule(),
+        new TestAspects.AspectRequiringProviderRule());
+
+    pkg("a",
+        "aspect_requiring_provider(name='a', foo=[':b'], baz='hello')",
+        "honest(name='b', foo=[])");
+
+    ConfiguredTarget a = getConfiguredTarget("//a:a");
+    assertThat(a.getProvider(TestAspects.RuleInfo.class).getData())
+        .containsExactly("rule //a:a", "aspect //a:b data hello");
+  }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AspectValueTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AspectValueTest.java
index 5365728..2906961 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AspectValueTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AspectValueTest.java
@@ -17,6 +17,7 @@
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
 import com.google.devtools.build.lib.analysis.util.TestAspects;
+import com.google.devtools.build.lib.packages.AspectParameters;
 import com.google.devtools.build.lib.skyframe.AspectValue;
 import com.google.devtools.build.lib.syntax.Label;
 
@@ -51,18 +52,26 @@
     Label l1 = Label.parseAbsolute("//a:l1");
     Label l1b = Label.parseAbsolute("//a:l1");
     Label l2 = Label.parseAbsolute("//a:l2");
+    AspectParameters i1 = new AspectParameters.Builder()
+        .addAttribute("foo", "bar")
+        .build();
+    AspectParameters i2 = new AspectParameters.Builder()
+        .addAttribute("foo", "baz")
+        .build();
     Class<? extends ConfiguredAspectFactory> a1 = TestAspects.AttributeAspect.class;
     Class<? extends ConfiguredAspectFactory> a2 = TestAspects.ExtraAttributeAspect.class;
 
     new EqualsTester()
-        .addEqualityGroup(AspectValue.key(l1, c1, a1), AspectValue.key(l1b, c1, a1))
-        .addEqualityGroup(AspectValue.key(l2, c1, a1))
-        .addEqualityGroup(AspectValue.key(l1, c2, a1))
-        .addEqualityGroup(AspectValue.key(l2, c2, a1))
-        .addEqualityGroup(AspectValue.key(l1, c1, a2))
-        .addEqualityGroup(AspectValue.key(l2, c1, a2))
-        .addEqualityGroup(AspectValue.key(l1, c2, a2))
-        .addEqualityGroup(AspectValue.key(l2, c2, a2))
+        .addEqualityGroup(AspectValue.key(l1, c1, a1, null), AspectValue.key(l1b, c1, a1, null))
+        .addEqualityGroup(AspectValue.key(l1, c1, a1, i1))
+        .addEqualityGroup(AspectValue.key(l1, c1, a1, i2))
+        .addEqualityGroup(AspectValue.key(l2, c1, a1, null))
+        .addEqualityGroup(AspectValue.key(l1, c2, a1, null))
+        .addEqualityGroup(AspectValue.key(l2, c2, a1, null))
+        .addEqualityGroup(AspectValue.key(l1, c1, a2, null))
+        .addEqualityGroup(AspectValue.key(l2, c1, a2, null))
+        .addEqualityGroup(AspectValue.key(l1, c2, a2, null))
+        .addEqualityGroup(AspectValue.key(l2, c2, a2, null))
         .addEqualityGroup(l1)  // A random object
         .testEquals();
   }
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 fc5b156..e149cb8 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
@@ -116,7 +116,7 @@
         new TargetAndConfiguration(target, getTargetConfiguration()),
         getHostConfiguration(),
         aspectDefinition,
-        ImmutableSet.<ConfigMatchingProvider>of());
+        null, ImmutableSet.<ConfigMatchingProvider>of());
   }
 
   @SafeVarargs
@@ -199,15 +199,15 @@
     BuildConfiguration host = getHostConfiguration();
     BuildConfiguration target = getTargetConfiguration();
 
-    ImmutableSet<Class<? extends ConfiguredAspectFactory>> twoAspects =
-        ImmutableSet.<Class<? extends ConfiguredAspectFactory>>of(
-            TestAspects.SimpleAspect.class, TestAspects.AttributeAspect.class);
-    ImmutableSet<Class<? extends ConfiguredAspectFactory>> inverseAspects =
-        ImmutableSet.<Class<? extends ConfiguredAspectFactory>>of(
-            TestAspects.AttributeAspect.class, TestAspects.SimpleAspect.class);
-    ImmutableSet<Class<? extends ConfiguredAspectFactory>> differentAspects =
-        ImmutableSet.<Class<? extends ConfiguredAspectFactory>>of(
-            TestAspects.AttributeAspect.class, TestAspects.ErrorAspect.class);
+    ImmutableSet<AspectWithParameters> twoAspects = ImmutableSet.of(
+        new AspectWithParameters(TestAspects.SimpleAspect.class), 
+        new AspectWithParameters(TestAspects.AttributeAspect.class));
+    ImmutableSet<AspectWithParameters> inverseAspects = ImmutableSet.of(
+        new AspectWithParameters(TestAspects.AttributeAspect.class), 
+        new AspectWithParameters(TestAspects.SimpleAspect.class));
+    ImmutableSet<AspectWithParameters> differentAspects = ImmutableSet.of(
+        new AspectWithParameters(TestAspects.AttributeAspect.class), 
+        new AspectWithParameters(TestAspects.ErrorAspect.class));
 
     new EqualsTester()
         .addEqualityGroup(
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 7f7d05b..7068278 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -84,6 +84,7 @@
 import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.events.StoredEventHandler;
 import com.google.devtools.build.lib.exec.ExecutionOptions;
+import com.google.devtools.build.lib.packages.AspectParameters;
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
 import com.google.devtools.build.lib.packages.AttributeMap;
 import com.google.devtools.build.lib.packages.ConstantRuleVisibility;
@@ -861,9 +862,9 @@
    * Gets a derived Artifact for testing in the subdirectory of the {@link
    * BuildConfiguration#getBinDirectory()} corresponding to the package of {@code owner},
    * where the given artifact belongs to the given ConfiguredTarget together with the given Aspect.
-   * So to specify a file foo/foo.o owned by target //foo:foo with an apsect from FooAspect,
+   * So to specify a file foo/foo.o owned by target //foo:foo with an aspect from FooAspect,
    * {@code packageRelativePath} should just be "foo.o", and aspectOfOwner should be
-   * FooAspect.class. This method is necessary when an Apsect of the target, not the target itself,
+   * FooAspect.class. This method is necessary when an Aspect of the target, not the target itself,
    * is creating an Artifact.
    */
   protected Artifact getBinArtifact(String packageRelativePath, ConfiguredTarget owner,
@@ -871,7 +872,8 @@
     return getPackageRelativeDerivedArtifact(packageRelativePath,
         owner.getConfiguration().getBinDirectory(),
         (AspectValue.AspectKey) AspectValue.key(
-            owner.getLabel(), owner.getConfiguration(), creatingAspectFactory).argument());
+            owner.getLabel(), owner.getConfiguration(), creatingAspectFactory,
+            AspectParameters.EMPTY).argument());
   }
 
   /**
@@ -930,7 +932,8 @@
     return getPackageRelativeDerivedArtifact(packageRelativePath,
         owner.getConfiguration().getGenfilesDirectory(),
         (AspectValue.AspectKey) AspectValue.key(
-            owner.getLabel(), owner.getConfiguration(), creatingAspectFactory).argument());
+            owner.getLabel(), owner.getConfiguration(), creatingAspectFactory,
+            AspectParameters.EMPTY).argument());
   }
 
   /**
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 bf564fb..ffea8bc 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
@@ -22,6 +22,8 @@
 import static com.google.devtools.build.lib.packages.Type.STRING;
 import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.Aspect;
 import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory;
@@ -39,6 +41,8 @@
 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.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;
@@ -131,11 +135,16 @@
    */
   public abstract static class BaseAspect implements ConfiguredAspectFactory {
     @Override
-    public Aspect create(ConfiguredTarget base, RuleContext ruleContext) {
+    public Aspect create(ConfiguredTarget base, RuleContext ruleContext,
+        AspectParameters parameters) {
+      String information = parameters.isEmpty()
+          ? ""
+          : " data " + Iterables.getFirst(parameters.getAttribute("baz"), null);
       return new Aspect.Builder(getClass().getName())
           .addProvider(
               AspectInfo.class,
-              new AspectInfo(collectAspectData("aspect " + ruleContext.getLabel(), ruleContext)))
+              new AspectInfo(collectAspectData("aspect " + ruleContext.getLabel() + information, 
+                  ruleContext)))
           .build();
     }
   }
@@ -215,7 +224,8 @@
    */
   public static class ErrorAspect implements ConfiguredAspectFactory {
     @Override
-    public Aspect create(ConfiguredTarget base, RuleContext ruleContext) {
+    public Aspect create(ConfiguredTarget base, RuleContext ruleContext,
+        AspectParameters parameters) {
       ruleContext.ruleError("Aspect error");
       return null;
     }
@@ -290,11 +300,25 @@
    * A rule that defines an {@link AspectRequiringProvider} on one of its attributes.
    */
   public static class AspectRequiringProviderRule implements RuleDefinition {
+
+    private static final class TestAspectParametersExtractor implements 
+        Function<Rule, AspectParameters> {
+      @Override
+      public AspectParameters apply(Rule rule) {
+        if (rule.isAttrDefined("baz", STRING)) {
+          return new AspectParameters.Builder().addAttribute("baz",
+              rule.getAttributeContainer().getAttr("baz").toString()).build();
+        }
+        return AspectParameters.EMPTY;
+      }
+    }
+
     @Override
     public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
       return builder
           .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(AspectRequiringProvider.class))
+              .aspect(AspectRequiringProvider.class, new TestAspectParametersExtractor()))
+          .add(attr("baz", STRING))
           .build();
 
     }