Disallow destructuring in 'for...in'

This commit is contained in:
Jason Freeman 2015-02-26 18:16:21 -08:00
parent 84a22be433
commit fd0fd36597
17 changed files with 78 additions and 5 deletions

View File

@ -8806,6 +8806,11 @@ module ts {
// VarDecl must be a variable declaration without a type annotation that declares a variable of type Any,
// and Expr must be an expression of type Any, an object type, or a type parameter type.
if (node.initializer.kind === SyntaxKind.VariableDeclarationList) {
var variable = (<VariableDeclarationList>node.initializer).declarations[0];
if (variable && isBindingPattern(variable.name)) {
error(variable.name, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
}
checkForInOrForOfVariableDeclaration(node);
}
else {
@ -8815,7 +8820,10 @@ module ts {
// and Expr must be an expression of type Any, an object type, or a type parameter type.
var varExpr = <Expression>node.initializer;
var leftType = checkExpression(varExpr);
if (!allConstituentTypesHaveKind(leftType, TypeFlags.Any | TypeFlags.StringLike)) {
if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
}
else if (!allConstituentTypesHaveKind(leftType, TypeFlags.Any | TypeFlags.StringLike)) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
}
else {

View File

@ -332,6 +332,7 @@ module ts {
The_right_hand_side_of_a_for_of_statement_must_have_a_Symbol_iterator_method_that_returns_an_iterator: { code: 2488, category: DiagnosticCategory.Error, key: "The right-hand side of a 'for...of' statement must have a '[Symbol.iterator]()' method that returns an iterator." },
The_iterator_returned_by_the_right_hand_side_of_a_for_of_statement_must_have_a_next_method: { code: 2489, category: DiagnosticCategory.Error, key: "The iterator returned by the right-hand side of a 'for...of' statement must have a 'next()' method." },
The_object_returned_by_the_next_method_of_the_iterator_must_have_a_value_property: { code: 2490, category: DiagnosticCategory.Error, key: "The object returned by the next method of the iterator must have a 'value' property." },
The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern: { code: 2491, category: DiagnosticCategory.Error, key: "The left-hand side of a 'for...in' statement cannot be a destructuring pattern." },
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}'." },

View File

@ -1320,6 +1320,10 @@
"category": "Error",
"code": 2490
},
"The left-hand side of a 'for...in' statement cannot be a destructuring pattern.": {
"category": "Error",
"code": 2491
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
@ -1596,7 +1600,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

View File

@ -665,7 +665,7 @@ module ts {
}
export function isBindingPattern(node: Node) {
return node.kind === SyntaxKind.ArrayBindingPattern || node.kind === SyntaxKind.ObjectBindingPattern;
return !!node && (node.kind === SyntaxKind.ArrayBindingPattern || node.kind === SyntaxKind.ObjectBindingPattern);
}
export function isInAmbientContext(node: Node): boolean {

View File

@ -0,0 +1,7 @@
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring.ts(1,10): error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.
==== tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring.ts (1 errors) ====
for (var [a, b] in []) {}
~~~~~~
!!! error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.

View File

@ -0,0 +1,5 @@
//// [for-inStatementsDestructuring.ts]
for (var [a, b] in []) {}
//// [for-inStatementsDestructuring.js]
for (var _a = void 0, a = _a[0], b = _a[1] in []) { }

View File

@ -0,0 +1,7 @@
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring2.ts(1,10): error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.
==== tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring2.ts (1 errors) ====
for (var {a, b} in []) {}
~~~~~~
!!! error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.

View File

@ -0,0 +1,5 @@
//// [for-inStatementsDestructuring2.ts]
for (var {a, b} in []) {}
//// [for-inStatementsDestructuring2.js]
for (var _a = void 0, a = _a.a, b = _a.b in []) { }

View File

@ -0,0 +1,8 @@
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring3.ts(2,6): error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.
==== tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring3.ts (1 errors) ====
var a, b;
for ([a, b] in []) { }
~~~~~~
!!! error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.

View File

@ -0,0 +1,7 @@
//// [for-inStatementsDestructuring3.ts]
var a, b;
for ([a, b] in []) { }
//// [for-inStatementsDestructuring3.js]
var a, b;
for ([a, b] in []) { }

View File

@ -0,0 +1,8 @@
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring4.ts(2,6): error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.
==== tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring4.ts (1 errors) ====
var a, b;
for ({a, b} in []) { }
~~~~~~
!!! error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.

View File

@ -0,0 +1,7 @@
//// [for-inStatementsDestructuring4.ts]
var a, b;
for ({a, b} in []) { }
//// [for-inStatementsDestructuring4.js]
var a, b;
for ({ a: a, b: b } in []) { }

View File

@ -1,11 +1,11 @@
tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement5.ts(1,6): error TS2405: The left-hand side of a 'for...in' statement must be of type 'string' or 'any'.
tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement5.ts(1,6): error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.
tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement5.ts(1,12): error TS2304: Cannot find name 'b'.
==== tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement5.ts (2 errors) ====
for ({} in b) {
~~
!!! error TS2405: The left-hand side of a 'for...in' statement must be of type 'string' or 'any'.
!!! error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.
~
!!! error TS2304: Cannot find name 'b'.
}

View File

@ -0,0 +1 @@
for (var [a, b] in []) {}

View File

@ -0,0 +1 @@
for (var {a, b} in []) {}

View File

@ -0,0 +1,2 @@
var a, b;
for ([a, b] in []) { }

View File

@ -0,0 +1,2 @@
var a, b;
for ({a, b} in []) { }