Skip to content

Commit d2c992c

Browse files
committed
Merge pull request #2066 from Microsoft/forOf
Parsing for for...of statements
2 parents aa13a97 + 5596993 commit d2c992c

File tree

148 files changed

+1743
-815
lines changed

Some content is hidden

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

148 files changed

+1743
-815
lines changed

Diff for: src/compiler/binder.ts

+1
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ module ts {
489489
case SyntaxKind.CatchClause:
490490
case SyntaxKind.ForStatement:
491491
case SyntaxKind.ForInStatement:
492+
case SyntaxKind.ForOfStatement:
492493
case SyntaxKind.SwitchStatement:
493494
bindChildren(node, 0, /*isBlockScopeContainer*/ true);
494495
break;

Diff for: src/compiler/checker.ts

+71-29
Original file line numberDiff line numberDiff line change
@@ -4642,6 +4642,7 @@ module ts {
46424642
case SyntaxKind.WhileStatement:
46434643
case SyntaxKind.ForStatement:
46444644
case SyntaxKind.ForInStatement:
4645+
case SyntaxKind.ForOfStatement:
46454646
case SyntaxKind.ReturnStatement:
46464647
case SyntaxKind.WithStatement:
46474648
case SyntaxKind.SwitchStatement:
@@ -8237,7 +8238,7 @@ module ts {
82378238
function checkBlock(node: Block) {
82388239
// Grammar checking for SyntaxKind.Block
82398240
if (node.kind === SyntaxKind.Block) {
8240-
checkGrammarForStatementInAmbientContext(node);
8241+
checkGrammarStatementInAmbientContext(node);
82418242
}
82428243

82438244
forEach(node.statements, checkSourceElement);
@@ -8553,14 +8554,14 @@ module ts {
85538554

85548555
function checkExpressionStatement(node: ExpressionStatement) {
85558556
// Grammar checking
8556-
checkGrammarForStatementInAmbientContext(node)
8557+
checkGrammarStatementInAmbientContext(node)
85578558

85588559
checkExpression(node.expression);
85598560
}
85608561

85618562
function checkIfStatement(node: IfStatement) {
85628563
// Grammar checking
8563-
checkGrammarForStatementInAmbientContext(node);
8564+
checkGrammarStatementInAmbientContext(node);
85648565

85658566
checkExpression(node.expression);
85668567
checkSourceElement(node.thenStatement);
@@ -8569,23 +8570,23 @@ module ts {
85698570

85708571
function checkDoStatement(node: DoStatement) {
85718572
// Grammar checking
8572-
checkGrammarForStatementInAmbientContext(node);
8573+
checkGrammarStatementInAmbientContext(node);
85738574

85748575
checkSourceElement(node.statement);
85758576
checkExpression(node.expression);
85768577
}
85778578

85788579
function checkWhileStatement(node: WhileStatement) {
85798580
// Grammar checking
8580-
checkGrammarForStatementInAmbientContext(node);
8581+
checkGrammarStatementInAmbientContext(node);
85818582

85828583
checkExpression(node.expression);
85838584
checkSourceElement(node.statement);
85848585
}
85858586

85868587
function checkForStatement(node: ForStatement) {
85878588
// Grammar checking
8588-
if (!checkGrammarForStatementInAmbientContext(node)) {
8589+
if (!checkGrammarStatementInAmbientContext(node)) {
85898590
if (node.initializer && node.initializer.kind == SyntaxKind.VariableDeclarationList) {
85908591
checkGrammarVariableDeclarationList(<VariableDeclarationList>node.initializer);
85918592
}
@@ -8605,18 +8606,14 @@ module ts {
86058606
checkSourceElement(node.statement);
86068607
}
86078608

8609+
function checkForOfStatement(node: ForOfStatement) {
8610+
// TODO: not yet implemented
8611+
checkGrammarForOfStatement(node);
8612+
}
8613+
86088614
function checkForInStatement(node: ForInStatement) {
86098615
// Grammar checking
8610-
if (!checkGrammarForStatementInAmbientContext(node)) {
8611-
if (node.initializer.kind === SyntaxKind.VariableDeclarationList) {
8612-
var variableList = <VariableDeclarationList>node.initializer;
8613-
if (!checkGrammarVariableDeclarationList(variableList)) {
8614-
if (variableList.declarations.length > 1) {
8615-
grammarErrorOnFirstToken(variableList.declarations[1], Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement);
8616-
}
8617-
}
8618-
}
8619-
}
8616+
checkGrammarForInOrForOfStatement(node);
86208617

86218618
// TypeScript 1.0 spec (April 2014): 5.4
86228619
// In a 'for-in' statement of the form
@@ -8628,9 +8625,6 @@ module ts {
86288625
if (variableDeclarationList.declarations.length >= 1) {
86298626
var decl = variableDeclarationList.declarations[0];
86308627
checkVariableDeclaration(decl);
8631-
if (decl.type) {
8632-
error(decl, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation);
8633-
}
86348628
}
86358629
}
86368630
else {
@@ -8661,7 +8655,7 @@ module ts {
86618655

86628656
function checkBreakOrContinueStatement(node: BreakOrContinueStatement) {
86638657
// Grammar checking
8664-
checkGrammarForStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
8658+
checkGrammarStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
86658659

86668660
// TODO: Check that target label is valid
86678661
}
@@ -8672,7 +8666,7 @@ module ts {
86728666

86738667
function checkReturnStatement(node: ReturnStatement) {
86748668
// Grammar checking
8675-
if (!checkGrammarForStatementInAmbientContext(node)) {
8669+
if (!checkGrammarStatementInAmbientContext(node)) {
86768670
var functionBlock = getContainingFunction(node);
86778671
if (!functionBlock) {
86788672
grammarErrorOnFirstToken(node, Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
@@ -8703,7 +8697,7 @@ module ts {
87038697

87048698
function checkWithStatement(node: WithStatement) {
87058699
// Grammar checking for withStatement
8706-
if (!checkGrammarForStatementInAmbientContext(node)) {
8700+
if (!checkGrammarStatementInAmbientContext(node)) {
87078701
if (node.parserContextFlags & ParserContextFlags.StrictMode) {
87088702
grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode);
87098703
}
@@ -8715,7 +8709,7 @@ module ts {
87158709

87168710
function checkSwitchStatement(node: SwitchStatement) {
87178711
// Grammar checking
8718-
checkGrammarForStatementInAmbientContext(node);
8712+
checkGrammarStatementInAmbientContext(node);
87198713

87208714
var firstDefaultClause: CaseOrDefaultClause;
87218715
var hasDuplicateDefaultClause = false;
@@ -8752,7 +8746,7 @@ module ts {
87528746

87538747
function checkLabeledStatement(node: LabeledStatement) {
87548748
// Grammar checking
8755-
if (!checkGrammarForStatementInAmbientContext(node)) {
8749+
if (!checkGrammarStatementInAmbientContext(node)) {
87568750
var current = node.parent;
87578751
while (current) {
87588752
if (isAnyFunction(current)) {
@@ -8773,7 +8767,7 @@ module ts {
87738767

87748768
function checkThrowStatement(node: ThrowStatement) {
87758769
// Grammar checking
8776-
if (!checkGrammarForStatementInAmbientContext(node)) {
8770+
if (!checkGrammarStatementInAmbientContext(node)) {
87778771
if (node.expression === undefined) {
87788772
grammarErrorAfterFirstToken(node, Diagnostics.Line_break_not_permitted_here);
87798773
}
@@ -8786,7 +8780,7 @@ module ts {
87868780

87878781
function checkTryStatement(node: TryStatement) {
87888782
// Grammar checking
8789-
checkGrammarForStatementInAmbientContext(node);
8783+
checkGrammarStatementInAmbientContext(node);
87908784

87918785
checkBlock(node.tryBlock);
87928786
var catchClause = node.catchClause;
@@ -9609,6 +9603,8 @@ module ts {
96099603
return checkForStatement(<ForStatement>node);
96109604
case SyntaxKind.ForInStatement:
96119605
return checkForInStatement(<ForInStatement>node);
9606+
case SyntaxKind.ForOfStatement:
9607+
return checkForOfStatement(<ForOfStatement>node);
96129608
case SyntaxKind.ContinueStatement:
96139609
case SyntaxKind.BreakStatement:
96149610
return checkBreakOrContinueStatement(<BreakOrContinueStatement>node);
@@ -9643,10 +9639,10 @@ module ts {
96439639
case SyntaxKind.ExportAssignment:
96449640
return checkExportAssignment(<ExportAssignment>node);
96459641
case SyntaxKind.EmptyStatement:
9646-
checkGrammarForStatementInAmbientContext(node);
9642+
checkGrammarStatementInAmbientContext(node);
96479643
return;
96489644
case SyntaxKind.DebuggerStatement:
9649-
checkGrammarForStatementInAmbientContext(node);
9645+
checkGrammarStatementInAmbientContext(node);
96509646
return;
96519647
}
96529648
}
@@ -9718,6 +9714,7 @@ module ts {
97189714
case SyntaxKind.WhileStatement:
97199715
case SyntaxKind.ForStatement:
97209716
case SyntaxKind.ForInStatement:
9717+
case SyntaxKind.ForOfStatement:
97219718
case SyntaxKind.ContinueStatement:
97229719
case SyntaxKind.BreakStatement:
97239720
case SyntaxKind.ReturnStatement:
@@ -10928,6 +10925,49 @@ module ts {
1092810925
}
1092910926
}
1093010927

10928+
function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInStatement | ForOfStatement): boolean {
10929+
if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
10930+
return true;
10931+
}
10932+
10933+
if (forInOrOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
10934+
var variableList = <VariableDeclarationList>forInOrOfStatement.initializer;
10935+
if (!checkGrammarVariableDeclarationList(variableList)) {
10936+
if (variableList.declarations.length > 1) {
10937+
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
10938+
? Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
10939+
: Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
10940+
return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
10941+
}
10942+
var firstDeclaration = variableList.declarations[0];
10943+
if (firstDeclaration.initializer) {
10944+
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
10945+
? Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
10946+
: Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
10947+
return grammarErrorOnNode(firstDeclaration.name, diagnostic);
10948+
}
10949+
if (firstDeclaration.type) {
10950+
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
10951+
? Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation
10952+
: Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
10953+
return grammarErrorOnNode(firstDeclaration, diagnostic);
10954+
}
10955+
}
10956+
}
10957+
10958+
return false;
10959+
}
10960+
10961+
function checkGrammarForOfStatement(forOfStatement: ForOfStatement): boolean {
10962+
// Temporarily disallow for-of statements until type check work is complete.
10963+
return grammarErrorOnFirstToken(forOfStatement, Diagnostics.for_of_statements_are_not_currently_supported);
10964+
if (languageVersion < ScriptTarget.ES6) {
10965+
return grammarErrorOnFirstToken(forOfStatement, Diagnostics.for_of_statements_are_only_available_when_targeting_ECMAScript_6_or_higher);
10966+
}
10967+
10968+
return checkGrammarForInOrForOfStatement(forOfStatement);
10969+
}
10970+
1093110971
function checkGrammarAccessor(accessor: MethodDeclaration): boolean {
1093210972
var kind = accessor.kind;
1093310973
if (languageVersion < ScriptTarget.ES5) {
@@ -11020,6 +11060,7 @@ module ts {
1102011060
switch (node.kind) {
1102111061
case SyntaxKind.ForStatement:
1102211062
case SyntaxKind.ForInStatement:
11063+
case SyntaxKind.ForOfStatement:
1102311064
case SyntaxKind.DoStatement:
1102411065
case SyntaxKind.WhileStatement:
1102511066
return true;
@@ -11176,6 +11217,7 @@ module ts {
1117611217
case SyntaxKind.WithStatement:
1117711218
case SyntaxKind.ForStatement:
1117811219
case SyntaxKind.ForInStatement:
11220+
case SyntaxKind.ForOfStatement:
1117911221
return false;
1118011222
case SyntaxKind.LabeledStatement:
1118111223
return allowLetAndConstDeclarations(parent.parent);
@@ -11366,7 +11408,7 @@ module ts {
1136611408
return isInAmbientContext(node) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
1136711409
}
1136811410

11369-
function checkGrammarForStatementInAmbientContext(node: Node): boolean {
11411+
function checkGrammarStatementInAmbientContext(node: Node): boolean {
1137011412
if (isInAmbientContext(node)) {
1137111413
// An accessors is already reported about the ambient context
1137211414
if (isAccessor(node.parent.kind)) {

Diff for: src/compiler/diagnosticInformationMap.generated.ts

+6
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ module ts {
147147
Merge_conflict_marker_encountered: { code: 1185, category: DiagnosticCategory.Error, key: "Merge conflict marker encountered." },
148148
A_rest_element_cannot_have_an_initializer: { code: 1186, category: DiagnosticCategory.Error, key: "A rest element cannot have an initializer." },
149149
A_parameter_property_may_not_be_a_binding_pattern: { code: 1187, category: DiagnosticCategory.Error, key: "A parameter property may not be a binding pattern." },
150+
Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: { code: 1188, category: DiagnosticCategory.Error, key: "Only a single variable declaration is allowed in a 'for...of' statement." },
151+
The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: { code: 1189, category: DiagnosticCategory.Error, key: "The variable declaration of a 'for...in' statement cannot have an initializer." },
152+
The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: { code: 1190, category: DiagnosticCategory.Error, key: "The variable declaration of a 'for...of' statement cannot have an initializer." },
150153
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
151154
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
152155
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
@@ -317,6 +320,8 @@ module ts {
317320
Property_0_does_not_exist_on_const_enum_1: { code: 2479, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on 'const' enum '{1}'." },
318321
let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: { code: 2480, category: DiagnosticCategory.Error, key: "'let' is not allowed to be used as a name in 'let' or 'const' declarations." },
319322
Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: { code: 2481, category: DiagnosticCategory.Error, key: "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'." },
323+
for_of_statements_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 2482, category: DiagnosticCategory.Error, key: "'for...of' statements are only available when targeting ECMAScript 6 or higher." },
324+
The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: { code: 2483, category: DiagnosticCategory.Error, key: "The left-hand side of a 'for...of' statement cannot use a type annotation." },
320325
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
321326
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
322327
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
@@ -462,5 +467,6 @@ module ts {
462467
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." },
463468
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." },
464469
The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression: { code: 9002, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression." },
470+
for_of_statements_are_not_currently_supported: { code: 9003, category: DiagnosticCategory.Error, key: "'for...of' statements are not currently supported." },
465471
};
466472
}

Diff for: src/compiler/diagnosticMessages.json

+25-1
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,18 @@
579579
"category": "Error",
580580
"code": 1187
581581
},
582+
"Only a single variable declaration is allowed in a 'for...of' statement.": {
583+
"category": "Error",
584+
"code": 1188
585+
},
586+
"The variable declaration of a 'for...in' statement cannot have an initializer.": {
587+
"category": "Error",
588+
"code": 1189
589+
},
590+
"The variable declaration of a 'for...of' statement cannot have an initializer.": {
591+
"category": "Error",
592+
"code": 1190
593+
},
582594

583595
"Duplicate identifier '{0}'.": {
584596
"category": "Error",
@@ -1260,6 +1272,14 @@
12601272
"category": "Error",
12611273
"code": 2481
12621274
},
1275+
"'for...of' statements are only available when targeting ECMAScript 6 or higher.": {
1276+
"category": "Error",
1277+
"code": 2482
1278+
},
1279+
"The left-hand side of a 'for...of' statement cannot use a type annotation.": {
1280+
"category": "Error",
1281+
"code": 2483
1282+
},
12631283

12641284
"Import declaration '{0}' is using private name '{1}'.": {
12651285
"category": "Error",
@@ -1536,7 +1556,7 @@
15361556
"Exported type alias '{0}' has or is using private name '{1}'.": {
15371557
"category": "Error",
15381558
"code": 4081
1539-
},
1559+
},
15401560
"The current host does not support the '{0}' option.": {
15411561
"category": "Error",
15421562
"code": 5001
@@ -1841,5 +1861,9 @@
18411861
"The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression.": {
18421862
"category": "Error",
18431863
"code": 9002
1864+
},
1865+
"'for...of' statements are not currently supported.": {
1866+
"category": "Error",
1867+
"code": 9003
18441868
}
18451869
}

0 commit comments

Comments
 (0)