aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Environment.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java8
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java12
3 files changed, 30 insertions, 5 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
index d4e6403312..eb06a10862 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
@@ -142,6 +142,11 @@ public final class Environment implements Freezable {
? ImmutableEmptyLexicalFrame.INSTANCE
: new MutableLexicalFrame(mutability);
}
+
+ static LexicalFrame createForUserDefinedFunctionCall(Mutability mutability, int numArgs) {
+ Preconditions.checkState(!mutability.isFrozen());
+ return new MutableLexicalFrame(mutability, /*initialCapacity=*/ numArgs);
+ }
}
private static final class ImmutableEmptyLexicalFrame implements LexicalFrame {
@@ -184,10 +189,16 @@ public final class Environment implements Freezable {
private static final class MutableLexicalFrame implements LexicalFrame {
private final Mutability mutability;
/** Bindings are maintained in order of creation. */
- private final LinkedHashMap<String, Object> bindings = new LinkedHashMap<>();
+ private final LinkedHashMap<String, Object> bindings;
- public MutableLexicalFrame(Mutability mutability) {
+ private MutableLexicalFrame(Mutability mutability, int initialCapacity) {
this.mutability = mutability;
+ this.bindings = new LinkedHashMap<>(initialCapacity);
+ }
+
+ private MutableLexicalFrame(Mutability mutability) {
+ this.mutability = mutability;
+ this.bindings = new LinkedHashMap<>();
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java
index b4fc95f5aa..485bac26e8 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java
@@ -63,10 +63,12 @@ public class UserDefinedFunction extends BaseFunction {
getName(), env.getCurrentFunction().getName()));
}
- Profiler.instance().startTask(ProfilerTask.SKYLARK_USER_FN, getName());
+ ImmutableList<String> names = signature.getSignature().getNames();
+ LexicalFrame lexicalFrame =
+ LexicalFrame.createForUserDefinedFunctionCall(env.mutability(), /*numArgs=*/ names.size());
try {
- env.enterScope(this, LexicalFrame.create(env.mutability()), ast, definitionGlobals);
- ImmutableList<String> names = signature.getSignature().getNames();
+ Profiler.instance().startTask(ProfilerTask.SKYLARK_USER_FN, getName());
+ env.enterScope(this, lexicalFrame, ast, definitionGlobals);
// Registering the functions's arguments as variables in the local Environment
int i = 0;
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java b/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java
index ff8dddc596..f91e2a8a72 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java
@@ -200,6 +200,18 @@ public class FunctionTest extends EvaluationTestCase {
}
@Test
+ public void testFunctionParamCanShadowGlobalVarAfterGlobalVarIsRead() throws Exception {
+ eval("a = 1",
+ "def func2(a):",
+ " return 0",
+ "def func1():",
+ " dummy = a",
+ " return func2(2)",
+ "b = func1()\n");
+ assertThat(lookup("b")).isEqualTo(0);
+ }
+
+ @Test
public void testSingleLineFunction() throws Exception {
eval("def func(): return 'a'",
"s = func()\n");