aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java76
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java15
4 files changed, 71 insertions, 32 deletions
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 8cc374f212..8e2ae52fcb 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
@@ -300,9 +300,7 @@ public final class AspectDefinition {
*/
public Builder advertiseProvider(ImmutableList<SkylarkProviderIdentifier> providers) {
for (SkylarkProviderIdentifier provider : providers) {
- // todo(dslomov,vladmos): support declared providers
- Preconditions.checkState(provider.isLegacy());
- advertisedProviders.addSkylark(provider.getLegacyId());
+ advertisedProviders.addSkylark(provider);
}
return this;
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java
index 21deb7b842..58a58015c0 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java
@@ -43,7 +43,7 @@ public class SkylarkAspect implements SkylarkExportable {
private final ImmutableList<String> attributeAspects;
private final ImmutableList<Attribute> attributes;
private final ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> requiredAspectProviders;
- private final ImmutableList<String> provides;
+ private final ImmutableSet<SkylarkProviderIdentifier> provides;
private final ImmutableSet<String> paramAttributes;
private final ImmutableSet<String> fragments;
private final ImmutableSet<String> hostFragments;
@@ -55,7 +55,7 @@ public class SkylarkAspect implements SkylarkExportable {
ImmutableList<String> attributeAspects,
ImmutableList<Attribute> attributes,
ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> requiredAspectProviders,
- ImmutableList<String> provides,
+ ImmutableSet<SkylarkProviderIdentifier> provides,
ImmutableSet<String> paramAttributes,
ImmutableSet<String> fragments,
ImmutableSet<String> hostFragments,
@@ -147,8 +147,8 @@ public class SkylarkAspect implements SkylarkExportable {
builder.requireAspectsWithProviders(requiredAspectProviders);
ImmutableList.Builder<SkylarkProviderIdentifier> advertisedSkylarkProviders =
ImmutableList.builder();
- for (String provider : provides) {
- advertisedSkylarkProviders.add(SkylarkProviderIdentifier.forLegacy(provider));
+ for (SkylarkProviderIdentifier provider : provides) {
+ advertisedSkylarkProviders.add(provider);
}
builder.advertiseProvider(advertisedSkylarkProviders.build());
builder.requiresConfigurationFragmentsBySkylarkModuleName(fragments);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
index 4c18384f4d..3f2b066575 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
@@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
@@ -26,6 +27,7 @@ import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTe
import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
import com.google.devtools.build.lib.packages.AttributeValueSource;
import com.google.devtools.build.lib.packages.BuildType;
+import com.google.devtools.build.lib.packages.ClassObjectConstructor;
import com.google.devtools.build.lib.packages.SkylarkAspect;
import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.skylarkinterface.Param;
@@ -256,7 +258,7 @@ public final class SkylarkAttr {
Object obj = arguments.get(PROVIDERS_ARG);
SkylarkType.checkType(obj, SkylarkList.class, PROVIDERS_ARG);
ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> providersList = buildProviderPredicate(
- (SkylarkList<?>) obj);
+ (SkylarkList<?>) obj, PROVIDERS_ARG, ast.getLocation());
builder.mandatoryProvidersList(providersList);
}
@@ -288,56 +290,84 @@ public final class SkylarkAttr {
return builder;
}
- public static ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> buildProviderPredicate(
- SkylarkList<?> obj) throws EvalException {
+ /**
+ * Builds a list of sets of accepted providers from Skylark list {@code obj}.
+ * The list can either be a list of providers (in that case the result is a list with one
+ * set) or a list of lists of providers (then the result is the list of sets).
+ * @param argumentName used in error messages.
+ * @param location location for error messages.
+ */
+ static ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> buildProviderPredicate(
+ SkylarkList<?> obj, String argumentName, Location location) throws EvalException {
if (obj.isEmpty()) {
return ImmutableList.of();
}
- boolean isSingleListOfStr = true;
- for (Object o : (SkylarkList) obj) {
- isSingleListOfStr = o instanceof String;
- if (!isSingleListOfStr) {
+ boolean isListOfProviders = true;
+ for (Object o : obj) {
+ if (!isProvider(o)) {
+ isListOfProviders = false;
break;
}
}
- if (isSingleListOfStr) {
- return ImmutableList.of(getSkylarkProviderIdentifiers(obj));
+ if (isListOfProviders) {
+ return ImmutableList.of(getSkylarkProviderIdentifiers(obj, location));
} else {
- return getProvidersList((SkylarkList) obj);
+ return getProvidersList(obj, argumentName, location);
}
}
- private static ImmutableSet<SkylarkProviderIdentifier> getSkylarkProviderIdentifiers(
- SkylarkList<?> obj) throws EvalException {
+ /**
+ * Returns true if {@code o} is a Skylark provider (either a declared provider or
+ * a legacy provider name.
+ */
+ static boolean isProvider(Object o) {
+ return o instanceof String || o instanceof ClassObjectConstructor;
+ }
+
+ /**
+ * Converts Skylark identifiers of providers (either a string or a provider value)
+ * to their internal representations.
+ */
+ static ImmutableSet<SkylarkProviderIdentifier> getSkylarkProviderIdentifiers(
+ SkylarkList<?> list, Location location) throws EvalException {
ImmutableList.Builder<SkylarkProviderIdentifier> result = ImmutableList.builder();
- List<String> contents = obj.getContents(String.class, PROVIDERS_ARG);
- for (String legacyId : contents) {
- result.add(SkylarkProviderIdentifier.forLegacy(legacyId));
+ for (Object obj : list) {
+ if (obj instanceof String) {
+ result.add(SkylarkProviderIdentifier.forLegacy((String) obj));
+ } else if (obj instanceof ClassObjectConstructor) {
+ ClassObjectConstructor constructor = (ClassObjectConstructor) obj;
+ if (!constructor.isExported()) {
+ throw new EvalException(location,
+ "Providers should be assigned to top-level values in modules");
+ }
+ result.add(SkylarkProviderIdentifier.forKey(constructor.getKey()));
+ }
}
return ImmutableSet.copyOf(result.build());
}
private static ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> getProvidersList(
- SkylarkList<?> skylarkList) throws EvalException {
+ SkylarkList<?> skylarkList, String argumentName, Location location) throws EvalException {
ImmutableList.Builder<ImmutableSet<SkylarkProviderIdentifier>> providersList =
ImmutableList.builder();
String errorMsg = "Illegal argument: element in '%s' is of unexpected type. "
- + "Should be list of string, but got %s. "
- + "Notice: one single list of string as 'providers' is still supported.";
+ + "Either all elements should be providers, "
+ + "or all elements should be lists of providers, but got %s.";
+
for (Object o : skylarkList) {
if (!(o instanceof SkylarkList)) {
- throw new EvalException(null, String.format(errorMsg, PROVIDERS_ARG,
- EvalUtils.getDataTypeName(o, true)));
+ throw new EvalException(location, String.format(errorMsg, PROVIDERS_ARG,
+ "an element of type " + EvalUtils.getDataTypeName(o, true)));
}
for (Object value : (SkylarkList) o) {
- if (!(value instanceof String)) {
- throw new EvalException(null, String.format(errorMsg, PROVIDERS_ARG,
+ if (!isProvider(value)) {
+ throw new EvalException(location, String.format(errorMsg, argumentName,
"list with an element of type "
+ EvalUtils.getDataTypeNameFromClass(value.getClass())));
}
}
- providersList.add(getSkylarkProviderIdentifiers((SkylarkList<?>) o));
+ providersList.add(getSkylarkProviderIdentifiers((SkylarkList<?>) o, location));
}
return providersList.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
index 1f71424048..b42ff3d924 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
@@ -590,12 +590,23 @@ public class SkylarkRuleClassFunctions {
attributes.add(attribute);
}
+ for (Object o : providesArg) {
+ if (!SkylarkAttr.isProvider(o)) {
+ throw new EvalException(ast.getLocation(),
+ String.format("Illegal argument: element in 'provides' is of unexpected type. "
+ + "Should be list of providers, but got %s. ",
+ EvalUtils.getDataTypeName(o, true)));
+ }
+ }
+
return new SkylarkAspect(
implementation,
attrAspects.build(),
attributes.build(),
- SkylarkAttr.buildProviderPredicate(requiredAspectProvidersArg),
- ImmutableList.copyOf(STRING_LIST.convert(providesArg, "provides")),
+ SkylarkAttr.buildProviderPredicate(requiredAspectProvidersArg,
+ "required_aspect_providers", ast.getLocation()
+ ),
+ SkylarkAttr.getSkylarkProviderIdentifiers(providesArg, ast.getLocation()),
requiredParams.build(),
ImmutableSet.copyOf(fragments.getContents(String.class, "fragments")),
ImmutableSet.copyOf(hostFragments.getContents(String.class, "host_fragments")),