do not inline async IIFEs in control flow graph

This commit is contained in:
Vladimir Matveev
2016-10-28 14:43:08 -07:00
parent d54e889cf2
commit 73c59bbf85
5 changed files with 81 additions and 2 deletions

View File

@@ -490,8 +490,8 @@ namespace ts {
const saveReturnTarget = currentReturnTarget;
const saveActiveLabels = activeLabels;
const saveHasExplicitReturn = hasExplicitReturn;
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !!getImmediatelyInvokedFunctionExpression(node);
// An IIFE is considered part of the containing control flow. Return statements behave
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node);
// A non-async IIFE is considered part of the containing control flow. Return statements behave
// similarly to break statements that exit to a label just past the statement body.
if (isIIFE) {
currentReturnTarget = createBranchLabel();

View File

@@ -0,0 +1,28 @@
//// [asyncIIFE.ts]
function f1() {
(async () => {
await 10
throw new Error();
})();
var x = 1;
}
//// [asyncIIFE.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
function f1() {
(() => __awaiter(this, void 0, void 0, function* () {
yield 10;
throw new Error();
}))();
var x = 1;
}

View File

@@ -0,0 +1,16 @@
=== tests/cases/compiler/asyncIIFE.ts ===
function f1() {
>f1 : Symbol(f1, Decl(asyncIIFE.ts, 0, 0))
(async () => {
await 10
throw new Error();
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
})();
var x = 1;
>x : Symbol(x, Decl(asyncIIFE.ts, 7, 7))
}

View File

@@ -0,0 +1,25 @@
=== tests/cases/compiler/asyncIIFE.ts ===
function f1() {
>f1 : () => void
(async () => {
>(async () => { await 10 throw new Error(); })() : Promise<never>
>(async () => { await 10 throw new Error(); }) : () => Promise<never>
>async () => { await 10 throw new Error(); } : () => Promise<never>
await 10
>await 10 : 10
>10 : 10
throw new Error();
>new Error() : Error
>Error : ErrorConstructor
})();
var x = 1;
>x : number
>1 : 1
}

View File

@@ -0,0 +1,10 @@
// @target: ES6
function f1() {
(async () => {
await 10
throw new Error();
})();
var x = 1;
}