Add type checking to select() keys.
Aside from making error messaging clearer, this stops Bazel from
crashing on select({None: ...}) (a pretty anti-social error message).
--
PiperOrigin-RevId: 146173043
MOS_MIGRATED_REVID=146173043
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
index c55e607..b943e4a 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
@@ -172,11 +172,19 @@
defaultValue = "''",
doc = "Optional custom error to report if no condition matches."
)
- }
+ },
+ useLocation = true
)
private static final BuiltinFunction select =
new BuiltinFunction("select") {
- public Object invoke(SkylarkDict<?, ?> dict, String noMatchError) throws EvalException {
+ public Object invoke(SkylarkDict<?, ?> dict, String noMatchError, Location loc)
+ throws EvalException {
+ for (Object key : dict.keySet()) {
+ if (!(key instanceof String)) {
+ throw new EvalException(loc,
+ String.format("Invalid key: %s. select keys must be label references", key));
+ }
+ }
return SelectorList.of(new SelectorValue(dict, noMatchError));
}
};
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 3121bfc..b303d00 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -322,6 +322,25 @@
return getPackageManager().getTarget(reporter, label);
}
+ /**
+ * Checks that loading the given target fails with the expected error message.
+ *
+ * <p>Fails with an assertion error if this doesn't happen.
+ *
+ * <p>This method is useful for checking loading phase errors. Analysis phase errors can be
+ * checked with {@link #getConfiguredTarget} and related methods.
+ */
+ protected void assertTargetError(String label, String expectedError)
+ throws InterruptedException {
+ try {
+ getTarget(label);
+ fail("Expected loading phase failure for target " + label);
+ } catch (NoSuchPackageException | NoSuchTargetException | LabelSyntaxException e) {
+ // Target loading failed as expected.
+ }
+ assertContainsEvent(expectedError);
+ }
+
private void setUpSkyframe() {
PathPackageLocator pkgLocator = PathPackageLocator.create(
outputBase, packageCacheOptions.packagePath, reporter, rootDirectory, rootDirectory);