diff options
Diffstat (limited to 'src/main')
10 files changed, 94 insertions, 20 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java index 39d6221aa6..ca99ef1635 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java @@ -117,6 +117,8 @@ public abstract class AbstractConfiguredTarget // accessible in Skylark. return SkylarkNestedSet.of( Artifact.class, getProvider(FileProvider.class).getFilesToBuild()); + case ASPECTS_FIELD: + return ImmutableList.<String>of(); case DEFAULT_RUNFILES_FIELD: return RunfilesProvider.DEFAULT_RUNFILES.apply(this); case DATA_RUNFILES_FIELD: @@ -172,6 +174,7 @@ public abstract class AbstractConfiguredTarget @Override public ImmutableCollection<String> getKeys() { - return ImmutableList.of(DATA_RUNFILES_FIELD, DEFAULT_RUNFILES_FIELD, LABEL_FIELD, FILES_FIELD); + return ImmutableList.of( + DATA_RUNFILES_FIELD, DEFAULT_RUNFILES_FIELD, LABEL_FIELD, FILES_FIELD, ASPECTS_FIELD); } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AspectDescriptor.java b/src/main/java/com/google/devtools/build/lib/analysis/AspectDescriptor.java index 7a43323362..2f56abbc15 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/AspectDescriptor.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/AspectDescriptor.java @@ -14,10 +14,12 @@ package com.google.devtools.build.lib.analysis; +import com.google.common.collect.ImmutableMultimap; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.packages.AspectClass; import com.google.devtools.build.lib.packages.AspectParameters; - +import com.google.protobuf.TextFormat; +import java.util.Map.Entry; import java.util.Objects; /** @@ -67,4 +69,35 @@ public final class AspectDescriptor { return Objects.equals(aspectClass, that.aspectClass) && Objects.equals(aspectParameters, that.aspectParameters); } + + /** + * Creates a presentable description of this aspect, avaliable + * to Skylark via "Target.aspects". + * + * The description is designed to be unique for each aspect descriptor, + * but not to be parseable. + */ + public String getDescription() { + if (aspectParameters.isEmpty()) { + return aspectClass.getName(); + } + + StringBuilder builder = new StringBuilder(aspectClass.getName()); + builder.append('['); + ImmutableMultimap<String, String> attributes = aspectParameters.getAttributes(); + boolean first = true; + for (Entry<String, String> attribute : attributes.entries()) { + if (!first) { + builder.append(','); + } else { + first = false; + } + builder.append(attribute.getKey()); + builder.append("=\""); + builder.append(TextFormat.escapeDoubleQuotesAndBackslashes(attribute.getValue())); + builder.append("\""); + } + builder.append(']'); + return builder.toString(); + } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java index 155110cc2f..e341991c1e 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java @@ -16,7 +16,6 @@ package com.google.devtools.build.lib.analysis; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.packages.Target; - import javax.annotation.Nullable; /** @@ -37,6 +36,11 @@ public interface ConfiguredTarget extends TransitiveInfoCollection { String LABEL_FIELD = "label"; /** + * All <code>ConfiguredTarget</code>s have a "aspect_ids" field. + */ + String ASPECTS_FIELD = "aspect_ids"; + + /** * All <code>ConfiguredTarget</code>s have a "files" field. */ String FILES_FIELD = "files"; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java index e2b21eb75e..e067612835 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java @@ -85,6 +85,18 @@ public final class MergedConfiguredTarget extends AbstractConfiguredTarget { return aspects; } + @Override + public Object getValue(String name) { + if (ASPECTS_FIELD.equals(name)) { + ImmutableList.Builder<String> builder = ImmutableList.builder(); + for (AspectDescriptor aspect : aspects) { + builder.add(aspect.getDescription()); + } + return builder.build(); + } + return super.getValue(name); + } + /** Creates an instance based on a configured target and a set of aspects. */ public static ConfiguredTarget of(ConfiguredTarget base, Iterable<ConfiguredAspect> aspects) throws DuplicateException { @@ -123,7 +135,7 @@ public final class MergedConfiguredTarget extends AbstractConfiguredTarget { aspectProviders.add(mergedExtraActionProviders); } - ImmutableList.Builder<AspectDescriptor> aspectRepresentations = ImmutableList.builder(); + ImmutableList.Builder<AspectDescriptor> aspectDescriptors = ImmutableList.builder(); for (ConfiguredAspect aspect : aspects) { for (Map.Entry<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> entry : @@ -140,11 +152,10 @@ public final class MergedConfiguredTarget extends AbstractConfiguredTarget { } aspectProviders.add(entry.getValue()); - aspectRepresentations.add(aspect.getDescriptor()); } - + aspectDescriptors.add(aspect.getDescriptor()); } - return new MergedConfiguredTarget(base, aspectRepresentations.build(), aspectProviders.build()); + return new MergedConfiguredTarget(base, aspectDescriptors.build(), aspectProviders.build()); } private static <T extends TransitiveInfoProvider> List<T> getAllProviders( diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java index 9984f54e53..ed5f9d6ee0 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java @@ -50,6 +50,9 @@ import javax.annotation.Nullable; + "<li><h3 id=\"modules.Target.files\">files</h3><code><a class=\"anchor\" " + "href=\"set.html\">set</a> Target.files </code><br>The set of <a class=\"anchor\" " + "href=\"File.html\">File</a>s produced directly by this target.</li>" + + "<li><h3 id=\"modules.Target.aspect_ids\">aspect_ids</h3><code><a class=\"anchor\"" + + "href=\"list.html\">list</a> Target.aspect_ids </code><br>The list of <a class=\"anchor\" " + + "href=\"ctx.html#aspect_id\">aspect_id</a>s applied to this target.</li>" + "<li><h3 id=\"modules.Target.extraproviders\">Extra providers</h3>For rule targets all " + "additional providers provided by this target are accessible as <code>struct</code> fields. " + "These extra providers are defined in the <code>struct</code> returned by the rule " diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java index bda14e9002..0878b2c762 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java +++ b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java @@ -73,6 +73,7 @@ public final class AspectDefinition { @Nullable ConfigurationFragmentPolicy configurationFragmentPolicy) { this.aspectClass = aspectClass; this.requiredProviderSets = requiredProviderSets; + this.attributes = attributes; this.attributeAspects = attributeAspects; this.configurationFragmentPolicy = configurationFragmentPolicy; 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 index 15ef2bb372..81d003300e 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/AspectParameters.java +++ b/src/main/java/com/google/devtools/build/lib/packages/AspectParameters.java @@ -15,7 +15,6 @@ package com.google.devtools.build.lib.packages; import static com.google.common.collect.Iterables.getOnlyElement; -import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; @@ -38,7 +37,8 @@ public final class AspectParameters { * A builder for @{link {@link AspectParameters} class. */ public static class Builder { - private final Multimap<String, String> attributes = ArrayListMultimap.create(); + private final ImmutableMultimap.Builder<String, String> attributes = + ImmutableMultimap.builder(); /** * Adds a new pair of attribute-value. @@ -52,7 +52,7 @@ public final class AspectParameters { * Creates a new instance of {@link AspectParameters} class. */ public AspectParameters build() { - return new AspectParameters(attributes); + return new AspectParameters(attributes.build()); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java index a6363b7659..458fba16d1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java +++ b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java @@ -127,6 +127,9 @@ public final class AliasConfiguredTarget implements ConfiguredTarget, ClassObjec ? NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER) : getProvider(FileProvider.class).getFilesToBuild()); } + if (actual instanceof ClassObject) { + return ((ClassObject) actual).getValue(name); + } return actual == null ? null : actual.get(name); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java index b68130d15e..5042338d5f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java +++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Root; import com.google.devtools.build.lib.analysis.ActionsProvider; import com.google.devtools.build.lib.analysis.AnalysisUtils; +import com.google.devtools.build.lib.analysis.AspectDescriptor; import com.google.devtools.build.lib.analysis.ConfigurationMakeVariableContext; import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.LabelExpander; @@ -45,7 +46,6 @@ import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SkylarkImp import com.google.devtools.build.lib.packages.OutputFile; import com.google.devtools.build.lib.packages.Package; import com.google.devtools.build.lib.packages.RawAttributeMapper; -import com.google.devtools.build.lib.packages.SkylarkAspect; import com.google.devtools.build.lib.packages.SkylarkClassObject; import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor; import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; @@ -146,7 +146,7 @@ public final class SkylarkRuleContext { private final FragmentCollection fragments; private final FragmentCollection hostFragments; - private final SkylarkAspect skylarkAspect; + private final AspectDescriptor aspectDescriptor; private final SkylarkDict<String, String> makeVariables; private final SkylarkRuleAttributesCollection attributesCollection; @@ -158,18 +158,18 @@ public final class SkylarkRuleContext { /** * Creates a new SkylarkRuleContext using ruleContext. - * @param skylarkAspect aspect for which the context is created, or <code>null</code> + * @param aspectDescriptor aspect for which the context is created, or <code>null</code> * if it is for a rule. * @throws InterruptedException */ - public SkylarkRuleContext(RuleContext ruleContext, @Nullable SkylarkAspect skylarkAspect) + public SkylarkRuleContext(RuleContext ruleContext, @Nullable AspectDescriptor aspectDescriptor) throws EvalException, InterruptedException { this.ruleContext = Preconditions.checkNotNull(ruleContext); this.fragments = new FragmentCollection(ruleContext, ConfigurationTransition.NONE); this.hostFragments = new FragmentCollection(ruleContext, ConfigurationTransition.HOST); - this.skylarkAspect = skylarkAspect; + this.aspectDescriptor = aspectDescriptor; - if (skylarkAspect == null) { + if (aspectDescriptor == null) { Collection<Attribute> attributes = ruleContext.getRule().getAttributes(); HashMap<String, Object> outputsBuilder = new HashMap<>(); if (ruleContext.getRule().getRuleClassObject().outputsDefaultExecutable()) { @@ -248,8 +248,8 @@ public final class SkylarkRuleContext { } @Nullable - public SkylarkAspect getSkylarkAspect() { - return skylarkAspect; + public AspectDescriptor getAspectDescriptor() { + return aspectDescriptor; } private Function<Attribute, Object> attributeValueExtractorForRule( @@ -587,6 +587,19 @@ public final class SkylarkRuleContext { } @SkylarkCallable(structField = true, + name = "aspect_id", + doc = "Returns a string uniquely identifying this aspect" + + " Only available in aspect implementation functions.") + public String aspectId() throws EvalException { + if (ruleAttributesCollection == null) { + throw new EvalException( + Location.BUILTIN, "'aspect' is only available in aspect implementations"); + } + return aspectDescriptor.getDescription(); + } + + + @SkylarkCallable(structField = true, doc = "Dictionary (String to String) of configuration variables") public SkylarkDict<String, String> var() { return makeVariables; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java index f078c3a154..2608c7f535 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.analysis.AspectDescriptor; import com.google.devtools.build.lib.analysis.ConfiguredAspect; import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory; import com.google.devtools.build.lib.analysis.ConfiguredTarget; @@ -50,9 +51,11 @@ public class SkylarkAspectFactory implements ConfiguredAspectFactory { ConfiguredTarget base, RuleContext ruleContext, AspectParameters parameters) throws InterruptedException { try (Mutability mutability = Mutability.create("aspect")) { + AspectDescriptor aspectDescriptor = new AspectDescriptor( + skylarkAspect.getAspectClass(), parameters); SkylarkRuleContext skylarkRuleContext; try { - skylarkRuleContext = new SkylarkRuleContext(ruleContext, skylarkAspect); + skylarkRuleContext = new SkylarkRuleContext(ruleContext, aspectDescriptor); } catch (EvalException e) { ruleContext.ruleError(e.getMessage()); return null; @@ -82,7 +85,7 @@ public class SkylarkAspectFactory implements ConfiguredAspectFactory { } ConfiguredAspect.Builder builder = new ConfiguredAspect.Builder( - skylarkAspect.getAspectClass(), parameters, ruleContext); + aspectDescriptor, ruleContext); SkylarkClassObject struct = (SkylarkClassObject) aspectSkylarkObject; Location loc = struct.getCreationLoc(); |