aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/packages
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/packages')
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/AspectParameters.java93
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/Attribute.java71
3 files changed, 160 insertions, 8 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java b/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java
index b375dd9b00..a92084bb6e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java
@@ -26,8 +26,10 @@ public interface AspectFactory<TConfiguredTarget, TRuleContext, TAspect> {
* @param base the configured target of the associated rule
* @param context the context of the associated configured target plus all the attributes the
* aspect itself has defined
+ * @param parameters information from attributes of the rule that have requested this
+ * aspect
*/
- TAspect create(TConfiguredTarget base, TRuleContext context);
+ TAspect create(TConfiguredTarget base, TRuleContext context, AspectParameters parameters);
/**
* Returns the definition of the aspect.
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectParameters.java b/src/main/java/com/google/devtools/build/lib/packages/AspectParameters.java
new file mode 100644
index 0000000000..69f82ceca1
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectParameters.java
@@ -0,0 +1,93 @@
+// Copyright 2015 Google Inc. 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.packages;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+
+import java.util.Objects;
+
+import javax.annotation.Nullable;
+
+/**
+ * Objects of this class contain values of some attributes of rules. Used for passing this
+ * information to the aspects.
+ */
+public final class AspectParameters {
+ private final ImmutableMultimap<String, String> attributes;
+
+ private AspectParameters(Multimap<String, String> attributes) {
+ this.attributes = ImmutableMultimap.copyOf(attributes);
+ }
+
+ public static final AspectParameters EMPTY = new AspectParameters.Builder().build();
+
+ /**
+ * A builder for @{link {@link AspectParameters} class.
+ */
+ public static class Builder {
+ private final Multimap<String, String> attributes = ArrayListMultimap.create();
+
+ /**
+ * Adds a new pair of attribute-value.
+ */
+ public Builder addAttribute(String name, String value) {
+ attributes.put(name, value);
+ return this;
+ }
+
+ /**
+ * Creates a new instance of {@link AspectParameters} class.
+ */
+ public AspectParameters build() {
+ return new AspectParameters(attributes);
+ }
+ }
+
+ /**
+ * Returns collection of values for specified key, or null if key is missing.
+ */
+ @Nullable
+ public ImmutableCollection<String> getAttribute(String key) {
+ return attributes.get(key);
+ }
+
+ public boolean isEmpty() {
+ return this.equals(AspectParameters.EMPTY);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof AspectParameters)) {
+ return false;
+ }
+ AspectParameters that = (AspectParameters) other;
+ return Objects.equals(this.attributes, that.attributes);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(attributes);
+ }
+
+ @Override
+ public String toString() {
+ return attributes.toString();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
index 7d06129e6b..391a1da7b6 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
@@ -15,10 +15,12 @@
package com.google.devtools.build.lib.packages;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
@@ -57,6 +59,26 @@ public final class Attribute implements Comparable<Attribute> {
public static final Predicate<RuleClass> NO_RULE = Predicates.alwaysFalse();
+ private static final class RuleAspect {
+ private final Class<? extends AspectFactory<?, ?, ?>> aspectFactory;
+ private final Function<Rule, AspectParameters> parametersExtractor;
+
+ RuleAspect(
+ Class<? extends AspectFactory<?, ?, ?>> aspectFactory,
+ Function<Rule, AspectParameters> parametersExtractor) {
+ this.aspectFactory = aspectFactory;
+ this.parametersExtractor = parametersExtractor;
+ }
+
+ Class<? extends AspectFactory<?, ?, ?>> getAspectFactory() {
+ return aspectFactory;
+ }
+
+ Function<Rule, AspectParameters> getParametersExtractor() {
+ return parametersExtractor;
+ }
+ }
+
/**
* A configuration transition.
*/
@@ -274,7 +296,7 @@ public final class Attribute implements Comparable<Attribute> {
private Set<PropertyFlag> propertyFlags = EnumSet.noneOf(PropertyFlag.class);
private PredicateWithMessage<Object> allowedValues = null;
private ImmutableSet<String> mandatoryProviders = ImmutableSet.<String>of();
- private Set<Class<? extends AspectFactory<?, ?, ?>>> aspects = new LinkedHashSet<>();
+ private Set<RuleAspect> aspects = new LinkedHashSet<>();
/**
* Creates an attribute builder with given name and type. This attribute is optional, uses
@@ -641,13 +663,31 @@ public final class Attribute implements Comparable<Attribute> {
}
/**
- * Asserts that a particular aspect needs to be computed for all direct dependencies through
- * this attribute.
+ * Asserts that a particular aspect probably needs to be computed for all direct dependencies
+ * through this attribute.
*/
public Builder<TYPE> aspect(Class<? extends AspectFactory<?, ?, ?>> aspect) {
- this.aspects.add(aspect);
+ Function<Rule, AspectParameters> noParameters = new Function<Rule, AspectParameters>() {
+ @Override
+ public AspectParameters apply(Rule input) {
+ return AspectParameters.EMPTY;
+ }
+ };
+ return this.aspect(aspect, noParameters);
+ }
+
+ /**
+ * Asserts that a particular parameterized aspect probably needs to be computed for all direct
+ * dependencies through this attribute.
+ *
+ * @param evaluator function that extracts aspect parameters from rule.
+ */
+ public Builder<TYPE> aspect(Class<? extends AspectFactory<?, ?, ?>> aspect,
+ Function<Rule, AspectParameters> evaluator) {
+ this.aspects.add(new RuleAspect(aspect, evaluator));
return this;
}
+
/**
* Sets the predicate-like edge validity checker.
*/
@@ -1001,7 +1041,7 @@ public final class Attribute implements Comparable<Attribute> {
private final ImmutableSet<String> mandatoryProviders;
- private final ImmutableSet<Class<? extends AspectFactory<?, ?, ?>>> aspects;
+ private final ImmutableSet<RuleAspect> aspects;
/**
* Constructs a rule attribute with the specified name, type and default
@@ -1028,7 +1068,7 @@ public final class Attribute implements Comparable<Attribute> {
Predicate<AttributeMap> condition,
PredicateWithMessage<Object> allowedValues,
ImmutableSet<String> mandatoryProviders,
- ImmutableSet<Class<? extends AspectFactory<?, ?, ?>>> aspects) {
+ ImmutableSet<RuleAspect> aspects) {
Preconditions.checkNotNull(configTransition);
Preconditions.checkArgument(
(configTransition == ConfigurationTransition.NONE && configurator == null)
@@ -1252,7 +1292,24 @@ public final class Attribute implements Comparable<Attribute> {
* Returns the set of aspects required for dependencies through this attribute.
*/
public ImmutableSet<Class<? extends AspectFactory<?, ?, ?>>> getAspects() {
- return aspects;
+ ImmutableSet.Builder<Class<? extends AspectFactory<?, ?, ?>>> builder = ImmutableSet.builder();
+ for (RuleAspect aspect : aspects) {
+ builder.add(aspect.getAspectFactory());
+ }
+ return builder.build();
+ }
+
+ /**
+ * Returns set of pairs of aspect factories and corresponding aspect parameters.
+ */
+ public ImmutableMap<Class<? extends AspectFactory<?, ?, ?>>, AspectParameters>
+ getAspectsWithParameters(Rule rule) {
+ ImmutableMap.Builder<Class<? extends AspectFactory<?, ?, ?>>, AspectParameters> builder =
+ ImmutableMap.builder();
+ for (RuleAspect aspect : aspects) {
+ builder.put(aspect.getAspectFactory(), aspect.getParametersExtractor().apply(rule));
+ }
+ return builder.build();
}
/**