Skip to content

Commit f562c69

Browse files
tbreisacherblickly
authored andcommitted
Slight tweak in how scope variables are handled when a function and one of its parameters have the same name. This will allow us to simplify MakeDeclaredNamesUnique.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=167786746
1 parent 20ddcae commit f562c69

File tree

3 files changed

+23
-23
lines changed

3 files changed

+23
-23
lines changed

src/com/google/javascript/jscomp/Es6SyntacticScopeCreator.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,17 @@ void populate() {
131131
final Node fnNameNode = n.getFirstChild();
132132
final Node args = fnNameNode.getNext();
133133

134-
// Bleed the function name into the scope, if it hasn't
135-
// been declared in the outer scope.
134+
// Args: Declare function variables
135+
checkState(args.isParamList());
136+
declareLHS(scope, args);
137+
138+
// Bleed the function name into the scope, if it hasn't been declared in the outer scope
139+
// and the name isn't already in the scope via the param list.
136140
String fnName = fnNameNode.getString();
137141
if (!fnName.isEmpty() && NodeUtil.isFunctionExpression(n)) {
138142
declareVar(scope, fnNameNode);
139143
}
140144

141-
// Args: Declare function variables
142-
checkState(args.isParamList());
143-
declareLHS(scope, args);
144145
// Since we create a separate scope for body, stop scanning here
145146
return;
146147
}
@@ -321,7 +322,7 @@ private void declareVar(Scope s, Node n) {
321322

322323
CompilerInput input = compiler.getInput(inputId);
323324
if (v != null
324-
|| isShadowingDisallowed(name, s)
325+
|| !isShadowingAllowed(name, s)
325326
|| ((s.isFunctionScope()
326327
|| s.isFunctionBlockScope()) && name.equals(ARGUMENTS))) {
327328
redeclarationHandler.onRedeclaration(s, name, n, input);
@@ -332,12 +333,12 @@ private void declareVar(Scope s, Node n) {
332333

333334
// Function body declarations are not allowed to shadow
334335
// function parameters.
335-
private static boolean isShadowingDisallowed(String name, Scope s) {
336+
private static boolean isShadowingAllowed(String name, Scope s) {
336337
if (s.isFunctionBlockScope()) {
337338
Var maybeParam = s.getParent().getOwnSlot(name);
338-
return maybeParam != null && maybeParam.isParam();
339+
return maybeParam == null || !maybeParam.isParam();
339340
}
340-
return false;
341+
return true;
341342
}
342343
}
343344

test/com/google/javascript/jscomp/Es6SyntacticScopeCreatorTest.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,8 @@ public void testParamAndVarShadowFunctionName() {
209209
assertThat(Iterables.transform(functionScope.getVarIterable(), Var::getName))
210210
.containsExactly("g");
211211

212-
// TODO(tbreisacher): "var g" doesn't declare a new var, so the body scope should have no
213-
// variables in it.
214-
assertThat(Iterables.transform(bodyScope.getVarIterable(), Var::getName)).containsExactly("g");
212+
// "var g" doesn't declare a new var, so there is no 'g' variable in the function body scope.
213+
assertThat(bodyScope.getVarIterable()).isEmpty();
215214
}
216215

217216
public void testVarRedeclaration1_inES6Module() {
@@ -1007,9 +1006,9 @@ public void testFunctionNameMatchesParamName1() {
10071006
assertFalse(fScope.isDeclared("f", false));
10081007
assertTrue(fScope.isDeclared("foo", false));
10091008

1010-
// The Es6SyntacticScopeCreator considers the function name to be the declaration of 'foo',
1011-
// even though a reference to 'foo' inside the function would refer to the parameter foo.
1012-
assertNode(fScope.getVar("foo").getNode().getParent()).hasType(Token.FUNCTION);
1009+
// The parameter 'foo', not the function name, is the declaration of the variable 'foo' in this
1010+
// scope.
1011+
assertNode(fScope.getVar("foo").getNode().getParent()).hasType(Token.PARAM_LIST);
10131012
}
10141013

10151014
public void testFunctionNameMatchesParamName2() {
@@ -1024,9 +1023,9 @@ public void testFunctionNameMatchesParamName2() {
10241023
assertFalse(fScope.isDeclared("f", false));
10251024
assertTrue(fScope.isDeclared("foo", false));
10261025

1027-
// The Es6SyntacticScopeCreator considers the function name to be the declaration of 'foo',
1028-
// even though a reference to 'foo' inside the function would refer to the parameter foo.
1029-
assertNode(fScope.getVar("foo").getNode().getParent()).hasType(Token.FUNCTION);
1026+
// The parameter 'foo', not the function name, is the declaration of the variable 'foo' in this
1027+
// scope.
1028+
assertNode(fScope.getVar("foo").getNode().getParent()).hasType(Token.PARAM_LIST);
10301029
}
10311030

10321031
public void testClassName() {

test/com/google/javascript/jscomp/RenameVarsTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@ public void testBleedingRecursiveFunctions2() {
237237
"}"),
238238
LINE_JOINER.join(
239239
"function d() {",
240-
" var e = function b(a) { return a ? 1 : b(1); };",
241-
" var f = function a(c) { return c ? 2 : a(2); };",
240+
" var e = function a(b) { return b ? 1 : a(1); };",
241+
" var f = function c(a) { return a ? 2 : c(2); };",
242242
"}"));
243243
}
244244

@@ -252,9 +252,9 @@ public void testBleedingRecursiveFunctions3() {
252252
"}"),
253253
LINE_JOINER.join(
254254
"function f() {",
255-
" var g = function c(a) { return a ? 1 : c(1); };",
256-
" var d = function a(b) { return b ? 2 : a(2); };",
257-
" var h = function b(e) { return e ? d : b(2); };",
255+
" var g = function a(c) { return c ? 1 : a(1); };",
256+
" var d = function b(a) { return a ? 2 : b(2); };",
257+
" var h = function e(b) { return b ? d : e(2); };",
258258
"}"));
259259
}
260260

0 commit comments

Comments
 (0)