Skip to content

Commit 3a4ac33

Browse files
committed
Merge pull request #5898 from Microsoft/fix3475_let
Disallow let in let/const declaration regardless of target
2 parents 2799d2e + 0784ea1 commit 3a4ac33

File tree

49 files changed

+736
-65
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+736
-65
lines changed

src/compiler/checker.ts

+18-4
Original file line numberDiff line numberDiff line change
@@ -15965,13 +15965,27 @@ namespace ts {
1596515965
if (forInOrOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
1596615966
const variableList = <VariableDeclarationList>forInOrOfStatement.initializer;
1596715967
if (!checkGrammarVariableDeclarationList(variableList)) {
15968-
if (variableList.declarations.length > 1) {
15968+
const declarations = variableList.declarations;
15969+
15970+
// declarations.length can be zero if there is an error in variable declaration in for-of or for-in
15971+
// See http://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements for details
15972+
// For example:
15973+
// var let = 10;
15974+
// for (let of [1,2,3]) {} // this is invalid ES6 syntax
15975+
// for (let in [1,2,3]) {} // this is invalid ES6 syntax
15976+
// We will then want to skip on grammar checking on variableList declaration
15977+
if (!declarations.length) {
15978+
return false;
15979+
}
15980+
15981+
if (declarations.length > 1) {
1596915982
const diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
1597015983
? Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
1597115984
: Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
1597215985
return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
1597315986
}
15974-
const firstDeclaration = variableList.declarations[0];
15987+
const firstDeclaration = declarations[0];
15988+
1597515989
if (firstDeclaration.initializer) {
1597615990
const diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
1597715991
? Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
@@ -16170,7 +16184,7 @@ namespace ts {
1617016184
}
1617116185
}
1617216186

16173-
const checkLetConstNames = languageVersion >= ScriptTarget.ES6 && (isLet(node) || isConst(node));
16187+
const checkLetConstNames = (isLet(node) || isConst(node));
1617416188

1617516189
// 1. LexicalDeclaration : LetOrConst BindingList ;
1617616190
// It is a Syntax Error if the BoundNames of BindingList contains "let".
@@ -16184,7 +16198,7 @@ namespace ts {
1618416198

1618516199
function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean {
1618616200
if (name.kind === SyntaxKind.Identifier) {
16187-
if ((<Identifier>name).text === "let") {
16201+
if ((<Identifier>name).originalKeywordKind === SyntaxKind.LetKeyword) {
1618816202
return grammarErrorOnNode(name, Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
1618916203
}
1619016204
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
tests/cases/compiler/invalidLetInForOfAndForIn_ES5.ts(5,13): error TS1005: '=' expected.
2+
tests/cases/compiler/invalidLetInForOfAndForIn_ES5.ts(5,20): error TS1005: ',' expected.
3+
tests/cases/compiler/invalidLetInForOfAndForIn_ES5.ts(7,1): error TS1005: ';' expected.
4+
5+
6+
==== tests/cases/compiler/invalidLetInForOfAndForIn_ES5.ts (3 errors) ====
7+
// This should be an error
8+
// More details: http://www.ecma-international.org/ecma-262/6.0/#sec-iteration-statements
9+
10+
var let = 10;
11+
for (let of [1,2,3]) {}
12+
~
13+
!!! error TS1005: '=' expected.
14+
~
15+
!!! error TS1005: ',' expected.
16+
17+
for (let in [1,2,3]) {}
18+
~~~
19+
!!! error TS1005: ';' expected.
20+
21+
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//// [invalidLetInForOfAndForIn_ES5.ts]
2+
// This should be an error
3+
// More details: http://www.ecma-international.org/ecma-262/6.0/#sec-iteration-statements
4+
5+
var let = 10;
6+
for (let of [1,2,3]) {}
7+
8+
for (let in [1,2,3]) {}
9+
10+
11+
12+
13+
//// [invalidLetInForOfAndForIn_ES5.js]
14+
// This should be an error
15+
// More details: http://www.ecma-international.org/ecma-262/6.0/#sec-iteration-statements
16+
var let = 10;
17+
for (let of = [1, 2, 3], { }; ; )
18+
for ( in [1, 2, 3]) { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
tests/cases/compiler/invalidLetInForOfAndForIn_ES6.ts(5,13): error TS1005: '=' expected.
2+
tests/cases/compiler/invalidLetInForOfAndForIn_ES6.ts(5,20): error TS1005: ',' expected.
3+
tests/cases/compiler/invalidLetInForOfAndForIn_ES6.ts(7,1): error TS1005: ';' expected.
4+
5+
6+
==== tests/cases/compiler/invalidLetInForOfAndForIn_ES6.ts (3 errors) ====
7+
// This should be an error
8+
// More details: http://www.ecma-international.org/ecma-262/6.0/#sec-iteration-statements
9+
10+
var let = 10;
11+
for (let of [1,2,3]) {}
12+
~
13+
!!! error TS1005: '=' expected.
14+
~
15+
!!! error TS1005: ',' expected.
16+
17+
for (let in [1,2,3]) {}
18+
~~~
19+
!!! error TS1005: ';' expected.
20+
21+
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//// [invalidLetInForOfAndForIn_ES6.ts]
2+
// This should be an error
3+
// More details: http://www.ecma-international.org/ecma-262/6.0/#sec-iteration-statements
4+
5+
var let = 10;
6+
for (let of [1,2,3]) {}
7+
8+
for (let in [1,2,3]) {}
9+
10+
11+
12+
13+
//// [invalidLetInForOfAndForIn_ES6.js]
14+
// This should be an error
15+
// More details: http://www.ecma-international.org/ecma-262/6.0/#sec-iteration-statements
16+
var let = 10;
17+
for (let of = [1, 2, 3], { }; ; )
18+
for ( in [1, 2, 3]) { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//// [letAsIdentifier2.ts]
2+
3+
function let() {}
4+
5+
//// [letAsIdentifier2.js]
6+
function let() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/letAsIdentifier2.ts ===
2+
3+
function let() {}
4+
>let : Symbol(let, Decl(letAsIdentifier2.ts, 0, 0))
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/letAsIdentifier2.ts ===
2+
3+
function let() {}
4+
>let : () => void
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
tests/cases/compiler/letInConstDeclarations_ES5.ts(3,15): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
2+
tests/cases/compiler/letInConstDeclarations_ES5.ts(6,19): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
3+
4+
5+
==== tests/cases/compiler/letInConstDeclarations_ES5.ts (2 errors) ====
6+
7+
// All use of let in const declaration should be an error
8+
const x = 50, let = 5;
9+
~~~
10+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
11+
12+
{
13+
const x = 10, let = 20;
14+
~~~
15+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [letInConstDeclarations_ES5.ts]
2+
3+
// All use of let in const declaration should be an error
4+
const x = 50, let = 5;
5+
6+
{
7+
const x = 10, let = 20;
8+
}
9+
10+
//// [letInConstDeclarations_ES5.js]
11+
// All use of let in const declaration should be an error
12+
var x = 50, let = 5;
13+
{
14+
var x_1 = 10, let_1 = 20;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
tests/cases/compiler/letInConstDeclarations_ES6.ts(3,15): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
2+
tests/cases/compiler/letInConstDeclarations_ES6.ts(6,19): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
3+
4+
5+
==== tests/cases/compiler/letInConstDeclarations_ES6.ts (2 errors) ====
6+
7+
// All use of let in const declaration should be an error
8+
const x = 50, let = 5;
9+
~~~
10+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
11+
12+
{
13+
const x = 10, let = 20;
14+
~~~
15+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [letInConstDeclarations_ES6.ts]
2+
3+
// All use of let in const declaration should be an error
4+
const x = 50, let = 5;
5+
6+
{
7+
const x = 10, let = 20;
8+
}
9+
10+
//// [letInConstDeclarations_ES6.js]
11+
// All use of let in const declaration should be an error
12+
const x = 50, let = 5;
13+
{
14+
const x = 10, let = 20;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts(3,10): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
2+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts(5,12): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
3+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts(7,10): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
4+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts(9,12): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
5+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts(12,11): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
6+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts(14,13): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
7+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts(16,11): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
8+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts(18,13): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
9+
10+
11+
==== tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES5.ts (8 errors) ====
12+
13+
// Should be an error
14+
for (let let of [1,2,3]) {}
15+
~~~
16+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
17+
18+
for (const let of [1,2,3]) {}
19+
~~~
20+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
21+
22+
for (let let in [1,2,3]) {}
23+
~~~
24+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
25+
26+
for (const let in [1,2,3]) {}
27+
~~~
28+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
29+
30+
{
31+
for (let let of [1,2,3]) {}
32+
~~~
33+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
34+
35+
for (const let of [1,2,3]) {}
36+
~~~
37+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
38+
39+
for (let let in [1,2,3]) {}
40+
~~~
41+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
42+
43+
for (const let in [1,2,3]) {}
44+
~~~
45+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
46+
}
47+
48+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//// [letInLetConstDeclOfForOfAndForIn_ES5.ts]
2+
3+
// Should be an error
4+
for (let let of [1,2,3]) {}
5+
6+
for (const let of [1,2,3]) {}
7+
8+
for (let let in [1,2,3]) {}
9+
10+
for (const let in [1,2,3]) {}
11+
12+
{
13+
for (let let of [1,2,3]) {}
14+
15+
for (const let of [1,2,3]) {}
16+
17+
for (let let in [1,2,3]) {}
18+
19+
for (const let in [1,2,3]) {}
20+
}
21+
22+
23+
24+
//// [letInLetConstDeclOfForOfAndForIn_ES5.js]
25+
// Should be an error
26+
for (var _i = 0, _a = [1, 2, 3]; _i < _a.length; _i++) {
27+
var let = _a[_i];
28+
}
29+
for (var _b = 0, _c = [1, 2, 3]; _b < _c.length; _b++) {
30+
var let = _c[_b];
31+
}
32+
for (var let in [1, 2, 3]) { }
33+
for (var let in [1, 2, 3]) { }
34+
{
35+
for (var _d = 0, _e = [1, 2, 3]; _d < _e.length; _d++) {
36+
var let = _e[_d];
37+
}
38+
for (var _f = 0, _g = [1, 2, 3]; _f < _g.length; _f++) {
39+
var let = _g[_f];
40+
}
41+
for (var let in [1, 2, 3]) { }
42+
for (var let in [1, 2, 3]) { }
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts(3,10): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
2+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts(5,12): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
3+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts(7,10): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
4+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts(9,12): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
5+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts(12,11): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
6+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts(14,13): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
7+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts(16,11): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
8+
tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts(18,13): error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
9+
10+
11+
==== tests/cases/compiler/letInLetConstDeclOfForOfAndForIn_ES6.ts (8 errors) ====
12+
13+
// Should be an error
14+
for (let let of [1,2,3]) {}
15+
~~~
16+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
17+
18+
for (const let of [1,2,3]) {}
19+
~~~
20+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
21+
22+
for (let let in [1,2,3]) {}
23+
~~~
24+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
25+
26+
for (const let in [1,2,3]) {}
27+
~~~
28+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
29+
30+
{
31+
for (let let of [1,2,3]) {}
32+
~~~
33+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
34+
35+
for (const let of [1,2,3]) {}
36+
~~~
37+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
38+
39+
for (let let in [1,2,3]) {}
40+
~~~
41+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
42+
43+
for (const let in [1,2,3]) {}
44+
~~~
45+
!!! error TS2480: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
46+
}
47+
48+

0 commit comments

Comments
 (0)