Introduce --incompatible_static_name_resolution
This implements a part of the name resolution document: https://github.com/bazelbuild/proposals/blob/master/docs/2018-06-18-name-resolution.md
When the flag is set:
- Builtins may be shadowed (e.g. `len = 2`) on top-level
- Symbols may be used before their definition point, e.g.
def fct(): return x
x = 2
In a followup change, we'll need to update the dynamic Environment too (to have truly lexical binding).
https://github.com/bazelbuild/bazel/issues/5637
RELNOTES: None.
PiperOrigin-RevId: 210412609
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTest.java
index 3a003b1..403bfa3 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTest.java
@@ -93,6 +93,18 @@
@Test
public void testDefinitionByItself() throws Exception {
+ env = newEnvironmentWithSkylarkOptions("--incompatible_static_name_resolution=true");
+ // Variables are assumed to be statically visible in the block (even if they might not be
+ // initialized).
+ parse("a = a");
+ parse("a += a");
+ parse("[[] for a in a]");
+ parse("def f():", " for a in a: pass");
+ }
+
+ @Test
+ public void testDefinitionByItselfLegacy() throws Exception {
+ env = newEnvironmentWithSkylarkOptions("--incompatible_static_name_resolution=false");
checkError("name 'a' is not defined", "a = a");
checkError("name 'a' is not defined", "a += a");
checkError("name 'a' is not defined", "[[] for a in a]");
@@ -105,11 +117,18 @@
}
@Test
- public void testBuiltinSymbolsAreReadOnly() throws Exception {
+ public void testBuiltinSymbolsAreReadOnlyLegacy() throws Exception {
+ env = newEnvironmentWithSkylarkOptions("--incompatible_static_name_resolution=false");
checkError("Variable repr is read only", "repr = 1");
}
@Test
+ public void testBuiltinsCanBeShadowed() throws Exception {
+ env = newEnvironmentWithSkylarkOptions("--incompatible_static_name_resolution=true");
+ parse("repr = 1");
+ }
+
+ @Test
public void testSkylarkGlobalVariablesAreReadonly() throws Exception {
checkError("Variable a is read only", "a = 1", "a = 2");
}
@@ -130,6 +149,23 @@
}
@Test
+ public void testGlobalDefinedBelow() throws Exception {
+ env = newEnvironmentWithSkylarkOptions("--incompatible_static_name_resolution=true");
+ parse("def bar(): return x", "x = 5\n");
+ }
+
+ @Test
+ public void testLocalVariableDefinedBelow() throws Exception {
+ env = newEnvironmentWithSkylarkOptions("--incompatible_static_name_resolution=true");
+ parse(
+ "def bar():",
+ " for i in range(5):",
+ " if i > 2: return x",
+ " x = i" // x is visible in the entire function block
+ );
+ }
+
+ @Test
public void testFunctionDoesNotExist() {
checkError("name 'foo' is not defined", "def bar(): a = foo() + 'a'");
}