Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ module ts {
case SyntaxKind.CatchClause:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.SwitchStatement:
bindChildren(node, 0, /*isBlockScopeContainer*/ true);
break;
Expand Down
100 changes: 71 additions & 29 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4642,6 +4642,7 @@ module ts {
case SyntaxKind.WhileStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.ReturnStatement:
case SyntaxKind.WithStatement:
case SyntaxKind.SwitchStatement:
Expand Down Expand Up @@ -8237,7 +8238,7 @@ module ts {
function checkBlock(node: Block) {
// Grammar checking for SyntaxKind.Block
if (node.kind === SyntaxKind.Block) {
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
}

forEach(node.statements, checkSourceElement);
Expand Down Expand Up @@ -8553,14 +8554,14 @@ module ts {

function checkExpressionStatement(node: ExpressionStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node)
checkGrammarStatementInAmbientContext(node)

checkExpression(node.expression);
}

function checkIfStatement(node: IfStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);

checkExpression(node.expression);
checkSourceElement(node.thenStatement);
Expand All @@ -8569,23 +8570,23 @@ module ts {

function checkDoStatement(node: DoStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);

checkSourceElement(node.statement);
checkExpression(node.expression);
}

function checkWhileStatement(node: WhileStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);

checkExpression(node.expression);
checkSourceElement(node.statement);
}

function checkForStatement(node: ForStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.initializer && node.initializer.kind == SyntaxKind.VariableDeclarationList) {
checkGrammarVariableDeclarationList(<VariableDeclarationList>node.initializer);
}
Expand All @@ -8605,18 +8606,14 @@ module ts {
checkSourceElement(node.statement);
}

function checkForOfStatement(node: ForOfStatement) {
// TODO: not yet implemented
checkGrammarForOfStatement(node);
}

function checkForInStatement(node: ForInStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (node.initializer.kind === SyntaxKind.VariableDeclarationList) {
var variableList = <VariableDeclarationList>node.initializer;
if (!checkGrammarVariableDeclarationList(variableList)) {
if (variableList.declarations.length > 1) {
grammarErrorOnFirstToken(variableList.declarations[1], Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement);
}
}
}
}
checkGrammarForInOrForOfStatement(node);

// TypeScript 1.0 spec (April 2014): 5.4
// In a 'for-in' statement of the form
Expand All @@ -8628,9 +8625,6 @@ module ts {
if (variableDeclarationList.declarations.length >= 1) {
var decl = variableDeclarationList.declarations[0];
checkVariableDeclaration(decl);
if (decl.type) {
error(decl, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation);
}
}
}
else {
Expand Down Expand Up @@ -8661,7 +8655,7 @@ module ts {

function checkBreakOrContinueStatement(node: BreakOrContinueStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
checkGrammarStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);

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

function checkReturnStatement(node: ReturnStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
var functionBlock = getContainingFunction(node);
if (!functionBlock) {
grammarErrorOnFirstToken(node, Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
Expand Down Expand Up @@ -8703,7 +8697,7 @@ module ts {

function checkWithStatement(node: WithStatement) {
// Grammar checking for withStatement
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.parserContextFlags & ParserContextFlags.StrictMode) {
grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode);
}
Expand All @@ -8715,7 +8709,7 @@ module ts {

function checkSwitchStatement(node: SwitchStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);

var firstDefaultClause: CaseOrDefaultClause;
var hasDuplicateDefaultClause = false;
Expand Down Expand Up @@ -8752,7 +8746,7 @@ module ts {

function checkLabeledStatement(node: LabeledStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
var current = node.parent;
while (current) {
if (isAnyFunction(current)) {
Expand All @@ -8773,7 +8767,7 @@ module ts {

function checkThrowStatement(node: ThrowStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.expression === undefined) {
grammarErrorAfterFirstToken(node, Diagnostics.Line_break_not_permitted_here);
}
Expand All @@ -8786,7 +8780,7 @@ module ts {

function checkTryStatement(node: TryStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);

checkBlock(node.tryBlock);
var catchClause = node.catchClause;
Expand Down Expand Up @@ -9609,6 +9603,8 @@ module ts {
return checkForStatement(<ForStatement>node);
case SyntaxKind.ForInStatement:
return checkForInStatement(<ForInStatement>node);
case SyntaxKind.ForOfStatement:
return checkForOfStatement(<ForOfStatement>node);
case SyntaxKind.ContinueStatement:
case SyntaxKind.BreakStatement:
return checkBreakOrContinueStatement(<BreakOrContinueStatement>node);
Expand Down Expand Up @@ -9643,10 +9639,10 @@ module ts {
case SyntaxKind.ExportAssignment:
return checkExportAssignment(<ExportAssignment>node);
case SyntaxKind.EmptyStatement:
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
return;
case SyntaxKind.DebuggerStatement:
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
return;
}
}
Expand Down Expand Up @@ -9718,6 +9714,7 @@ module ts {
case SyntaxKind.WhileStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.ContinueStatement:
case SyntaxKind.BreakStatement:
case SyntaxKind.ReturnStatement:
Expand Down Expand Up @@ -10928,6 +10925,49 @@ module ts {
}
}

function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInStatement | ForOfStatement): boolean {
if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
return true;
}

if (forInOrOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
var variableList = <VariableDeclarationList>forInOrOfStatement.initializer;
if (!checkGrammarVariableDeclarationList(variableList)) {
if (variableList.declarations.length > 1) {
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
? Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
: Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
}
var firstDeclaration = variableList.declarations[0];
if (firstDeclaration.initializer) {
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
? Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
: Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
return grammarErrorOnNode(firstDeclaration.name, diagnostic);
}
if (firstDeclaration.type) {
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
? Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation
: Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
return grammarErrorOnNode(firstDeclaration, diagnostic);
}
}
}

return false;
}

function checkGrammarForOfStatement(forOfStatement: ForOfStatement): boolean {
// Temporarily disallow for-of statements until type check work is complete.
return grammarErrorOnFirstToken(forOfStatement, Diagnostics.for_of_statements_are_not_currently_supported);
if (languageVersion < ScriptTarget.ES6) {
return grammarErrorOnFirstToken(forOfStatement, Diagnostics.for_of_statements_are_only_available_when_targeting_ECMAScript_6_or_higher);
}

return checkGrammarForInOrForOfStatement(forOfStatement);
}

function checkGrammarAccessor(accessor: MethodDeclaration): boolean {
var kind = accessor.kind;
if (languageVersion < ScriptTarget.ES5) {
Expand Down Expand Up @@ -11020,6 +11060,7 @@ module ts {
switch (node.kind) {
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.DoStatement:
case SyntaxKind.WhileStatement:
return true;
Expand Down Expand Up @@ -11176,6 +11217,7 @@ module ts {
case SyntaxKind.WithStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
return false;
case SyntaxKind.LabeledStatement:
return allowLetAndConstDeclarations(parent.parent);
Expand Down Expand Up @@ -11366,7 +11408,7 @@ module ts {
return isInAmbientContext(node) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
}

function checkGrammarForStatementInAmbientContext(node: Node): boolean {
function checkGrammarStatementInAmbientContext(node: Node): boolean {
if (isInAmbientContext(node)) {
// An accessors is already reported about the ambient context
if (isAccessor(node.parent.kind)) {
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ module ts {
Merge_conflict_marker_encountered: { code: 1185, category: DiagnosticCategory.Error, key: "Merge conflict marker encountered." },
A_rest_element_cannot_have_an_initializer: { code: 1186, category: DiagnosticCategory.Error, key: "A rest element cannot have an initializer." },
A_parameter_property_may_not_be_a_binding_pattern: { code: 1187, category: DiagnosticCategory.Error, key: "A parameter property may not be a binding pattern." },
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." },
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." },
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." },
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
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." },
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
Expand Down Expand Up @@ -317,6 +320,8 @@ module ts {
Property_0_does_not_exist_on_const_enum_1: { code: 2479, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on 'const' enum '{1}'." },
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." },
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}'." },
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." },
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." },
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
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}'." },
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}'." },
Expand Down Expand Up @@ -462,5 +467,6 @@ module ts {
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." },
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." },
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." },
for_of_statements_are_not_currently_supported: { code: 9003, category: DiagnosticCategory.Error, key: "'for...of' statements are not currently supported." },
};
}
26 changes: 25 additions & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,18 @@
"category": "Error",
"code": 1187
},
"Only a single variable declaration is allowed in a 'for...of' statement.": {
"category": "Error",
"code": 1188
},
"The variable declaration of a 'for...in' statement cannot have an initializer.": {
"category": "Error",
"code": 1189
},
"The variable declaration of a 'for...of' statement cannot have an initializer.": {
"category": "Error",
"code": 1190
},

"Duplicate identifier '{0}'.": {
"category": "Error",
Expand Down Expand Up @@ -1260,6 +1272,14 @@
"category": "Error",
"code": 2481
},
"'for...of' statements are only available when targeting ECMAScript 6 or higher.": {
"category": "Error",
"code": 2482
},
"The left-hand side of a 'for...of' statement cannot use a type annotation.": {
"category": "Error",
"code": 2483
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down Expand Up @@ -1536,7 +1556,7 @@
"Exported type alias '{0}' has or is using private name '{1}'.": {
"category": "Error",
"code": 4081
},
},
"The current host does not support the '{0}' option.": {
"category": "Error",
"code": 5001
Expand Down Expand Up @@ -1841,5 +1861,9 @@
"The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression.": {
"category": "Error",
"code": 9002
},
"'for...of' statements are not currently supported.": {
"category": "Error",
"code": 9003
}
}
Loading