Skip to content

Commit f2c98ba

Browse files
committed
Merge pull request #2003 from Microsoft/letAsName
disallow let to be used as name in let\const in ES6
2 parents 4b92e42 + f29d931 commit f2c98ba

6 files changed

+89
-1
lines changed

src/compiler/checker.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10916,9 +10916,32 @@ module ts {
1091610916
}
1091710917
}
1091810918
}
10919+
10920+
var checkLetConstNames = languageVersion >= ScriptTarget.ES6 && (isLet(node) || isConst(node));
10921+
10922+
// 1. LexicalDeclaration : LetOrConst BindingList ;
10923+
// It is a Syntax Error if the BoundNames of BindingList contains "let".
10924+
// 2. ForDeclaration: ForDeclaration : LetOrConst ForBinding
10925+
// It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
10926+
1091910927
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
1092010928
// and its Identifier is eval or arguments
10921-
return checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
10929+
return (checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name)) ||
10930+
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
10931+
}
10932+
10933+
function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean {
10934+
if (name.kind === SyntaxKind.Identifier) {
10935+
if ((<Identifier>name).text === "let") {
10936+
return grammarErrorOnNode(name, Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
10937+
}
10938+
}
10939+
else {
10940+
var elements = (<BindingPattern>name).elements;
10941+
for (var i = 0; i < elements.length; ++i) {
10942+
checkGrammarNameInLetOrConstDeclarations(elements[i].name);
10943+
}
10944+
}
1092210945
}
1092310946

1092410947
function checkGrammarVariableDeclarationList(declarationList: VariableDeclarationList): boolean {

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ module ts {
380380
const_enum_member_initializer_was_evaluated_to_a_non_finite_value: { code: 4086, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to a non-finite value." },
381381
const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: { code: 4087, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to disallowed value 'NaN'." },
382382
Property_0_does_not_exist_on_const_enum_1: { code: 4088, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on 'const' enum '{1}'." },
383+
let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: { code: 4089, category: DiagnosticCategory.Error, key: "'let' is not allowed to be used as a name in 'let' or 'const' declarations." },
383384
The_current_host_does_not_support_the_0_option: { code: 5001, category: DiagnosticCategory.Error, key: "The current host does not support the '{0}' option." },
384385
Cannot_find_the_common_subdirectory_path_for_the_input_files: { code: 5009, category: DiagnosticCategory.Error, key: "Cannot find the common subdirectory path for the input files." },
385386
Cannot_read_file_0_Colon_1: { code: 5012, category: DiagnosticCategory.Error, key: "Cannot read file '{0}': {1}" },

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,10 @@
15131513
"category": "Error",
15141514
"code": 4088
15151515
},
1516+
"'let' is not allowed to be used as a name in 'let' or 'const' declarations.": {
1517+
"category": "Error",
1518+
"code": 4089
1519+
},
15161520
"The current host does not support the '{0}' option.": {
15171521
"category": "Error",
15181522
"code": 5001
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
tests/cases/compiler/letInLetOrConstDeclarations.ts(2,9): error TS4089: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
2+
tests/cases/compiler/letInLetOrConstDeclarations.ts(3,14): error TS4089: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
3+
tests/cases/compiler/letInLetOrConstDeclarations.ts(6,11): error TS4089: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
4+
5+
6+
==== tests/cases/compiler/letInLetOrConstDeclarations.ts (3 errors) ====
7+
{
8+
let let = 1; // should error
9+
~~~
10+
!!! error TS4089: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
11+
for (let let in []) { } // should error
12+
~~~
13+
!!! error TS4089: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
14+
}
15+
{
16+
const let = 1; // should error
17+
~~~
18+
!!! error TS4089: 'let' is not allowed to be used as a name in 'let' or 'const' declarations.
19+
}
20+
{
21+
function let() { // should be ok
22+
}
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//// [letInLetOrConstDeclarations.ts]
2+
{
3+
let let = 1; // should error
4+
for (let let in []) { } // should error
5+
}
6+
{
7+
const let = 1; // should error
8+
}
9+
{
10+
function let() { // should be ok
11+
}
12+
}
13+
14+
//// [letInLetOrConstDeclarations.js]
15+
{
16+
let let = 1; // should error
17+
for (let let in []) { } // should error
18+
}
19+
{
20+
const let = 1; // should error
21+
}
22+
{
23+
function let() {
24+
}
25+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @target: es6
2+
{
3+
let let = 1; // should error
4+
for (let let in []) { } // should error
5+
}
6+
{
7+
const let = 1; // should error
8+
}
9+
{
10+
function let() { // should be ok
11+
}
12+
}

0 commit comments

Comments
 (0)