Change allowedRuleClasses/mandatoryProviders semantics to "either-or" instead of "and".
Also allow native rules to require declared providers on their
dependencies.
--
MOS_MIGRATED_REVID=135454750
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 ec184b4..347c728 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
@@ -27,6 +27,9 @@
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor.Key;
+import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.syntax.ClassObject;
import com.google.devtools.build.lib.syntax.EvalException;
@@ -75,6 +78,18 @@
return actual == null ? null : actual.get(providerKey);
}
+ @Nullable
+ @Override
+ public SkylarkClassObject get(Key providerKey) {
+ return actual == null ? null : actual.get(providerKey);
+ }
+
+ @Nullable
+ @Override
+ public Object get(SkylarkProviderIdentifier id) {
+ return actual == null ? null : actual.get(id);
+ }
+
@Override
public Object getIndex(Object key, Location loc) throws EvalException {
return actual == null ? null : actual.getIndex(key, loc);
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 015b0f0..71f176d 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
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules;
+import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -26,6 +27,7 @@
import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.SkylarkAspect;
+import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -258,7 +260,7 @@
}
}
if (isSingleListOfStr) {
- builder.mandatoryProviders(((SkylarkList<?>) obj).getContents(String.class, PROVIDERS_ARG));
+ builder.mandatoryProviders(getSkylarkProviderIdentifiers((SkylarkList<?>) obj));
} else {
builder.mandatoryProvidersList(getProvidersList((SkylarkList) obj));
}
@@ -283,8 +285,20 @@
return builder;
}
- private static List<List<String>> getProvidersList(SkylarkList skylarkList) throws EvalException {
- List<List<String>> providersList = new ArrayList<>();
+ private static Iterable<SkylarkProviderIdentifier> getSkylarkProviderIdentifiers(
+ SkylarkList<?> obj) throws EvalException {
+ return Iterables.transform(obj.getContents(String.class, PROVIDERS_ARG),
+ new Function<String, SkylarkProviderIdentifier>() {
+ @Override
+ public SkylarkProviderIdentifier apply(String s) {
+ return SkylarkProviderIdentifier.forLegacy(s);
+ }
+ });
+ }
+
+ private static List<Iterable<SkylarkProviderIdentifier>> getProvidersList(
+ SkylarkList<?> skylarkList) throws EvalException {
+ List<Iterable<SkylarkProviderIdentifier>> providersList = new ArrayList<>();
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.";
@@ -300,7 +314,7 @@
+ EvalUtils.getDataTypeNameFromClass(value.getClass())));
}
}
- providersList.add(((SkylarkList<?>) o).getContents(String.class, PROVIDERS_ARG));
+ providersList.add(getSkylarkProviderIdentifiers((SkylarkList<?>) o));
}
return providersList;
}
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 50133da..6ac83f5 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
@@ -311,7 +311,9 @@
SkylarkClassObject declaredProvider = SkylarkType.cast(o, SkylarkClassObject.class, loc,
"A return value of rule implementation function should be "
+ "a sequence of declared providers");
- builder.addSkylarkDeclaredProvider(declaredProvider, declaredProvider.getCreationLoc());
+ Location creationLoc = declaredProvider.getCreationLocOrNull();
+ builder.addSkylarkDeclaredProvider(declaredProvider,
+ creationLoc != null ? creationLoc : loc);
}
}