diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index a3ae750f6e7..16d67fcef38 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -5,6 +5,38 @@ namespace ts { AsyncMethodsWithSuper = 1 << 0 } + // Facts we track as we traverse the tree + const enum HierarchyFacts { + None = 0, + + // + // Ancestor facts + // + + HasLexicalThis = 1 << 0, + IterationContainer = 1 << 1, + // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below. + + // + // Ancestor masks + // + + AncestorFactsMask = (IterationContainer << 1) - 1, + + SourceFileIncludes = HasLexicalThis, + SourceFileExcludes = IterationContainer, + StrictModeSourceFileIncludes = None, + + ClassOrFunctionIncludes = HasLexicalThis, + ClassOrFunctionExcludes = IterationContainer, + + ArrowFunctionIncludes = None, + ArrowFunctionExcludes = ClassOrFunctionExcludes, + + IterationStatementIncludes = IterationContainer, + IterationStatementExcludes = None, + } + export function transformES2018(context: TransformationContext) { const { resumeLexicalEnvironment, @@ -26,7 +58,7 @@ namespace ts { let enabledSubstitutions: ESNextSubstitutionFlags; let enclosingFunctionFlags: FunctionFlags; let enclosingSuperContainerFlags: NodeCheckFlags = 0; - let hasLexicalThis: boolean; + let hierarchyFacts: HierarchyFacts = 0; let currentSourceFile: SourceFile; let taggedTemplateStringDeclarations: VariableDeclaration[]; @@ -40,6 +72,30 @@ namespace ts { return chainBundle(transformSourceFile); + function affectsSubtree(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) { + return hierarchyFacts !== (hierarchyFacts & ~excludeFacts | includeFacts); + } + + /** + * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification. + * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree. + * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree. + */ + function enterSubtree(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) { + const ancestorFacts = hierarchyFacts; + hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & HierarchyFacts.AncestorFactsMask; + return ancestorFacts; + } + + /** + * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's + * subtree. + * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree. + */ + function exitSubtree(ancestorFacts: HierarchyFacts) { + hierarchyFacts = ancestorFacts; + } + function recordTaggedTemplateString(temp: Identifier) { taggedTemplateStringDeclarations = append( taggedTemplateStringDeclarations, @@ -75,11 +131,11 @@ namespace ts { return node; } - function doWithLexicalThis(cb: (value: T) => U, value: T) { - if (!hasLexicalThis) { - hasLexicalThis = true; + function doWithHierarchyFacts(cb: (value: T) => U, value: T, excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) { + if (affectsSubtree(excludeFacts, includeFacts)) { + const ancestorFacts = enterSubtree(excludeFacts, includeFacts); const result = cb(value); - hasLexicalThis = false; + exitSubtree(ancestorFacts); return result; } return cb(value); @@ -112,26 +168,66 @@ namespace ts { return visitVariableStatement(node as VariableStatement); case SyntaxKind.VariableDeclaration: return visitVariableDeclaration(node as VariableDeclaration); + case SyntaxKind.DoStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.ForInStatement: + return doWithHierarchyFacts( + visitDefault, + node, + HierarchyFacts.IterationStatementExcludes, + HierarchyFacts.IterationStatementIncludes); case SyntaxKind.ForOfStatement: return visitForOfStatement(node as ForOfStatement, /*outermostLabeledStatement*/ undefined); case SyntaxKind.ForStatement: - return visitForStatement(node as ForStatement); + return doWithHierarchyFacts( + visitForStatement, + node as ForStatement, + HierarchyFacts.IterationStatementExcludes, + HierarchyFacts.IterationStatementIncludes); case SyntaxKind.VoidExpression: return visitVoidExpression(node as VoidExpression); case SyntaxKind.Constructor: - return doWithLexicalThis(visitConstructorDeclaration, node as ConstructorDeclaration); + return doWithHierarchyFacts( + visitConstructorDeclaration, + node as ConstructorDeclaration, + HierarchyFacts.ClassOrFunctionExcludes, + HierarchyFacts.ClassOrFunctionIncludes); case SyntaxKind.MethodDeclaration: - return doWithLexicalThis(visitMethodDeclaration, node as MethodDeclaration); + return doWithHierarchyFacts( + visitMethodDeclaration, + node as MethodDeclaration, + HierarchyFacts.ClassOrFunctionExcludes, + HierarchyFacts.ClassOrFunctionIncludes); case SyntaxKind.GetAccessor: - return doWithLexicalThis(visitGetAccessorDeclaration, node as GetAccessorDeclaration); + return doWithHierarchyFacts( + visitGetAccessorDeclaration, + node as GetAccessorDeclaration, + HierarchyFacts.ClassOrFunctionExcludes, + HierarchyFacts.ClassOrFunctionIncludes); case SyntaxKind.SetAccessor: - return doWithLexicalThis(visitSetAccessorDeclaration, node as SetAccessorDeclaration); + return doWithHierarchyFacts( + visitSetAccessorDeclaration, + node as SetAccessorDeclaration, + HierarchyFacts.ClassOrFunctionExcludes, + HierarchyFacts.ClassOrFunctionIncludes); case SyntaxKind.FunctionDeclaration: - return doWithLexicalThis(visitFunctionDeclaration, node as FunctionDeclaration); + return doWithHierarchyFacts( + visitFunctionDeclaration, + node as FunctionDeclaration, + HierarchyFacts.ClassOrFunctionExcludes, + HierarchyFacts.ClassOrFunctionIncludes); case SyntaxKind.FunctionExpression: - return doWithLexicalThis(visitFunctionExpression, node as FunctionExpression); + return doWithHierarchyFacts( + visitFunctionExpression, + node as FunctionExpression, + HierarchyFacts.ClassOrFunctionExcludes, + HierarchyFacts.ClassOrFunctionIncludes); case SyntaxKind.ArrowFunction: - return visitArrowFunction(node as ArrowFunction); + return doWithHierarchyFacts( + visitArrowFunction, + node as ArrowFunction, + HierarchyFacts.ArrowFunctionExcludes, + HierarchyFacts.ArrowFunctionIncludes); case SyntaxKind.Parameter: return visitParameter(node as ParameterDeclaration); case SyntaxKind.ExpressionStatement: @@ -152,7 +248,11 @@ namespace ts { return visitEachChild(node, visitor, context); case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: - return doWithLexicalThis(visitDefault, node); + return doWithHierarchyFacts( + visitDefault, + node, + HierarchyFacts.ClassOrFunctionExcludes, + HierarchyFacts.ClassOrFunctionIncludes); default: return visitEachChild(node, visitor, context); } @@ -231,7 +331,7 @@ namespace ts { if (statement.kind === SyntaxKind.ForOfStatement && (statement).awaitModifier) { return visitForOfStatement(statement, node); } - return restoreEnclosingLabel(visitEachChild(statement, visitor, context), node); + return restoreEnclosingLabel(visitNode(statement, visitor, isStatement, liftToBlock), node); } return visitEachChild(node, visitor, context); } @@ -311,14 +411,20 @@ namespace ts { } function visitSourceFile(node: SourceFile): SourceFile { + const ancestorFacts = enterSubtree( + HierarchyFacts.SourceFileExcludes, + isEffectiveStrictModeSourceFile(node, compilerOptions) ? + HierarchyFacts.StrictModeSourceFileIncludes : + HierarchyFacts.SourceFileIncludes); exportedVariableStatement = false; - hasLexicalThis = !isEffectiveStrictModeSourceFile(node, compilerOptions); const visited = visitEachChild(node, visitor, context); const statement = concatenate(visited.statements, taggedTemplateStringDeclarations && [ createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList(taggedTemplateStringDeclarations)) ]); - return updateSourceFileNode(visited, setTextRange(createNodeArray(statement), node.statements)); + const result = updateSourceFileNode(visited, setTextRange(createNodeArray(statement), node.statements)); + exitSubtree(ancestorFacts); + return result; } function visitTaggedTemplateExpression(node: TaggedTemplateExpression) { @@ -441,15 +547,15 @@ namespace ts { * @param node A ForOfStatement. */ function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined): VisitResult { + const ancestorFacts = enterSubtree(HierarchyFacts.IterationStatementExcludes, HierarchyFacts.IterationStatementIncludes); if (node.initializer.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { node = transformForOfStatementWithObjectRest(node); } - if (node.awaitModifier) { - return transformForAwaitOfStatement(node, outermostLabeledStatement); - } - else { - return restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement); - } + const result = node.awaitModifier ? + transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) : + restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement); + exitSubtree(ancestorFacts); + return result; } function transformForOfStatementWithObjectRest(node: ForOfStatement) { @@ -528,7 +634,7 @@ namespace ts { : createAwait(expression); } - function transformForAwaitOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined) { + function transformForAwaitOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, ancestorFacts: HierarchyFacts) { const expression = visitNode(node.expression, visitor, isExpression); const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined); const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined); @@ -544,13 +650,18 @@ namespace ts { hoistVariableDeclaration(errorRecord); hoistVariableDeclaration(returnMethod); + // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration + const initializer = ancestorFacts & HierarchyFacts.IterationContainer ? + inlineExpressions([createAssignment(errorRecord, createVoidZero()), callValues]) : + callValues; + const forStatement = setEmitFlags( setTextRange( createFor( /*initializer*/ setEmitFlags( setTextRange( createVariableDeclarationList([ - setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, callValues), node.expression), + setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression), createVariableDeclaration(result) ]), node.expression @@ -809,7 +920,7 @@ namespace ts { visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset) ) ), - hasLexicalThis + !!(hierarchyFacts & HierarchyFacts.HasLexicalThis) ) ); diff --git a/tests/baselines/reference/emitter.forAwait.es2015.js b/tests/baselines/reference/emitter.forAwait(target=es2015).js similarity index 81% rename from tests/baselines/reference/emitter.forAwait.es2015.js rename to tests/baselines/reference/emitter.forAwait(target=es2015).js index 2b2cc3ce08d..a651bbbb92c 100644 --- a/tests/baselines/reference/emitter.forAwait.es2015.js +++ b/tests/baselines/reference/emitter.forAwait(target=es2015).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/emitter/es2015/forAwait/emitter.forAwait.es2015.ts] //// +//// [tests/cases/conformance/statements/for-await-ofStatements/emitter.forAwait.ts] //// //// [file1.ts] async function f1() { @@ -40,6 +40,15 @@ async function* f6() { continue outer; } } +//// [file7.ts] +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { + let y: any; + for (;;) { + for await (const x of y) { + } + } +} //// [file1.js] var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { @@ -264,3 +273,44 @@ function f6() { } }); } +//// [file7.js] +var __asyncValues = (this && this.__asyncValues) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +}; +var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } +var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +}; +// https://github.com/microsoft/TypeScript/issues/36166 +function f7() { + return __asyncGenerator(this, arguments, function* f7_1() { + var e_1, _a; + let y; + for (;;) { + try { + for (var y_1 = (e_1 = void 0, __asyncValues(y)), y_1_1; y_1_1 = yield __await(y_1.next()), !y_1_1.done;) { + const x = y_1_1.value; + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (y_1_1 && !y_1_1.done && (_a = y_1.return)) yield __await(_a.call(y_1)); + } + finally { if (e_1) throw e_1.error; } + } + } + }); +} diff --git a/tests/baselines/reference/emitter.forAwait.es2017.symbols b/tests/baselines/reference/emitter.forAwait(target=es2015).symbols similarity index 63% rename from tests/baselines/reference/emitter.forAwait.es2017.symbols rename to tests/baselines/reference/emitter.forAwait(target=es2015).symbols index 184d26c1266..f32170c889a 100644 --- a/tests/baselines/reference/emitter.forAwait.es2017.symbols +++ b/tests/baselines/reference/emitter.forAwait(target=es2015).symbols @@ -1,4 +1,4 @@ -=== tests/cases/conformance/emitter/es2017/forAwait/file1.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file1.ts === async function f1() { >f1 : Symbol(f1, Decl(file1.ts, 0, 0)) @@ -10,7 +10,7 @@ async function f1() { >y : Symbol(y, Decl(file1.ts, 1, 7)) } } -=== tests/cases/conformance/emitter/es2017/forAwait/file2.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file2.ts === async function f2() { >f2 : Symbol(f2, Decl(file2.ts, 0, 0)) @@ -23,7 +23,7 @@ async function f2() { >y : Symbol(y, Decl(file2.ts, 1, 15)) } } -=== tests/cases/conformance/emitter/es2017/forAwait/file3.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file3.ts === async function* f3() { >f3 : Symbol(f3, Decl(file3.ts, 0, 0)) @@ -35,7 +35,7 @@ async function* f3() { >y : Symbol(y, Decl(file3.ts, 1, 7)) } } -=== tests/cases/conformance/emitter/es2017/forAwait/file4.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file4.ts === async function* f4() { >f4 : Symbol(f4, Decl(file4.ts, 0, 0)) @@ -48,7 +48,7 @@ async function* f4() { >y : Symbol(y, Decl(file4.ts, 1, 15)) } } -=== tests/cases/conformance/emitter/es2017/forAwait/file5.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file5.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function f5() { >f5 : Symbol(f5, Decl(file5.ts, 0, 0)) @@ -63,7 +63,7 @@ async function f5() { continue outer; } } -=== tests/cases/conformance/emitter/es2017/forAwait/file6.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file6.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function* f6() { >f6 : Symbol(f6, Decl(file6.ts, 0, 0)) @@ -78,3 +78,18 @@ async function* f6() { continue outer; } } +=== tests/cases/conformance/statements/for-await-ofStatements/file7.ts === +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { +>f7 : Symbol(f7, Decl(file7.ts, 0, 0)) + + let y: any; +>y : Symbol(y, Decl(file7.ts, 2, 7)) + + for (;;) { + for await (const x of y) { +>x : Symbol(x, Decl(file7.ts, 4, 24)) +>y : Symbol(y, Decl(file7.ts, 2, 7)) + } + } +} diff --git a/tests/baselines/reference/emitter.forAwait.es2018.types b/tests/baselines/reference/emitter.forAwait(target=es2015).types similarity index 56% rename from tests/baselines/reference/emitter.forAwait.es2018.types rename to tests/baselines/reference/emitter.forAwait(target=es2015).types index a9b3a94dead..406f669ab3a 100644 --- a/tests/baselines/reference/emitter.forAwait.es2018.types +++ b/tests/baselines/reference/emitter.forAwait(target=es2015).types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/emitter/es2018/forAwait/file1.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file1.ts === async function f1() { >f1 : () => Promise @@ -10,7 +10,7 @@ async function f1() { >y : any } } -=== tests/cases/conformance/emitter/es2018/forAwait/file2.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file2.ts === async function f2() { >f2 : () => Promise @@ -23,7 +23,7 @@ async function f2() { >y : any } } -=== tests/cases/conformance/emitter/es2018/forAwait/file3.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file3.ts === async function* f3() { >f3 : () => AsyncGenerator @@ -35,7 +35,7 @@ async function* f3() { >y : any } } -=== tests/cases/conformance/emitter/es2018/forAwait/file4.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file4.ts === async function* f4() { >f4 : () => AsyncGenerator @@ -48,7 +48,7 @@ async function* f4() { >y : any } } -=== tests/cases/conformance/emitter/es2018/forAwait/file5.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file5.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function f5() { >f5 : () => Promise @@ -65,7 +65,7 @@ async function f5() { >outer : any } } -=== tests/cases/conformance/emitter/es2018/forAwait/file6.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file6.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function* f6() { >f6 : () => AsyncGenerator @@ -82,4 +82,18 @@ async function* f6() { >outer : any } } +=== tests/cases/conformance/statements/for-await-ofStatements/file7.ts === +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { +>f7 : () => AsyncGenerator + let y: any; +>y : any + + for (;;) { + for await (const x of y) { +>x : any +>y : any + } + } +} diff --git a/tests/baselines/reference/emitter.forAwait.es2017.js b/tests/baselines/reference/emitter.forAwait(target=es2017).js similarity index 79% rename from tests/baselines/reference/emitter.forAwait.es2017.js rename to tests/baselines/reference/emitter.forAwait(target=es2017).js index dd0e8aede2b..e7ab46bccc5 100644 --- a/tests/baselines/reference/emitter.forAwait.es2017.js +++ b/tests/baselines/reference/emitter.forAwait(target=es2017).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/emitter/es2017/forAwait/emitter.forAwait.es2017.ts] //// +//// [tests/cases/conformance/statements/for-await-ofStatements/emitter.forAwait.ts] //// //// [file1.ts] async function f1() { @@ -40,6 +40,15 @@ async function* f6() { continue outer; } } +//// [file7.ts] +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { + let y: any; + for (;;) { + for await (const x of y) { + } + } +} //// [file1.js] var __asyncValues = (this && this.__asyncValues) || function (o) { @@ -231,3 +240,44 @@ function f6() { } }); } +//// [file7.js] +var __asyncValues = (this && this.__asyncValues) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +}; +var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } +var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +}; +// https://github.com/microsoft/TypeScript/issues/36166 +function f7() { + return __asyncGenerator(this, arguments, function* f7_1() { + var e_1, _a; + let y; + for (;;) { + try { + for (var y_1 = (e_1 = void 0, __asyncValues(y)), y_1_1; y_1_1 = yield __await(y_1.next()), !y_1_1.done;) { + const x = y_1_1.value; + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (y_1_1 && !y_1_1.done && (_a = y_1.return)) yield __await(_a.call(y_1)); + } + finally { if (e_1) throw e_1.error; } + } + } + }); +} diff --git a/tests/baselines/reference/emitter.forAwait.es2015.symbols b/tests/baselines/reference/emitter.forAwait(target=es2017).symbols similarity index 63% rename from tests/baselines/reference/emitter.forAwait.es2015.symbols rename to tests/baselines/reference/emitter.forAwait(target=es2017).symbols index bc75908f601..f32170c889a 100644 --- a/tests/baselines/reference/emitter.forAwait.es2015.symbols +++ b/tests/baselines/reference/emitter.forAwait(target=es2017).symbols @@ -1,4 +1,4 @@ -=== tests/cases/conformance/emitter/es2015/forAwait/file1.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file1.ts === async function f1() { >f1 : Symbol(f1, Decl(file1.ts, 0, 0)) @@ -10,7 +10,7 @@ async function f1() { >y : Symbol(y, Decl(file1.ts, 1, 7)) } } -=== tests/cases/conformance/emitter/es2015/forAwait/file2.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file2.ts === async function f2() { >f2 : Symbol(f2, Decl(file2.ts, 0, 0)) @@ -23,7 +23,7 @@ async function f2() { >y : Symbol(y, Decl(file2.ts, 1, 15)) } } -=== tests/cases/conformance/emitter/es2015/forAwait/file3.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file3.ts === async function* f3() { >f3 : Symbol(f3, Decl(file3.ts, 0, 0)) @@ -35,7 +35,7 @@ async function* f3() { >y : Symbol(y, Decl(file3.ts, 1, 7)) } } -=== tests/cases/conformance/emitter/es2015/forAwait/file4.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file4.ts === async function* f4() { >f4 : Symbol(f4, Decl(file4.ts, 0, 0)) @@ -48,7 +48,7 @@ async function* f4() { >y : Symbol(y, Decl(file4.ts, 1, 15)) } } -=== tests/cases/conformance/emitter/es2015/forAwait/file5.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file5.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function f5() { >f5 : Symbol(f5, Decl(file5.ts, 0, 0)) @@ -63,7 +63,7 @@ async function f5() { continue outer; } } -=== tests/cases/conformance/emitter/es2015/forAwait/file6.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file6.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function* f6() { >f6 : Symbol(f6, Decl(file6.ts, 0, 0)) @@ -78,3 +78,18 @@ async function* f6() { continue outer; } } +=== tests/cases/conformance/statements/for-await-ofStatements/file7.ts === +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { +>f7 : Symbol(f7, Decl(file7.ts, 0, 0)) + + let y: any; +>y : Symbol(y, Decl(file7.ts, 2, 7)) + + for (;;) { + for await (const x of y) { +>x : Symbol(x, Decl(file7.ts, 4, 24)) +>y : Symbol(y, Decl(file7.ts, 2, 7)) + } + } +} diff --git a/tests/baselines/reference/emitter.forAwait.es2015.types b/tests/baselines/reference/emitter.forAwait(target=es2017).types similarity index 56% rename from tests/baselines/reference/emitter.forAwait.es2015.types rename to tests/baselines/reference/emitter.forAwait(target=es2017).types index 3c345386c37..406f669ab3a 100644 --- a/tests/baselines/reference/emitter.forAwait.es2015.types +++ b/tests/baselines/reference/emitter.forAwait(target=es2017).types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/emitter/es2015/forAwait/file1.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file1.ts === async function f1() { >f1 : () => Promise @@ -10,7 +10,7 @@ async function f1() { >y : any } } -=== tests/cases/conformance/emitter/es2015/forAwait/file2.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file2.ts === async function f2() { >f2 : () => Promise @@ -23,7 +23,7 @@ async function f2() { >y : any } } -=== tests/cases/conformance/emitter/es2015/forAwait/file3.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file3.ts === async function* f3() { >f3 : () => AsyncGenerator @@ -35,7 +35,7 @@ async function* f3() { >y : any } } -=== tests/cases/conformance/emitter/es2015/forAwait/file4.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file4.ts === async function* f4() { >f4 : () => AsyncGenerator @@ -48,7 +48,7 @@ async function* f4() { >y : any } } -=== tests/cases/conformance/emitter/es2015/forAwait/file5.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file5.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function f5() { >f5 : () => Promise @@ -65,7 +65,7 @@ async function f5() { >outer : any } } -=== tests/cases/conformance/emitter/es2015/forAwait/file6.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file6.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function* f6() { >f6 : () => AsyncGenerator @@ -82,3 +82,18 @@ async function* f6() { >outer : any } } +=== tests/cases/conformance/statements/for-await-ofStatements/file7.ts === +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { +>f7 : () => AsyncGenerator + + let y: any; +>y : any + + for (;;) { + for await (const x of y) { +>x : any +>y : any + } + } +} diff --git a/tests/baselines/reference/emitter.forAwait.es2018.js b/tests/baselines/reference/emitter.forAwait(target=es2018).js similarity index 73% rename from tests/baselines/reference/emitter.forAwait.es2018.js rename to tests/baselines/reference/emitter.forAwait(target=es2018).js index f9ae2b1bd95..f111d9d4bc1 100644 --- a/tests/baselines/reference/emitter.forAwait.es2018.js +++ b/tests/baselines/reference/emitter.forAwait(target=es2018).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/emitter/es2018/forAwait/emitter.forAwait.es2018.ts] //// +//// [tests/cases/conformance/statements/for-await-ofStatements/emitter.forAwait.ts] //// //// [file1.ts] async function f1() { @@ -39,8 +39,16 @@ async function* f6() { outer: for await (const x of y) { continue outer; } -} - +} +//// [file7.ts] +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { + let y: any; + for (;;) { + for await (const x of y) { + } + } +} //// [file1.js] async function f1() { @@ -82,3 +90,12 @@ async function* f6() { continue outer; } } +//// [file7.js] +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { + let y; + for (;;) { + for await (const x of y) { + } + } +} diff --git a/tests/baselines/reference/emitter.forAwait.es2018.symbols b/tests/baselines/reference/emitter.forAwait(target=es2018).symbols similarity index 63% rename from tests/baselines/reference/emitter.forAwait.es2018.symbols rename to tests/baselines/reference/emitter.forAwait(target=es2018).symbols index c1beab7fb78..f32170c889a 100644 --- a/tests/baselines/reference/emitter.forAwait.es2018.symbols +++ b/tests/baselines/reference/emitter.forAwait(target=es2018).symbols @@ -1,4 +1,4 @@ -=== tests/cases/conformance/emitter/es2018/forAwait/file1.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file1.ts === async function f1() { >f1 : Symbol(f1, Decl(file1.ts, 0, 0)) @@ -10,7 +10,7 @@ async function f1() { >y : Symbol(y, Decl(file1.ts, 1, 7)) } } -=== tests/cases/conformance/emitter/es2018/forAwait/file2.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file2.ts === async function f2() { >f2 : Symbol(f2, Decl(file2.ts, 0, 0)) @@ -23,7 +23,7 @@ async function f2() { >y : Symbol(y, Decl(file2.ts, 1, 15)) } } -=== tests/cases/conformance/emitter/es2018/forAwait/file3.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file3.ts === async function* f3() { >f3 : Symbol(f3, Decl(file3.ts, 0, 0)) @@ -35,7 +35,7 @@ async function* f3() { >y : Symbol(y, Decl(file3.ts, 1, 7)) } } -=== tests/cases/conformance/emitter/es2018/forAwait/file4.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file4.ts === async function* f4() { >f4 : Symbol(f4, Decl(file4.ts, 0, 0)) @@ -48,7 +48,7 @@ async function* f4() { >y : Symbol(y, Decl(file4.ts, 1, 15)) } } -=== tests/cases/conformance/emitter/es2018/forAwait/file5.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file5.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function f5() { >f5 : Symbol(f5, Decl(file5.ts, 0, 0)) @@ -63,7 +63,7 @@ async function f5() { continue outer; } } -=== tests/cases/conformance/emitter/es2018/forAwait/file6.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file6.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function* f6() { >f6 : Symbol(f6, Decl(file6.ts, 0, 0)) @@ -78,4 +78,18 @@ async function* f6() { continue outer; } } +=== tests/cases/conformance/statements/for-await-ofStatements/file7.ts === +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { +>f7 : Symbol(f7, Decl(file7.ts, 0, 0)) + let y: any; +>y : Symbol(y, Decl(file7.ts, 2, 7)) + + for (;;) { + for await (const x of y) { +>x : Symbol(x, Decl(file7.ts, 4, 24)) +>y : Symbol(y, Decl(file7.ts, 2, 7)) + } + } +} diff --git a/tests/baselines/reference/emitter.forAwait.es2017.types b/tests/baselines/reference/emitter.forAwait(target=es2018).types similarity index 56% rename from tests/baselines/reference/emitter.forAwait.es2017.types rename to tests/baselines/reference/emitter.forAwait(target=es2018).types index 19642ddd677..406f669ab3a 100644 --- a/tests/baselines/reference/emitter.forAwait.es2017.types +++ b/tests/baselines/reference/emitter.forAwait(target=es2018).types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/emitter/es2017/forAwait/file1.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file1.ts === async function f1() { >f1 : () => Promise @@ -10,7 +10,7 @@ async function f1() { >y : any } } -=== tests/cases/conformance/emitter/es2017/forAwait/file2.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file2.ts === async function f2() { >f2 : () => Promise @@ -23,7 +23,7 @@ async function f2() { >y : any } } -=== tests/cases/conformance/emitter/es2017/forAwait/file3.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file3.ts === async function* f3() { >f3 : () => AsyncGenerator @@ -35,7 +35,7 @@ async function* f3() { >y : any } } -=== tests/cases/conformance/emitter/es2017/forAwait/file4.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file4.ts === async function* f4() { >f4 : () => AsyncGenerator @@ -48,7 +48,7 @@ async function* f4() { >y : any } } -=== tests/cases/conformance/emitter/es2017/forAwait/file5.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file5.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function f5() { >f5 : () => Promise @@ -65,7 +65,7 @@ async function f5() { >outer : any } } -=== tests/cases/conformance/emitter/es2017/forAwait/file6.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file6.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function* f6() { >f6 : () => AsyncGenerator @@ -82,3 +82,18 @@ async function* f6() { >outer : any } } +=== tests/cases/conformance/statements/for-await-ofStatements/file7.ts === +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { +>f7 : () => AsyncGenerator + + let y: any; +>y : any + + for (;;) { + for await (const x of y) { +>x : any +>y : any + } + } +} diff --git a/tests/baselines/reference/emitter.forAwait.es5.js b/tests/baselines/reference/emitter.forAwait(target=es5).js similarity index 83% rename from tests/baselines/reference/emitter.forAwait.es5.js rename to tests/baselines/reference/emitter.forAwait(target=es5).js index f33af25dcc1..5b182d16d5c 100644 --- a/tests/baselines/reference/emitter.forAwait.es5.js +++ b/tests/baselines/reference/emitter.forAwait(target=es5).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/emitter/es5/forAwait/emitter.forAwait.es5.ts] //// +//// [tests/cases/conformance/statements/for-await-ofStatements/emitter.forAwait.ts] //// //// [file1.ts] async function f1() { @@ -40,6 +40,15 @@ async function* f6() { continue outer; } } +//// [file7.ts] +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { + let y: any; + for (;;) { + for await (const x of y) { + } + } +} //// [file1.js] var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { @@ -544,3 +553,90 @@ function f6() { }); }); } +//// [file7.js] +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __asyncValues = (this && this.__asyncValues) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +}; +var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } +var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +}; +// https://github.com/microsoft/TypeScript/issues/36166 +function f7() { + return __asyncGenerator(this, arguments, function f7_1() { + var y, y_1, y_1_1, x, e_1_1; + var e_1, _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + _b.trys.push([0, 5, 6, 11]); + y_1 = (e_1 = void 0, __asyncValues(y)); + _b.label = 1; + case 1: return [4 /*yield*/, __await(y_1.next())]; + case 2: + if (!(y_1_1 = _b.sent(), !y_1_1.done)) return [3 /*break*/, 4]; + x = y_1_1.value; + _b.label = 3; + case 3: return [3 /*break*/, 1]; + case 4: return [3 /*break*/, 11]; + case 5: + e_1_1 = _b.sent(); + e_1 = { error: e_1_1 }; + return [3 /*break*/, 11]; + case 6: + _b.trys.push([6, , 9, 10]); + if (!(y_1_1 && !y_1_1.done && (_a = y_1.return))) return [3 /*break*/, 8]; + return [4 /*yield*/, __await(_a.call(y_1))]; + case 7: + _b.sent(); + _b.label = 8; + case 8: return [3 /*break*/, 10]; + case 9: + if (e_1) throw e_1.error; + return [7 /*endfinally*/]; + case 10: return [7 /*endfinally*/]; + case 11: return [3 /*break*/, 0]; + case 12: return [2 /*return*/]; + } + }); + }); +} diff --git a/tests/baselines/reference/emitter.forAwait.es5.symbols b/tests/baselines/reference/emitter.forAwait(target=es5).symbols similarity index 63% rename from tests/baselines/reference/emitter.forAwait.es5.symbols rename to tests/baselines/reference/emitter.forAwait(target=es5).symbols index 05fb915c0fc..f32170c889a 100644 --- a/tests/baselines/reference/emitter.forAwait.es5.symbols +++ b/tests/baselines/reference/emitter.forAwait(target=es5).symbols @@ -1,4 +1,4 @@ -=== tests/cases/conformance/emitter/es5/forAwait/file1.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file1.ts === async function f1() { >f1 : Symbol(f1, Decl(file1.ts, 0, 0)) @@ -10,7 +10,7 @@ async function f1() { >y : Symbol(y, Decl(file1.ts, 1, 7)) } } -=== tests/cases/conformance/emitter/es5/forAwait/file2.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file2.ts === async function f2() { >f2 : Symbol(f2, Decl(file2.ts, 0, 0)) @@ -23,7 +23,7 @@ async function f2() { >y : Symbol(y, Decl(file2.ts, 1, 15)) } } -=== tests/cases/conformance/emitter/es5/forAwait/file3.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file3.ts === async function* f3() { >f3 : Symbol(f3, Decl(file3.ts, 0, 0)) @@ -35,7 +35,7 @@ async function* f3() { >y : Symbol(y, Decl(file3.ts, 1, 7)) } } -=== tests/cases/conformance/emitter/es5/forAwait/file4.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file4.ts === async function* f4() { >f4 : Symbol(f4, Decl(file4.ts, 0, 0)) @@ -48,7 +48,7 @@ async function* f4() { >y : Symbol(y, Decl(file4.ts, 1, 15)) } } -=== tests/cases/conformance/emitter/es5/forAwait/file5.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file5.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function f5() { >f5 : Symbol(f5, Decl(file5.ts, 0, 0)) @@ -63,7 +63,7 @@ async function f5() { continue outer; } } -=== tests/cases/conformance/emitter/es5/forAwait/file6.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file6.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function* f6() { >f6 : Symbol(f6, Decl(file6.ts, 0, 0)) @@ -78,3 +78,18 @@ async function* f6() { continue outer; } } +=== tests/cases/conformance/statements/for-await-ofStatements/file7.ts === +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { +>f7 : Symbol(f7, Decl(file7.ts, 0, 0)) + + let y: any; +>y : Symbol(y, Decl(file7.ts, 2, 7)) + + for (;;) { + for await (const x of y) { +>x : Symbol(x, Decl(file7.ts, 4, 24)) +>y : Symbol(y, Decl(file7.ts, 2, 7)) + } + } +} diff --git a/tests/baselines/reference/emitter.forAwait.es5.types b/tests/baselines/reference/emitter.forAwait(target=es5).types similarity index 56% rename from tests/baselines/reference/emitter.forAwait.es5.types rename to tests/baselines/reference/emitter.forAwait(target=es5).types index 1452be304b6..406f669ab3a 100644 --- a/tests/baselines/reference/emitter.forAwait.es5.types +++ b/tests/baselines/reference/emitter.forAwait(target=es5).types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/emitter/es5/forAwait/file1.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file1.ts === async function f1() { >f1 : () => Promise @@ -10,7 +10,7 @@ async function f1() { >y : any } } -=== tests/cases/conformance/emitter/es5/forAwait/file2.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file2.ts === async function f2() { >f2 : () => Promise @@ -23,7 +23,7 @@ async function f2() { >y : any } } -=== tests/cases/conformance/emitter/es5/forAwait/file3.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file3.ts === async function* f3() { >f3 : () => AsyncGenerator @@ -35,7 +35,7 @@ async function* f3() { >y : any } } -=== tests/cases/conformance/emitter/es5/forAwait/file4.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file4.ts === async function* f4() { >f4 : () => AsyncGenerator @@ -48,7 +48,7 @@ async function* f4() { >y : any } } -=== tests/cases/conformance/emitter/es5/forAwait/file5.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file5.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function f5() { >f5 : () => Promise @@ -65,7 +65,7 @@ async function f5() { >outer : any } } -=== tests/cases/conformance/emitter/es5/forAwait/file6.ts === +=== tests/cases/conformance/statements/for-await-ofStatements/file6.ts === // https://github.com/Microsoft/TypeScript/issues/21363 async function* f6() { >f6 : () => AsyncGenerator @@ -82,3 +82,18 @@ async function* f6() { >outer : any } } +=== tests/cases/conformance/statements/for-await-ofStatements/file7.ts === +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { +>f7 : () => AsyncGenerator + + let y: any; +>y : any + + for (;;) { + for await (const x of y) { +>x : any +>y : any + } + } +} diff --git a/tests/cases/conformance/emitter/es2015/forAwait/emitter.forAwait.es2015.ts b/tests/cases/conformance/emitter/es2015/forAwait/emitter.forAwait.es2015.ts deleted file mode 100644 index 64b44e901e2..00000000000 --- a/tests/cases/conformance/emitter/es2015/forAwait/emitter.forAwait.es2015.ts +++ /dev/null @@ -1,42 +0,0 @@ -// @target: es2015 -// @lib: esnext -// @filename: file1.ts -async function f1() { - let y: any; - for await (const x of y) { - } -} -// @filename: file2.ts -async function f2() { - let x: any, y: any; - for await (x of y) { - } -} -// @filename: file3.ts -async function* f3() { - let y: any; - for await (const x of y) { - } -} -// @filename: file4.ts -async function* f4() { - let x: any, y: any; - for await (x of y) { - } -} -// @filename: file5.ts -// https://github.com/Microsoft/TypeScript/issues/21363 -async function f5() { - let y: any; - outer: for await (const x of y) { - continue outer; - } -} -// @filename: file6.ts -// https://github.com/Microsoft/TypeScript/issues/21363 -async function* f6() { - let y: any; - outer: for await (const x of y) { - continue outer; - } -} \ No newline at end of file diff --git a/tests/cases/conformance/emitter/es2017/forAwait/emitter.forAwait.es2017.ts b/tests/cases/conformance/emitter/es2017/forAwait/emitter.forAwait.es2017.ts deleted file mode 100644 index f9d9fc3d4d9..00000000000 --- a/tests/cases/conformance/emitter/es2017/forAwait/emitter.forAwait.es2017.ts +++ /dev/null @@ -1,42 +0,0 @@ -// @target: es2017 -// @lib: esnext -// @filename: file1.ts -async function f1() { - let y: any; - for await (const x of y) { - } -} -// @filename: file2.ts -async function f2() { - let x: any, y: any; - for await (x of y) { - } -} -// @filename: file3.ts -async function* f3() { - let y: any; - for await (const x of y) { - } -} -// @filename: file4.ts -async function* f4() { - let x: any, y: any; - for await (x of y) { - } -} -// @filename: file5.ts -// https://github.com/Microsoft/TypeScript/issues/21363 -async function f5() { - let y: any; - outer: for await (const x of y) { - continue outer; - } -} -// @filename: file6.ts -// https://github.com/Microsoft/TypeScript/issues/21363 -async function* f6() { - let y: any; - outer: for await (const x of y) { - continue outer; - } -} \ No newline at end of file diff --git a/tests/cases/conformance/emitter/es5/forAwait/emitter.forAwait.es5.ts b/tests/cases/conformance/emitter/es5/forAwait/emitter.forAwait.es5.ts deleted file mode 100644 index a441b0da2bd..00000000000 --- a/tests/cases/conformance/emitter/es5/forAwait/emitter.forAwait.es5.ts +++ /dev/null @@ -1,42 +0,0 @@ -// @target: es5 -// @lib: esnext -// @filename: file1.ts -async function f1() { - let y: any; - for await (const x of y) { - } -} -// @filename: file2.ts -async function f2() { - let x: any, y: any; - for await (x of y) { - } -} -// @filename: file3.ts -async function* f3() { - let y: any; - for await (const x of y) { - } -} -// @filename: file4.ts -async function* f4() { - let x: any, y: any; - for await (x of y) { - } -} -// @filename: file5.ts -// https://github.com/Microsoft/TypeScript/issues/21363 -async function f5() { - let y: any; - outer: for await (const x of y) { - continue outer; - } -} -// @filename: file6.ts -// https://github.com/Microsoft/TypeScript/issues/21363 -async function* f6() { - let y: any; - outer: for await (const x of y) { - continue outer; - } -} \ No newline at end of file diff --git a/tests/cases/conformance/emitter/es2018/forAwait/emitter.forAwait.es2018.ts b/tests/cases/conformance/statements/for-await-ofStatements/emitter.forAwait.ts similarity index 74% rename from tests/cases/conformance/emitter/es2018/forAwait/emitter.forAwait.es2018.ts rename to tests/cases/conformance/statements/for-await-ofStatements/emitter.forAwait.ts index 02e875fb7e4..f61bc343261 100644 --- a/tests/cases/conformance/emitter/es2018/forAwait/emitter.forAwait.es2018.ts +++ b/tests/cases/conformance/statements/for-await-ofStatements/emitter.forAwait.ts @@ -1,4 +1,4 @@ -// @target: es2018 +// @target: es2018,es2017,es2015,es5 // @lib: esnext // @filename: file1.ts async function f1() { @@ -40,3 +40,12 @@ async function* f6() { continue outer; } } +// @filename: file7.ts +// https://github.com/microsoft/TypeScript/issues/36166 +async function* f7() { + let y: any; + for (;;) { + for await (const x of y) { + } + } +} \ No newline at end of file