aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/AspectDescriptor.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/AspectParameters.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java29
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java7
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();