aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar vladmos <vladmos@google.com>2017-04-11 11:14:22 +0000
committerGravatar Jakob Buchgraber <buchgr@google.com>2017-04-11 13:50:44 +0200
commit360fb4d9a1e2c44154b17aeb866e07bac2dd1b5b (patch)
tree7a61fc7be99320496a50780807945271d4a6c586 /src/main/java/com/google
parent1dadb878a59b180bf950c72ee3b4bdb8d7ea7d67 (diff)
Implement default provider
Default providers can now be used not only to return standard providers values from a rule implementation function, but also to access these values provided by other rules. PiperOrigin-RevId: 152797193
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java25
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java58
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java20
7 files changed, 115 insertions, 44 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 d32b279b49..f5313b8ca0 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
@@ -16,7 +16,6 @@ package com.google.devtools.build.lib.analysis;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -27,10 +26,10 @@ import com.google.devtools.build.lib.packages.ClassObjectConstructor;
import com.google.devtools.build.lib.packages.PackageSpecification;
import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.rules.SkylarkRuleContext;
import com.google.devtools.build.lib.syntax.ClassObject;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
-import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import javax.annotation.Nullable;
/**
@@ -108,19 +107,17 @@ public abstract class AbstractConfiguredTarget
@Override
public Object getValue(String name) {
+ // Standard fields should be proxied to their default provider object
+ DefaultProvider defaultProvider =
+ (DefaultProvider) get(SkylarkRuleContext.getDefaultProvider().getKey());
switch (name) {
- case LABEL_FIELD:
- return getLabel();
case FILES_FIELD:
- // A shortcut for files to build in Skylark. FileConfiguredTarget and RuleConfiguredTarget
- // always has FileProvider and Error- and PackageGroupConfiguredTarget-s shouldn't be
- // accessible in Skylark.
- return SkylarkNestedSet.of(
- Artifact.class, getProvider(FileProvider.class).getFilesToBuild());
case DEFAULT_RUNFILES_FIELD:
- return RunfilesProvider.DEFAULT_RUNFILES.apply(this);
case DATA_RUNFILES_FIELD:
- return RunfilesProvider.DATA_RUNFILES.apply(this);
+ case FilesToRunProvider.SKYLARK_NAME:
+ return defaultProvider.getValue(name);
+ case LABEL_FIELD:
+ return getLabel();
default:
return get(name);
}
@@ -173,6 +170,10 @@ public abstract class AbstractConfiguredTarget
@Override
public ImmutableCollection<String> getKeys() {
return ImmutableList.of(
- DATA_RUNFILES_FIELD, DEFAULT_RUNFILES_FIELD, LABEL_FIELD, FILES_FIELD);
+ DATA_RUNFILES_FIELD,
+ DEFAULT_RUNFILES_FIELD,
+ LABEL_FIELD,
+ FILES_FIELD,
+ FilesToRunProvider.SKYLARK_NAME);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java
new file mode 100644
index 0000000000..c0c2a317a4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java
@@ -0,0 +1,58 @@
+// Copyright 2017 The Bazel Authors. 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.analysis;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.rules.SkylarkRuleContext;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import java.util.Map;
+
+/** DefaultProvider is provided by all targets implicitly and contains all standard fields. */
+@Immutable
+public final class DefaultProvider extends SkylarkClassObject {
+
+ // Accessors for Skylark
+ private static final String DATA_RUNFILES_FIELD = "data_runfiles";
+ private static final String DEFAULT_RUNFILES_FIELD = "default_runfiles";
+ private static final String FILES_FIELD = "files";
+
+ private DefaultProvider(ClassObjectConstructor constructor, Map<String, Object> values) {
+ super(constructor, values);
+ }
+
+ public static DefaultProvider build(
+ RunfilesProvider runfilesProvider,
+ FileProvider fileProvider,
+ FilesToRunProvider filesToRunProvider) {
+ ImmutableMap.Builder<String, Object> attrBuilder = new ImmutableMap.Builder<>();
+ if (runfilesProvider != null) {
+ attrBuilder.put(DATA_RUNFILES_FIELD, runfilesProvider.getDataRunfiles());
+ attrBuilder.put(DEFAULT_RUNFILES_FIELD, runfilesProvider.getDefaultRunfiles());
+ } else {
+ attrBuilder.put(DATA_RUNFILES_FIELD, Runfiles.EMPTY);
+ attrBuilder.put(DEFAULT_RUNFILES_FIELD, Runfiles.EMPTY);
+ }
+
+ attrBuilder.put(
+ FILES_FIELD, SkylarkNestedSet.of(Artifact.class, fileProvider.getFilesToBuild()));
+ attrBuilder.put(FilesToRunProvider.SKYLARK_NAME, filesToRunProvider);
+
+ ClassObjectConstructor constructor = SkylarkRuleContext.getDefaultProvider();
+ return new DefaultProvider(constructor, attrBuilder.build());
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
index 0bc9b5342b..0fe798b6d8 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.analysis;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -21,6 +22,7 @@ import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.ClassObjectConstructor;
import com.google.devtools.build.lib.packages.FileTarget;
import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.rules.SkylarkRuleContext;
import com.google.devtools.build.lib.rules.fileset.FilesetProvider;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider;
import com.google.devtools.build.lib.util.FileType;
@@ -40,12 +42,22 @@ public abstract class FileConfiguredTarget extends AbstractConfiguredTarget
super(targetContext);
NestedSet<Artifact> filesToBuild = NestedSetBuilder.create(Order.STABLE_ORDER, artifact);
this.artifact = artifact;
+ FileProvider fileProvider = new FileProvider(filesToBuild);
+ FilesToRunProvider filesToRunProvider =
+ FilesToRunProvider.fromSingleExecutableArtifact(artifact);
+ SkylarkClassObject defaultProvider =
+ DefaultProvider.build(null, fileProvider, filesToRunProvider);
+ SkylarkProviders skylarkProviders =
+ new SkylarkProviders(
+ ImmutableMap.<String, Object>of(),
+ ImmutableMap.of(SkylarkRuleContext.getDefaultProvider().getKey(), defaultProvider));
TransitiveInfoProviderMap.Builder builder =
TransitiveInfoProviderMap.builder()
.put(VisibilityProvider.class, this)
.put(LicensesProvider.class, this)
- .add(new FileProvider(filesToBuild))
- .add(FilesToRunProvider.fromSingleExecutableArtifact(artifact));
+ .put(SkylarkProviders.class, skylarkProviders)
+ .add(fileProvider)
+ .add(filesToRunProvider);
if (this instanceof FilesetProvider) {
builder.put(FilesetProvider.class, this);
}
@@ -86,6 +98,6 @@ public abstract class FileConfiguredTarget extends AbstractConfiguredTarget
@Nullable
@Override
public SkylarkClassObject get(ClassObjectConstructor.Key providerKey) {
- return null;
+ return getProvider(SkylarkProviders.class).getDeclaredProvider(providerKey);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
index 51954c137c..7ba2eff806 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
@@ -53,7 +53,7 @@ import javax.annotation.Nullable;
@Immutable
public final class OutputGroupProvider implements
TransitiveInfoProvider, SkylarkIndexable, Iterable<String> {
- public static String SKYLARK_NAME = "output_groups";
+ public static final String SKYLARK_NAME = "output_groups";
/**
* Prefix for output groups that are not reported to the user on the terminal output of Blaze when
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
index 9bab0463af..077e2ec5e5 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
@@ -92,7 +92,6 @@ public final class RuleConfiguredTargetBuilder {
getFilesToRun(runfilesSupport, filesToBuild), runfilesSupport, executable);
addProvider(new FileProvider(filesToBuild));
addProvider(filesToRunProvider);
- addSkylarkTransitiveInfo(FilesToRunProvider.SKYLARK_NAME, filesToRunProvider);
if (runfilesSupport != null) {
// If a binary is built, build its runfiles, too
@@ -136,6 +135,14 @@ public final class RuleConfiguredTargetBuilder {
addSkylarkTransitiveInfo(OutputGroupProvider.SKYLARK_NAME, outputGroupProvider);
}
+ // Populate default provider fields and build it
+ DefaultProvider defaultProvider =
+ DefaultProvider.build(
+ providersBuilder.getProvider(RunfilesProvider.class),
+ providersBuilder.getProvider(FileProvider.class),
+ filesToRunProvider);
+ skylarkDeclaredProviders.put(defaultProvider.getConstructor().getKey(), defaultProvider);
+
TransitiveInfoProviderMap providers = providersBuilder.build();
addRegisteredProvidersToSkylarkProviders(providers);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
index c3f6954312..6f0ac7f0a3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.rules;
-import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
@@ -270,7 +269,7 @@ public final class SkylarkRuleConfiguredTargetBuilder {
}
if (!isParsed) {
- addSimpleProviders(builder, ruleContext, loc, executable, null, null, null, null);
+ addSimpleProviders(builder, ruleContext, loc, executable, null, null, null);
}
try {
@@ -365,18 +364,19 @@ public final class SkylarkRuleConfiguredTargetBuilder {
}
}
- addSimpleProviders(builder, ruleContext, loc, executable, statelessRunfiles, dataRunfiles,
- defaultRunfiles, (isDefaultProvider ? provider : null));
+ addSimpleProviders(
+ builder, ruleContext, loc, executable, statelessRunfiles, dataRunfiles, defaultRunfiles);
}
- private static void addSimpleProviders(RuleConfiguredTargetBuilder builder,
+ private static void addSimpleProviders(
+ RuleConfiguredTargetBuilder builder,
RuleContext ruleContext,
Location loc,
Artifact executable,
Runfiles statelessRunfiles,
Runfiles dataRunfiles,
- Runfiles defaultRunfiles,
- SkylarkClassObject defaultProvider) throws EvalException {
+ Runfiles defaultRunfiles)
+ throws EvalException {
if ((statelessRunfiles != null) && (dataRunfiles != null || defaultRunfiles != null)) {
throw new EvalException(loc, "Cannot specify the provider 'runfiles' "
@@ -414,19 +414,6 @@ public final class SkylarkRuleConfiguredTargetBuilder {
ruleContext.getAnalysisEnvironment().getRegisteredActions());
builder.addSkylarkDeclaredProvider(actions, loc);
}
-
- // Populate default provider fields and build it
- ImmutableMap.Builder<String, Object> attrBuilder = new ImmutableMap.Builder<>();
- // TODO: Add actual attributes that users expect to access from default providers
- attrBuilder.put("runfiles", runfilesProvider);
- SkylarkClassObject statelessDefaultProvider =
- new SkylarkClassObject(
- SkylarkRuleContext.getDefaultProvider(),
- attrBuilder.build());
-
- // Add the default provider
- builder.addSkylarkDeclaredProvider(statelessDefaultProvider, (defaultProvider == null) ? loc
- : Optional.fromNullable(defaultProvider.getCreationLocOrNull()).or(loc));
}
private static <T> T cast(String paramName, ClassObject struct, Class<T> expectedGenericType,
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 76ac1a99bf..de8d3de361 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
@@ -594,13 +594,19 @@ public final class SkylarkRuleContext implements SkylarkValue {
}
};
- @SkylarkCallable(name = "default_provider", structField = true,
- doc = "A provider that's provided by every rule, even if it's not returned explicitly. "
- + "A <code>default_provider</code> accepts all special parameters that can be returned "
- + "from rule implementation function in a struct, which are <code>runfiles</code>, "
- + "<code>data_runfiles</code>, <code>default_runfiles</code>, "
- + "<code>output_groups</code>, <code>instrumented_files</code>, and all "
- + "<a href=\"skylark-provider.html\">providers</a> that are available on built-in rules.")
+ @SkylarkCallable(
+ name = "default_provider",
+ structField = true,
+ doc = "A provider that's provided by every rule, even if it's not returned explicitly. "
+ + "A <code>default_provider</code> accepts all special parameters that can be returned "
+ + "from rule implementation function in a struct, which are <code>runfiles</code>, "
+ + "<code>data_runfiles</code>, <code>default_runfiles</code>, "
+ + "<code>output_groups</code>, <code>instrumented_files</code>, and all "
+ + "<a href=\"skylark-provider.html\">providers</a> that are available on built-in rules. "
+ + "Each instance of the default provider contains the following standard fields: "
+ + "<code>data_runfiles</code>, <code>default_runfiles</code>, <code>files</code>, "
+ + "and <code>files_to_run</code>. The values of these fields are equivalent to the "
+ + "values of the corresponding fields of the target the default provider belongs to.")
public static ClassObjectConstructor getDefaultProvider() {
return DEFAULT_PROVIDER;
}