Skip to content

Commit 9bb7ba5

Browse files
authored
Merge pull request microsoft#11928 from Microsoft/vladima/11738
do not inline async IIFEs in control flow graph
2 parents 3f16f37 + 73c59bb commit 9bb7ba5

5 files changed

Lines changed: 81 additions & 2 deletions

File tree

src/compiler/binder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,8 @@ namespace ts {
499499
const saveReturnTarget = currentReturnTarget;
500500
const saveActiveLabels = activeLabels;
501501
const saveHasExplicitReturn = hasExplicitReturn;
502-
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !!getImmediatelyInvokedFunctionExpression(node);
503-
// An IIFE is considered part of the containing control flow. Return statements behave
502+
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node);
503+
// A non-async IIFE is considered part of the containing control flow. Return statements behave
504504
// similarly to break statements that exit to a label just past the statement body.
505505
if (isIIFE) {
506506
currentReturnTarget = createBranchLabel();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [asyncIIFE.ts]
2+
3+
function f1() {
4+
(async () => {
5+
await 10
6+
throw new Error();
7+
})();
8+
9+
var x = 1;
10+
}
11+
12+
13+
//// [asyncIIFE.js]
14+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15+
return new (P || (P = Promise))(function (resolve, reject) {
16+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18+
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
19+
step((generator = generator.apply(thisArg, _arguments)).next());
20+
});
21+
};
22+
function f1() {
23+
(() => __awaiter(this, void 0, void 0, function* () {
24+
yield 10;
25+
throw new Error();
26+
}))();
27+
var x = 1;
28+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/asyncIIFE.ts ===
2+
3+
function f1() {
4+
>f1 : Symbol(f1, Decl(asyncIIFE.ts, 0, 0))
5+
6+
(async () => {
7+
await 10
8+
throw new Error();
9+
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
10+
11+
})();
12+
13+
var x = 1;
14+
>x : Symbol(x, Decl(asyncIIFE.ts, 7, 7))
15+
}
16+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=== tests/cases/compiler/asyncIIFE.ts ===
2+
3+
function f1() {
4+
>f1 : () => void
5+
6+
(async () => {
7+
>(async () => { await 10 throw new Error(); })() : Promise<never>
8+
>(async () => { await 10 throw new Error(); }) : () => Promise<never>
9+
>async () => { await 10 throw new Error(); } : () => Promise<never>
10+
11+
await 10
12+
>await 10 : 10
13+
>10 : 10
14+
15+
throw new Error();
16+
>new Error() : Error
17+
>Error : ErrorConstructor
18+
19+
})();
20+
21+
var x = 1;
22+
>x : number
23+
>1 : 1
24+
}
25+

tests/cases/compiler/asyncIIFE.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// @target: ES6
2+
3+
function f1() {
4+
(async () => {
5+
await 10
6+
throw new Error();
7+
})();
8+
9+
var x = 1;
10+
}

0 commit comments

Comments
 (0)