diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6ef6912d650ab..14e743cf59f76 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -71,43 +71,92 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); };`; + // The __generator helper is used by down-level transformations to emulate the runtime + // semantics of an ES2015 generator function. When called, this helper returns an + // object that implements the Iterator protocol, in that it has `next`, `return`, and + // `throw` methods that step through the generator when invoked. + // + // parameters: + // thisArg The value to use as the `this` binding for the transformed generator body. + // body A function that acts as the transformed generator body. + // + // variables: + // _ Persistent state for the generator that is shared between the helper and the + // generator body. The state object has the following members: + // sent() - A method that returns or throws the current completion value. + // label - The next point at which to resume evaluation of the generator body. + // trys - A stack of protected regions (try/catch/finally blocks). + // ops - A stack of pending instructions when inside of a finally block. + // f A value indicating whether the generator is executing. + // y An iterator to delegate for a yield*. + // t A temporary variable that holds one of the following values (note that these + // cases do not overlap): + // - The completion value when resuming from a `yield` or `yield*`. + // - The error value for a catch block. + // - The current protected region (array of try/catch/finally/end labels). + // - The verb (`next`, `throw`, or `return` method) to delegate to the expression + // of a `yield*`. + // - The result of evaluating the verb delegated to the expression of a `yield*`. + // + // functions: + // verb(n) Creates a bound callback to the `step` function for opcode `n`. + // step(op) Evaluates opcodes in a generator body until execution is suspended or + // completed. + // + // The __generator helper understands a limited set of instructions: + // 0: next(value?) - Start or resume the generator with the specified value. + // 1: throw(error) - Resume the generator with an exception. If the generator is + // suspended inside of one or more protected regions, evaluates + // any intervening finally blocks between the current label and + // the nearest catch block or function boundary. If uncaught, the + // exception is thrown to the caller. + // 2: return(value?) - Resume the generator as if with a return. If the generator is + // suspended inside of one or more protected regions, evaluates any + // intervening finally blocks. + // 3: break(label) - Jump to the specified label. If the label is outside of the + // current protected region, evaluates any intervening finally + // blocks. + // 4: yield(value?) - Yield execution to the caller with an optional value. When + // resumed, the generator will continue at the next label. + // 5: yield*(value) - Delegates evaluation to the supplied iterator. When + // delegation completes, the generator will continue at the next + // label. + // 6: catch(error) - Handles an exception thrown from within the generator body. If + // the current label is inside of one or more protected regions, + // evaluates any intervening finally blocks between the current + // label and the nearest catch block or function boundary. If + // uncaught, the exception is thrown to the caller. + // 7: endfinally - Ends a finally block, resuming the last instruction prior to + // entering a finally block. + // + // For examples of how these are used, see the comments in ./transformers/generators.ts const generatorHelper = ` var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (1) { - if (_.done) switch (op[0]) { - case 0: return { value: void 0, done: true }; - case 1: case 6: throw op[1]; - case 2: return { value: op[1], done: true }; - } - try { - switch (f = 1, op[0]) { - case 0: case 1: sent = op; break; - case 4: return _.label++, { value: op[1], done: false }; - case 7: op = _.stack.pop(), _.trys.pop(); continue; - default: - var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; - if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } - if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } - if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } - if (r[2]) { _.stack.pop(); } - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } - catch (e) { op = [6, e]; } - finally { f = 0, sent = void 0; } - } + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, 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 }; } - return { - next: function (v) { return step([0, v]); }, - "throw": function (v) { return step([1, v]); }, - "return": function (v) { return step([2, v]); } - }; };`; // emit output for the __export helper function diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 9cb759027e6f3..44deac04279c6 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -2055,9 +2055,24 @@ namespace ts { if (!isBlock(loopBody)) { loopBody = createBlock([loopBody], /*location*/ undefined, /*multiline*/ true); } + + const isAsyncBlockContainingAwait = + containingNonArrowFunction + && (containingNonArrowFunction.emitFlags & NodeEmitFlags.AsyncFunctionBody) !== 0 + && (node.statement.transformFlags & TransformFlags.ContainsYield) !== 0; + + let loopBodyFlags: NodeEmitFlags = 0; + if (currentState.containsLexicalThis) { + loopBodyFlags |= NodeEmitFlags.CapturesThis; + } + + if (isAsyncBlockContainingAwait) { + loopBodyFlags |= NodeEmitFlags.AsyncFunctionBody; + } + const convertedLoopVariable = createVariableStatement( - /*modifiers*/ undefined, + /*modifiers*/ undefined, createVariableDeclarationList( [ createVariableDeclaration( @@ -2065,16 +2080,14 @@ namespace ts { /*type*/ undefined, setNodeEmitFlags( createFunctionExpression( - /*asteriskToken*/ undefined, + isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined, /*name*/ undefined, /*typeParameters*/ undefined, loopParameters, /*type*/ undefined, loopBody ), - currentState.containsLexicalThis - ? NodeEmitFlags.CapturesThis - : 0 + loopBodyFlags ) ) ] @@ -2160,7 +2173,7 @@ namespace ts { )); } - const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState); + const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, isAsyncBlockContainingAwait); let loop: IterationStatement; if (convert) { loop = convert(node, convertedLoopBodyStatements); @@ -2173,12 +2186,17 @@ namespace ts { loop = visitEachChild(loop, visitor, context); // set loop statement loop.statement = createBlock( - generateCallToConvertedLoop(functionName, loopParameters, currentState), + convertedLoopBodyStatements, /*location*/ undefined, /*multiline*/ true ); + + // reset and re-aggregate the transform flags + loop.transformFlags = 0; + aggregateTransformFlags(loop); } + statements.push( currentParent.kind === SyntaxKind.LabeledStatement ? createLabel((currentParent).label, loop) @@ -2199,7 +2217,7 @@ namespace ts { } } - function generateCallToConvertedLoop(loopFunctionExpressionName: Identifier, parameters: ParameterDeclaration[], state: ConvertedLoopState): Statement[] { + function generateCallToConvertedLoop(loopFunctionExpressionName: Identifier, parameters: ParameterDeclaration[], state: ConvertedLoopState, isAsyncBlockContainingAwait: boolean): Statement[] { const outerConvertedLoopState = convertedLoopState; const statements: Statement[] = []; @@ -2212,8 +2230,9 @@ namespace ts { !state.labeledNonLocalContinues; const call = createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(parameters, p => p.name)); + const callResult = isAsyncBlockContainingAwait ? createYield(createToken(SyntaxKind.AsteriskToken), call) : call; if (isSimpleLoop) { - statements.push(createStatement(call)); + statements.push(createStatement(callResult)); copyOutParameters(state.loopOutParameters, CopyDirection.ToOriginal, statements); } else { @@ -2221,7 +2240,7 @@ namespace ts { const stateVariable = createVariableStatement( /*modifiers*/ undefined, createVariableDeclarationList( - [createVariableDeclaration(loopResultName, /*type*/ undefined, call)] + [createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)] ) ); statements.push(stateVariable); diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 9a4b567cb8017..76ecdac26f942 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -21,10 +21,11 @@ // .brfalse LABEL, (x) - Jump to a label IIF the expression `x` is falsey. // If jumping out of a protected region, all .finally // blocks are executed. -// .yield RESUME, (x) - Yield the value of the optional expression `x`. -// Resume at the label RESUME. -// .yieldstar RESUME, (x) - Delegate yield to the value of the optional -// expression `x`. Resume at the label RESUME. +// .yield (x) - Yield the value of the optional expression `x`. +// Resume at the next label. +// .yieldstar (x) - Delegate yield to the value of the optional +// expression `x`. Resume at the next label. +// NOTE: `x` must be an Iterator, not an Iterable. // .loop CONTINUE, BREAK - Marks the beginning of a loop. Any "continue" or // "break" abrupt completions jump to the CONTINUE or // BREAK labels, respectively. @@ -80,13 +81,13 @@ // -------------------------------|---------------------------------------------- // .brfalse LABEL, (x) | if (!(x)) return [3, /*break*/, LABEL]; // -------------------------------|---------------------------------------------- -// .yield RESUME, (x) | return [4 /*yield*/, x]; +// .yield (x) | return [4 /*yield*/, x]; // .mark RESUME | case RESUME: -// a = %sent%; | a = state.sent(); +// a = %sent%; | a = state.sent(); // -------------------------------|---------------------------------------------- -// .yieldstar RESUME, (X) | return [5 /*yield**/, x]; +// .yieldstar (x) | return [5 /*yield**/, x]; // .mark RESUME | case RESUME: -// a = %sent%; | a = state.sent(); +// a = %sent%; | a = state.sent(); // -------------------------------|---------------------------------------------- // .with (_a) | with (_a) { // a(); | a(); @@ -109,7 +110,7 @@ // .br END | return [3 /*break*/, END]; // .catch (e) | // .mark CATCH | case CATCH: -// | e = state.error; +// | e = state.sent(); // b(); | b(); // .br END | return [3 /*break*/, END]; // .finally | @@ -906,7 +907,7 @@ namespace ts { * * @param node The node to visit. */ - function visitYieldExpression(node: YieldExpression) { + function visitYieldExpression(node: YieldExpression): LeftHandSideExpression { // [source] // x = yield a(); // @@ -917,7 +918,14 @@ namespace ts { // NOTE: we are explicitly not handling YieldStar at this time. const resumeLabel = defineLabel(); - emitYield(visitNode(node.expression, visitor, isExpression), /*location*/ node); + const expression = visitNode(node.expression, visitor, isExpression); + if (node.asteriskToken) { + emitYieldStar(expression, /*location*/ node); + } + else { + emitYield(expression, /*location*/ node); + } + markLabel(resumeLabel); return createGeneratorResume(); } @@ -2480,6 +2488,16 @@ namespace ts { emitWorker(OpCode.BreakWhenFalse, [label, condition], location); } + /** + * Emits a YieldStar operation for the provided expression. + * + * @param expression An optional value for the yield operation. + * @param location An optional source map location for the assignment. + */ + function emitYieldStar(expression?: Expression, location?: TextRange): void { + emitWorker(OpCode.YieldStar, [expression], location); + } + /** * Emits a Yield operation for the provided expression. * diff --git a/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js b/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js index 95416f3aaa278..7eb2157c02663 100644 --- a/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js +++ b/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js @@ -50,41 +50,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (1) { - if (_.done) switch (op[0]) { - case 0: return { value: void 0, done: true }; - case 1: case 6: throw op[1]; - case 2: return { value: op[1], done: true }; + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, 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; } - try { - switch (f = 1, op[0]) { - case 0: case 1: sent = op; break; - case 4: return _.label++, { value: op[1], done: false }; - case 7: op = _.stack.pop(), _.trys.pop(); continue; - default: - var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; - if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } - if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } - if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } - if (r[2]) { _.stack.pop(); } - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } - catch (e) { op = [6, e]; } - finally { f = 0, sent = void 0; } - } + 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 }; } - return { - next: function (v) { return step([0, v]); }, - "throw": function (v) { return step([1, v]); }, - "return": function (v) { return step([2, v]); } - }; }; var _this = this; function f0() { diff --git a/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.js b/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.js new file mode 100644 index 0000000000000..49566904ae1a4 --- /dev/null +++ b/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.js @@ -0,0 +1,182 @@ +//// [asyncAwaitWithCapturedBlockScopeVar.ts] +async function fn1() { + let ar = []; + for (let i = 0; i < 1; i++) { + await 1; + ar.push(() => i); + } +} + +async function fn2() { + let ar = []; + for (let i = 0; i < 1; i++) { + await 1; + ar.push(() => i); + break; + } +} + +async function fn3() { + let ar = []; + for (let i = 0; i < 1; i++) { + await 1; + ar.push(() => i); + continue; + } +} + +async function fn4(): Promise { + let ar = []; + for (let i = 0; i < 1; i++) { + await 1; + ar.push(() => i); + return 1; + } +} + + +//// [asyncAwaitWithCapturedBlockScopeVar.js] +function fn1() { + return __awaiter(this, void 0, void 0, function () { + var ar, _loop_1, i; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + ar = []; + _loop_1 = function (i) { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, 1]; + case 1: + _a.sent(); + ar.push(function () { return i; }); + return [2 /*return*/]; + } + }); + }; + i = 0; + _a.label = 1; + case 1: + if (!(i < 1)) + return [3 /*break*/, 4]; + return [5 /*yield**/, _loop_1(i)]; + case 2: + _a.sent(); + _a.label = 3; + case 3: + i++; + return [3 /*break*/, 1]; + case 4: return [2 /*return*/]; + } + }); + }); +} +function fn2() { + return __awaiter(this, void 0, void 0, function () { + var ar, _loop_2, i, state_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + ar = []; + _loop_2 = function (i) { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, 1]; + case 1: + _a.sent(); + ar.push(function () { return i; }); + return [2 /*return*/, "break"]; + } + }); + }; + i = 0; + _a.label = 1; + case 1: + if (!(i < 1)) + return [3 /*break*/, 4]; + return [5 /*yield**/, _loop_2(i)]; + case 2: + state_1 = _a.sent(); + if (state_1 === "break") + return [3 /*break*/, 4]; + _a.label = 3; + case 3: + i++; + return [3 /*break*/, 1]; + case 4: return [2 /*return*/]; + } + }); + }); +} +function fn3() { + return __awaiter(this, void 0, void 0, function () { + var ar, _loop_3, i; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + ar = []; + _loop_3 = function (i) { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, 1]; + case 1: + _a.sent(); + ar.push(function () { return i; }); + return [2 /*return*/, "continue"]; + } + }); + }; + i = 0; + _a.label = 1; + case 1: + if (!(i < 1)) + return [3 /*break*/, 4]; + return [5 /*yield**/, _loop_3(i)]; + case 2: + _a.sent(); + _a.label = 3; + case 3: + i++; + return [3 /*break*/, 1]; + case 4: return [2 /*return*/]; + } + }); + }); +} +function fn4() { + return __awaiter(this, void 0, void 0, function () { + var ar, _loop_4, i, state_2; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + ar = []; + _loop_4 = function (i) { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, 1]; + case 1: + _a.sent(); + ar.push(function () { return i; }); + return [2 /*return*/, { value: 1 }]; + } + }); + }; + i = 0; + _a.label = 1; + case 1: + if (!(i < 1)) + return [3 /*break*/, 4]; + return [5 /*yield**/, _loop_4(i)]; + case 2: + state_2 = _a.sent(); + if (typeof state_2 === "object") + return [2 /*return*/, state_2.value]; + _a.label = 3; + case 3: + i++; + return [3 /*break*/, 1]; + case 4: return [2 /*return*/]; + } + }); + }); +} diff --git a/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.symbols b/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.symbols new file mode 100644 index 0000000000000..12a60509f4f83 --- /dev/null +++ b/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.symbols @@ -0,0 +1,88 @@ +=== tests/cases/compiler/asyncAwaitWithCapturedBlockScopeVar.ts === +async function fn1() { +>fn1 : Symbol(fn1, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 0, 0)) + + let ar = []; +>ar : Symbol(ar, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 1, 7)) + + for (let i = 0; i < 1; i++) { +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 2, 12)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 2, 12)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 2, 12)) + + await 1; + ar.push(() => i); +>ar.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>ar : Symbol(ar, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 1, 7)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 2, 12)) + } +} + +async function fn2() { +>fn2 : Symbol(fn2, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 6, 1)) + + let ar = []; +>ar : Symbol(ar, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 9, 7)) + + for (let i = 0; i < 1; i++) { +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 10, 12)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 10, 12)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 10, 12)) + + await 1; + ar.push(() => i); +>ar.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>ar : Symbol(ar, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 9, 7)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 10, 12)) + + break; + } +} + +async function fn3() { +>fn3 : Symbol(fn3, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 15, 1)) + + let ar = []; +>ar : Symbol(ar, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 18, 7)) + + for (let i = 0; i < 1; i++) { +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 19, 12)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 19, 12)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 19, 12)) + + await 1; + ar.push(() => i); +>ar.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>ar : Symbol(ar, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 18, 7)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 19, 12)) + + continue; + } +} + +async function fn4(): Promise { +>fn4 : Symbol(fn4, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 24, 1)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + let ar = []; +>ar : Symbol(ar, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 27, 7)) + + for (let i = 0; i < 1; i++) { +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 28, 12)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 28, 12)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 28, 12)) + + await 1; + ar.push(() => i); +>ar.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>ar : Symbol(ar, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 27, 7)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>i : Symbol(i, Decl(asyncAwaitWithCapturedBlockScopeVar.ts, 28, 12)) + + return 1; + } +} + diff --git a/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.types b/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.types new file mode 100644 index 0000000000000..424959ddb22be --- /dev/null +++ b/tests/baselines/reference/asyncAwaitWithCapturedBlockScopeVar.types @@ -0,0 +1,129 @@ +=== tests/cases/compiler/asyncAwaitWithCapturedBlockScopeVar.ts === +async function fn1() { +>fn1 : () => Promise + + let ar = []; +>ar : any[] +>[] : undefined[] + + for (let i = 0; i < 1; i++) { +>i : number +>0 : 0 +>i < 1 : boolean +>i : number +>1 : 1 +>i++ : number +>i : number + + await 1; +>await 1 : 1 +>1 : 1 + + ar.push(() => i); +>ar.push(() => i) : number +>ar.push : (...items: any[]) => number +>ar : any[] +>push : (...items: any[]) => number +>() => i : () => number +>i : number + } +} + +async function fn2() { +>fn2 : () => Promise + + let ar = []; +>ar : any[] +>[] : undefined[] + + for (let i = 0; i < 1; i++) { +>i : number +>0 : 0 +>i < 1 : boolean +>i : number +>1 : 1 +>i++ : number +>i : number + + await 1; +>await 1 : 1 +>1 : 1 + + ar.push(() => i); +>ar.push(() => i) : number +>ar.push : (...items: any[]) => number +>ar : any[] +>push : (...items: any[]) => number +>() => i : () => number +>i : number + + break; + } +} + +async function fn3() { +>fn3 : () => Promise + + let ar = []; +>ar : any[] +>[] : undefined[] + + for (let i = 0; i < 1; i++) { +>i : number +>0 : 0 +>i < 1 : boolean +>i : number +>1 : 1 +>i++ : number +>i : number + + await 1; +>await 1 : 1 +>1 : 1 + + ar.push(() => i); +>ar.push(() => i) : number +>ar.push : (...items: any[]) => number +>ar : any[] +>push : (...items: any[]) => number +>() => i : () => number +>i : number + + continue; + } +} + +async function fn4(): Promise { +>fn4 : () => Promise +>Promise : Promise + + let ar = []; +>ar : any[] +>[] : undefined[] + + for (let i = 0; i < 1; i++) { +>i : number +>0 : 0 +>i < 1 : boolean +>i : number +>1 : 1 +>i++ : number +>i : number + + await 1; +>await 1 : 1 +>1 : 1 + + ar.push(() => i); +>ar.push(() => i) : number +>ar.push : (...items: any[]) => number +>ar : any[] +>push : (...items: any[]) => number +>() => i : () => number +>i : number + + return 1; +>1 : 1 + } +} + diff --git a/tests/baselines/reference/asyncAwait_es5.js b/tests/baselines/reference/asyncAwait_es5.js index e148de70ad271..67f7d000351f9 100644 --- a/tests/baselines/reference/asyncAwait_es5.js +++ b/tests/baselines/reference/asyncAwait_es5.js @@ -49,41 +49,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (1) { - if (_.done) switch (op[0]) { - case 0: return { value: void 0, done: true }; - case 1: case 6: throw op[1]; - case 2: return { value: op[1], done: true }; + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, 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; } - try { - switch (f = 1, op[0]) { - case 0: case 1: sent = op; break; - case 4: return _.label++, { value: op[1], done: false }; - case 7: op = _.stack.pop(), _.trys.pop(); continue; - default: - var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; - if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } - if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } - if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } - if (r[2]) { _.stack.pop(); } - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } - catch (e) { op = [6, e]; } - finally { f = 0, sent = void 0; } - } + 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 }; } - return { - next: function (v) { return step([0, v]); }, - "throw": function (v) { return step([1, v]); }, - "return": function (v) { return step([2, v]); } - }; }; var _this = this; function f0() { diff --git a/tests/baselines/reference/asyncFunctionNoReturnType.js b/tests/baselines/reference/asyncFunctionNoReturnType.js index a3635b85a094e..fc7b0b52f1c2e 100644 --- a/tests/baselines/reference/asyncFunctionNoReturnType.js +++ b/tests/baselines/reference/asyncFunctionNoReturnType.js @@ -15,41 +15,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (1) { - if (_.done) switch (op[0]) { - case 0: return { value: void 0, done: true }; - case 1: case 6: throw op[1]; - case 2: return { value: op[1], done: true }; + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, 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; } - try { - switch (f = 1, op[0]) { - case 0: case 1: sent = op; break; - case 4: return _.label++, { value: op[1], done: false }; - case 7: op = _.stack.pop(), _.trys.pop(); continue; - default: - var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; - if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } - if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } - if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } - if (r[2]) { _.stack.pop(); } - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } - catch (e) { op = [6, e]; } - finally { f = 0, sent = void 0; } - } + 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 }; } - return { - next: function (v) { return step([0, v]); }, - "throw": function (v) { return step([1, v]); }, - "return": function (v) { return step([2, v]); } - }; }; var _this = this; (function () { return __awaiter(_this, void 0, void 0, function () { diff --git a/tests/baselines/reference/asyncImportedPromise_es5.js b/tests/baselines/reference/asyncImportedPromise_es5.js index 54d1b0fdac824..0e6e8d515014d 100644 --- a/tests/baselines/reference/asyncImportedPromise_es5.js +++ b/tests/baselines/reference/asyncImportedPromise_es5.js @@ -35,41 +35,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (1) { - if (_.done) switch (op[0]) { - case 0: return { value: void 0, done: true }; - case 1: case 6: throw op[1]; - case 2: return { value: op[1], done: true }; + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, 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; } - try { - switch (f = 1, op[0]) { - case 0: case 1: sent = op; break; - case 4: return _.label++, { value: op[1], done: false }; - case 7: op = _.stack.pop(), _.trys.pop(); continue; - default: - var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; - if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } - if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } - if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } - if (r[2]) { _.stack.pop(); } - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } - catch (e) { op = [6, e]; } - finally { f = 0, sent = void 0; } - } + 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 }; } - return { - next: function (v) { return step([0, v]); }, - "throw": function (v) { return step([1, v]); }, - "return": function (v) { return step([2, v]); } - }; }; var task_1 = require("./task"); var Test = (function () { diff --git a/tests/baselines/reference/asyncMultiFile_es5.js b/tests/baselines/reference/asyncMultiFile_es5.js index 197127c5f1024..cfc3cb235b0cd 100644 --- a/tests/baselines/reference/asyncMultiFile_es5.js +++ b/tests/baselines/reference/asyncMultiFile_es5.js @@ -15,41 +15,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (1) { - if (_.done) switch (op[0]) { - case 0: return { value: void 0, done: true }; - case 1: case 6: throw op[1]; - case 2: return { value: op[1], done: true }; + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, 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; } - try { - switch (f = 1, op[0]) { - case 0: case 1: sent = op; break; - case 4: return _.label++, { value: op[1], done: false }; - case 7: op = _.stack.pop(), _.trys.pop(); continue; - default: - var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; - if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } - if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } - if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } - if (r[2]) { _.stack.pop(); } - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } - catch (e) { op = [6, e]; } - finally { f = 0, sent = void 0; } - } + 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 }; } - return { - next: function (v) { return step([0, v]); }, - "throw": function (v) { return step([1, v]); }, - "return": function (v) { return step([2, v]); } - }; }; function f() { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { diff --git a/tests/baselines/reference/es5-asyncFunction.js b/tests/baselines/reference/es5-asyncFunction.js index 9cb6f1d367443..d6cd770e45463 100644 --- a/tests/baselines/reference/es5-asyncFunction.js +++ b/tests/baselines/reference/es5-asyncFunction.js @@ -18,41 +18,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (1) { - if (_.done) switch (op[0]) { - case 0: return { value: void 0, done: true }; - case 1: case 6: throw op[1]; - case 2: return { value: op[1], done: true }; + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, 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; } - try { - switch (f = 1, op[0]) { - case 0: case 1: sent = op; break; - case 4: return _.label++, { value: op[1], done: false }; - case 7: op = _.stack.pop(), _.trys.pop(); continue; - default: - var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; - if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } - if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } - if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } - if (r[2]) { _.stack.pop(); } - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } - catch (e) { op = [6, e]; } - finally { f = 0, sent = void 0; } - } + 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 }; } - return { - next: function (v) { return step([0, v]); }, - "throw": function (v) { return step([1, v]); }, - "return": function (v) { return step([2, v]); } - }; }; function empty() { return __awaiter(this, void 0, void 0, function () { diff --git a/tests/baselines/reference/es5-importHelpersAsyncFunctions.js b/tests/baselines/reference/es5-importHelpersAsyncFunctions.js index 0fcd8897018ff..6c9a16b546f38 100644 --- a/tests/baselines/reference/es5-importHelpersAsyncFunctions.js +++ b/tests/baselines/reference/es5-importHelpersAsyncFunctions.js @@ -38,41 +38,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (1) { - if (_.done) switch (op[0]) { - case 0: return { value: void 0, done: true }; - case 1: case 6: throw op[1]; - case 2: return { value: op[1], done: true }; + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, 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; } - try { - switch (f = 1, op[0]) { - case 0: case 1: sent = op; break; - case 4: return _.label++, { value: op[1], done: false }; - case 7: op = _.stack.pop(), _.trys.pop(); continue; - default: - var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; - if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } - if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } - if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } - if (r[2]) { _.stack.pop(); } - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } - catch (e) { op = [6, e]; } - finally { f = 0, sent = void 0; } - } + 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 }; } - return { - next: function (v) { return step([0, v]); }, - "throw": function (v) { return step([1, v]); }, - "return": function (v) { return step([2, v]); } - }; }; function foo() { return __awaiter(this, void 0, void 0, function () { diff --git a/tests/cases/compiler/asyncAwaitWithCapturedBlockScopeVar.ts b/tests/cases/compiler/asyncAwaitWithCapturedBlockScopeVar.ts new file mode 100644 index 0000000000000..6db92f0273d57 --- /dev/null +++ b/tests/cases/compiler/asyncAwaitWithCapturedBlockScopeVar.ts @@ -0,0 +1,37 @@ +// @target: es5 +// @lib: es6 +// @noEmitHelpers: true +async function fn1() { + let ar = []; + for (let i = 0; i < 1; i++) { + await 1; + ar.push(() => i); + } +} + +async function fn2() { + let ar = []; + for (let i = 0; i < 1; i++) { + await 1; + ar.push(() => i); + break; + } +} + +async function fn3() { + let ar = []; + for (let i = 0; i < 1; i++) { + await 1; + ar.push(() => i); + continue; + } +} + +async function fn4(): Promise { + let ar = []; + for (let i = 0; i < 1; i++) { + await 1; + ar.push(() => i); + return 1; + } +}