diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/packages')
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(); } /** |