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 {