aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java21
-rw-r--r--src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java17
2 files changed, 36 insertions, 2 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 824ecc1377..45d1e0e143 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -892,10 +892,12 @@ public final class PackageFactory {
* Returns null if we don't want to export the value.
*
* <p>All of the types returned are immutable. If we want, we can change this to
- * immutable in the future, but this is the safe choice for now.o
+ * immutable in the future, but this is the safe choice for now.
*/
@Nullable
private static Object skylarkifyValue(Object val, Package pkg) throws NotRepresentableException {
+ // TODO(bazel-team): the location of this function is ad-hoc. Arguably, the conversion
+ // from Java native types to Skylark types should be part of the Type class hierarchy,
if (val == null) {
return null;
}
@@ -909,7 +911,6 @@ public final class PackageFactory {
return val;
}
- // Maybe we should have an interface for types so they can represent themselves to skylark?
if (val instanceof TriState) {
switch ((TriState) val) {
case AUTO:
@@ -972,6 +973,22 @@ public final class PackageFactory {
return null;
}
+ if (val instanceof BuildType.SelectorList) {
+ // This is terrible:
+ // 1) this value is opaque, and not a BUILD value, so it cannot be used in rule arguments
+ // 2) its representation has a pointer address, so it breaks hermeticity.
+ //
+ // Even though this is clearly imperfect, we return this value because otherwise
+ // native.rules() fails if there is any rule using a select() in the BUILD file.
+ //
+ // To remedy this, we should return a syntax.SelectorList. To do so, we have to
+ // 1) recurse into the Selector contents of SelectorList, so those values are skylarkified too
+ // 2) get the right Class<?> value. We could probably get at that by looking at
+ // ((SelectorList)val).getSelectors().first().getEntries().first().getClass().
+
+ return val;
+ }
+
// We are explicit about types we don't understand so we minimize changes to existing callers
// if we add more types that we can represent.
throw new NotRepresentableException(
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
index 088a542c89..240b5878b1 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
@@ -354,6 +354,23 @@ public class SkylarkRuleContextTest extends SkylarkTestCase {
}
@Test
+ public void testGetRuleSelect() throws Exception {
+ scratch.file("test/skylark/BUILD");
+ scratch.file("test/skylark/rulestr.bzl", "def rule_dict(name):", " return native.rule(name)");
+
+ scratch.file(
+ "test/getrule/BUILD",
+ "load('/test/skylark/rulestr', 'rule_dict')",
+ "cc_library(name ='x', ",
+ " srcs = select({'//conditions:default': []})",
+ ")",
+ "rule_dict('x')");
+
+ // Parse the BUILD file, to make sure select() makes it out of native.rule().
+ createRuleContext("//test/getrule:x");
+ }
+
+ @Test
public void testGetRule() throws Exception {
scratch.file("test/skylark/BUILD");
scratch.file(