diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bbe014753fb2b..6da9f4c8e6a4e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -41471,6 +41471,12 @@ namespace ts { } } + if (isForOfStatement(forInOrOfStatement) && !(forInOrOfStatement.flags & NodeFlags.AwaitContext) && + isIdentifier(forInOrOfStatement.initializer) && forInOrOfStatement.initializer.escapedText === "async") { + grammarErrorOnNode(forInOrOfStatement.initializer, Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_async); + return false; + } + if (forInOrOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) { const variableList = forInOrOfStatement.initializer; if (!checkGrammarVariableDeclarationList(variableList)) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 8a48d220fb938..5c8810f5ea8ca 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -319,6 +319,10 @@ "category": "Error", "code": 1105 }, + "The left-hand side of a 'for...of' statement may not be 'async'.": { + "category": "Error", + "code": 1106 + }, "Jump target cannot cross function boundary.": { "category": "Error", "code": 1107 diff --git a/tests/baselines/reference/for-inStatementsAsyncIdentifier.js b/tests/baselines/reference/for-inStatementsAsyncIdentifier.js new file mode 100644 index 0000000000000..c32f42ce571f3 --- /dev/null +++ b/tests/baselines/reference/for-inStatementsAsyncIdentifier.js @@ -0,0 +1,8 @@ +//// [for-inStatementsAsyncIdentifier.ts] +var async; +for (async in { a: 1, b: 2 }) {} + + +//// [for-inStatementsAsyncIdentifier.js] +var async; +for (async in { a: 1, b: 2 }) { } diff --git a/tests/baselines/reference/for-inStatementsAsyncIdentifier.symbols b/tests/baselines/reference/for-inStatementsAsyncIdentifier.symbols new file mode 100644 index 0000000000000..221443c0e7994 --- /dev/null +++ b/tests/baselines/reference/for-inStatementsAsyncIdentifier.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/statements/for-inStatements/for-inStatementsAsyncIdentifier.ts === +var async; +>async : Symbol(async, Decl(for-inStatementsAsyncIdentifier.ts, 0, 3)) + +for (async in { a: 1, b: 2 }) {} +>async : Symbol(async, Decl(for-inStatementsAsyncIdentifier.ts, 0, 3)) +>a : Symbol(a, Decl(for-inStatementsAsyncIdentifier.ts, 1, 15)) +>b : Symbol(b, Decl(for-inStatementsAsyncIdentifier.ts, 1, 21)) + diff --git a/tests/baselines/reference/for-inStatementsAsyncIdentifier.types b/tests/baselines/reference/for-inStatementsAsyncIdentifier.types new file mode 100644 index 0000000000000..0975ca83b0187 --- /dev/null +++ b/tests/baselines/reference/for-inStatementsAsyncIdentifier.types @@ -0,0 +1,12 @@ +=== tests/cases/conformance/statements/for-inStatements/for-inStatementsAsyncIdentifier.ts === +var async; +>async : any + +for (async in { a: 1, b: 2 }) {} +>async : any +>{ a: 1, b: 2 } : { a: number; b: number; } +>a : number +>1 : 1 +>b : number +>2 : 2 + diff --git a/tests/baselines/reference/parserForOfStatement22.errors.txt b/tests/baselines/reference/parserForOfStatement22.errors.txt new file mode 100644 index 0000000000000..8971f84ec4bb6 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement22.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement22.ts(2,6): error TS1106: The left-hand side of a 'for...of' statement may not be 'async'. + + +==== tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement22.ts (1 errors) ==== + var async; + for (async of [1, 2]) {} + ~~~~~ +!!! error TS1106: The left-hand side of a 'for...of' statement may not be 'async'. + \ No newline at end of file diff --git a/tests/baselines/reference/parserForOfStatement22.js b/tests/baselines/reference/parserForOfStatement22.js new file mode 100644 index 0000000000000..b628c2607b8d6 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement22.js @@ -0,0 +1,8 @@ +//// [parserForOfStatement22.ts] +var async; +for (async of [1, 2]) {} + + +//// [parserForOfStatement22.js] +var async; +for (async of [1, 2]) { } diff --git a/tests/baselines/reference/parserForOfStatement22.symbols b/tests/baselines/reference/parserForOfStatement22.symbols new file mode 100644 index 0000000000000..7264e268d63a1 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement22.symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement22.ts === +var async; +>async : Symbol(async, Decl(parserForOfStatement22.ts, 0, 3)) + +for (async of [1, 2]) {} +>async : Symbol(async, Decl(parserForOfStatement22.ts, 0, 3)) + diff --git a/tests/baselines/reference/parserForOfStatement22.types b/tests/baselines/reference/parserForOfStatement22.types new file mode 100644 index 0000000000000..a8d68ae36a21e --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement22.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement22.ts === +var async; +>async : any + +for (async of [1, 2]) {} +>async : any +>[1, 2] : number[] +>1 : 1 +>2 : 2 + diff --git a/tests/baselines/reference/parserForOfStatement23.js b/tests/baselines/reference/parserForOfStatement23.js new file mode 100644 index 0000000000000..00d9931b1b5f6 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement23.js @@ -0,0 +1,12 @@ +//// [parserForOfStatement23.ts] +async function foo(x: any) { + var async; + for await (async of x) {} +} + + +//// [parserForOfStatement23.js] +async function foo(x) { + var async; + for await (async of x) { } +} diff --git a/tests/baselines/reference/parserForOfStatement23.symbols b/tests/baselines/reference/parserForOfStatement23.symbols new file mode 100644 index 0000000000000..29d0a249a1edb --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement23.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement23.ts === +async function foo(x: any) { +>foo : Symbol(foo, Decl(parserForOfStatement23.ts, 0, 0)) +>x : Symbol(x, Decl(parserForOfStatement23.ts, 0, 19)) + + var async; +>async : Symbol(async, Decl(parserForOfStatement23.ts, 1, 7)) + + for await (async of x) {} +>async : Symbol(async, Decl(parserForOfStatement23.ts, 1, 7)) +>x : Symbol(x, Decl(parserForOfStatement23.ts, 0, 19)) +} + diff --git a/tests/baselines/reference/parserForOfStatement23.types b/tests/baselines/reference/parserForOfStatement23.types new file mode 100644 index 0000000000000..6591082e468db --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement23.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement23.ts === +async function foo(x: any) { +>foo : (x: any) => Promise +>x : any + + var async; +>async : any + + for await (async of x) {} +>async : any +>x : any +} + diff --git a/tests/baselines/reference/parserForOfStatement24.js b/tests/baselines/reference/parserForOfStatement24.js new file mode 100644 index 0000000000000..0b335f4bfb649 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement24.js @@ -0,0 +1,9 @@ +//// [parserForOfStatement24.ts] +var async; +for ((async) of [1, 2]); + + +//// [parserForOfStatement24.js] +var async; +for ((async) of [1, 2]) + ; diff --git a/tests/baselines/reference/parserForOfStatement24.symbols b/tests/baselines/reference/parserForOfStatement24.symbols new file mode 100644 index 0000000000000..ef874ffe6a79b --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement24.symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement24.ts === +var async; +>async : Symbol(async, Decl(parserForOfStatement24.ts, 0, 3)) + +for ((async) of [1, 2]); +>async : Symbol(async, Decl(parserForOfStatement24.ts, 0, 3)) + diff --git a/tests/baselines/reference/parserForOfStatement24.types b/tests/baselines/reference/parserForOfStatement24.types new file mode 100644 index 0000000000000..014b0954df899 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement24.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement24.ts === +var async; +>async : any + +for ((async) of [1, 2]); +>(async) : any +>async : any +>[1, 2] : number[] +>1 : 1 +>2 : 2 + diff --git a/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement22.ts b/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement22.ts new file mode 100644 index 0000000000000..87f569dbfb52f --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement22.ts @@ -0,0 +1,4 @@ +// @target: esnext + +var async; +for (async of [1, 2]) {} diff --git a/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement23.ts b/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement23.ts new file mode 100644 index 0000000000000..5a3601380b90a --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement23.ts @@ -0,0 +1,6 @@ +// @target: esnext + +async function foo(x: any) { + var async; + for await (async of x) {} +} diff --git a/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement24.ts b/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement24.ts new file mode 100644 index 0000000000000..3846bd0a91a7d --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement24.ts @@ -0,0 +1,4 @@ +// @target: esnext + +var async; +for ((async) of [1, 2]); diff --git a/tests/cases/conformance/statements/for-inStatements/for-inStatementsAsyncIdentifier.ts b/tests/cases/conformance/statements/for-inStatements/for-inStatementsAsyncIdentifier.ts new file mode 100644 index 0000000000000..ae63dd31362ab --- /dev/null +++ b/tests/cases/conformance/statements/for-inStatements/for-inStatementsAsyncIdentifier.ts @@ -0,0 +1,4 @@ +// @target: esnext + +var async; +for (async in { a: 1, b: 2 }) {}