Skip to content

Commit 5b32903

Browse files
committed
Fix async function emit for lexical arguments
1 parent eb03ae8 commit 5b32903

32 files changed

+122
-113
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5765,6 +5765,7 @@ namespace ts {
57655765

57665766
if (node.parserContextFlags & ParserContextFlags.Await) {
57675767
getNodeLinks(container).flags |= NodeCheckFlags.CaptureArguments;
5768+
getNodeLinks(node).flags |= NodeCheckFlags.LexicalArguments;
57685769
}
57695770
}
57705771

src/compiler/emitter.ts

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
4949
};`;
5050

5151
const awaiterHelper = `
52-
var __awaiter = (this && this.__awaiter) || function (args, generator) {
53-
var PromiseConstructor = args[1] || Promise;
54-
return new PromiseConstructor(function (resolve, reject) {
55-
generator = generator.call(args[0], args[2]);
56-
function cast(value) { return value instanceof PromiseConstructor ? value : new PromiseConstructor(function (resolve) { resolve(value); }); }
52+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
53+
return new Promise(function (resolve, reject) {
54+
generator = generator.call(thisArg, _arguments);
55+
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
5756
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
5857
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
5958
function step(verb, value) {
@@ -1239,6 +1238,11 @@ var __awaiter = (this && this.__awaiter) || function (args, generator) {
12391238
}
12401239

12411240
function emitExpressionIdentifier(node: Identifier) {
1241+
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LexicalArguments) {
1242+
write("_arguments");
1243+
return;
1244+
}
1245+
12421246
let container = resolver.getReferencedExportContainer(node);
12431247
if (container) {
12441248
if (container.kind === SyntaxKind.SourceFile) {
@@ -3374,17 +3378,17 @@ var __awaiter = (this && this.__awaiter) || function (args, generator) {
33743378
// let a = async (b) => { await b; }
33753379
//
33763380
// // output
3377-
// let a = (b) => __awaiter([this], function* (b) {
3381+
// let a = (b) => __awaiter(this, void 0, void 0, function* () {
33783382
// yield b;
3379-
// }, this);
3383+
// });
33803384
//
33813385
// The emit for an async arrow with a lexical `arguments` binding might be:
33823386
//
33833387
// // input
33843388
// let a = async (b) => { await arguments[0]; }
33853389
//
33863390
// // output
3387-
// let a = (b) => __awaiter([this, arguments], function* (arguments) {
3391+
// let a = (b) => __awaiter(this, arguments, void 0, function* (arguments) {
33883392
// yield arguments[0];
33893393
// });
33903394
//
@@ -3398,9 +3402,9 @@ var __awaiter = (this && this.__awaiter) || function (args, generator) {
33983402
//
33993403
// // output
34003404
// let a = function (b) {
3401-
// return __awaiter([this], function* () {
3405+
// return __awaiter(this, void 0, void 0, function* () {
34023406
// yield b;
3403-
// }, this);
3407+
// });
34043408
// }
34053409
//
34063410
// The emit for an async function expression with a lexical `arguments` binding
@@ -3413,8 +3417,8 @@ var __awaiter = (this && this.__awaiter) || function (args, generator) {
34133417
//
34143418
// // output
34153419
// let a = function (b) {
3416-
// return __awaiter([this, arguments], function* (arguments) {
3417-
// yield arguments[0];
3420+
// return __awaiter(this, arguments, void 0, function* (_arguments) {
3421+
// yield _arguments[0];
34183422
// });
34193423
// }
34203424
//
@@ -3428,8 +3432,8 @@ var __awaiter = (this && this.__awaiter) || function (args, generator) {
34283432
//
34293433
// // output
34303434
// let a = function (b) {
3431-
// return __awaiter([this, arguments, MyPromise], function* (arguments) {
3432-
// yield arguments[0];
3435+
// return __awaiter(this, arguments, MyPromise, function* (_arguments) {
3436+
// yield _arguments[0];
34333437
// });
34343438
// }
34353439
//
@@ -3443,23 +3447,28 @@ var __awaiter = (this && this.__awaiter) || function (args, generator) {
34433447
write("return");
34443448
}
34453449

3446-
write(" __awaiter([this");
3447-
if (promiseConstructor || hasLexicalArguments) {
3450+
write(" __awaiter(this");
3451+
if (hasLexicalArguments) {
3452+
write(", arguments");
3453+
}
3454+
else {
3455+
write(", void 0");
3456+
}
3457+
3458+
if (promiseConstructor) {
34483459
write(", ");
3449-
if (promiseConstructor) {
3450-
emitNodeWithoutSourceMap(promiseConstructor);
3451-
}
3452-
if (hasLexicalArguments) {
3453-
write(", arguments");
3454-
}
3460+
emitNodeWithoutSourceMap(promiseConstructor);
3461+
}
3462+
else {
3463+
write(", Promise");
34553464
}
34563465

34573466
// Emit the call to __awaiter.
34583467
if (hasLexicalArguments) {
3459-
write("], function* (arguments)");
3468+
write(", function* (_arguments)");
34603469
}
34613470
else {
3462-
write("], function* ()");
3471+
write(", function* ()");
34633472
}
34643473

34653474
// Emit the signature and body for the inner generator function.

src/compiler/types.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,12 +1595,13 @@ namespace ts {
15951595
SuperInstance = 0x00000100, // Instance 'super' reference
15961596
SuperStatic = 0x00000200, // Static 'super' reference
15971597
ContextChecked = 0x00000400, // Contextual types have been assigned
1598-
CaptureArguments = 0x00000800, // Lexical 'arguments' used in body (for async functions)
1598+
LexicalArguments = 0x00000800,
1599+
CaptureArguments = 0x00001000, // Lexical 'arguments' used in body (for async functions)
15991600

16001601
// Values for enum members have been computed, and any errors have been reported for them.
1601-
EnumValuesComputed = 0x00001000,
1602-
BlockScopedBindingInLoop = 0x00002000,
1603-
LexicalModuleMergesWithClass= 0x00004000, // Instantiated lexical module declaration is merged with a previous class declaration.
1602+
EnumValuesComputed = 0x00002000,
1603+
BlockScopedBindingInLoop = 0x00004000,
1604+
LexicalModuleMergesWithClass= 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
16041605
}
16051606

16061607
/* @internal */

tests/baselines/reference/asyncArrowFunction1_es6.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ var foo = async (): Promise<void> => {
44
};
55

66
//// [asyncArrowFunction1_es6.js]
7-
var foo = () => __awaiter([this, Promise], function* () {
7+
var foo = () => __awaiter(this, void 0, Promise, function* () {
88
});

tests/baselines/reference/asyncArrowFunction6_es6.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ var foo = async (a = await): Promise<void> => {
44
}
55

66
//// [asyncArrowFunction6_es6.js]
7-
var foo = (a = yield ) => __awaiter([this, Promise], function* () {
7+
var foo = (a = yield ) => __awaiter(this, void 0, Promise, function* () {
88
});

tests/baselines/reference/asyncArrowFunction7_es6.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ var bar = async (): Promise<void> => {
77
}
88

99
//// [asyncArrowFunction7_es6.js]
10-
var bar = () => __awaiter([this, Promise], function* () {
10+
var bar = () => __awaiter(this, void 0, Promise, function* () {
1111
// 'await' here is an identifier, and not an await expression.
12-
var foo = (a = yield ) => __awaiter([this, Promise], function* () {
12+
var foo = (a = yield ) => __awaiter(this, void 0, Promise, function* () {
1313
});
1414
});

tests/baselines/reference/asyncArrowFunction8_es6.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ var foo = async (): Promise<void> => {
55
}
66

77
//// [asyncArrowFunction8_es6.js]
8-
var foo = () => __awaiter([this, Promise], function* () {
8+
var foo = () => __awaiter(this, void 0, Promise, function* () {
99
var v = { [yield ]: foo };
1010
});

tests/baselines/reference/asyncArrowFunctionCapturesArguments_es6.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ class C {
1111
class C {
1212
method() {
1313
function other() { }
14-
var fn = () => __awaiter([this, , arguments], function* (arguments) { return yield other.apply(this, arguments); });
14+
var fn = () => __awaiter(this, arguments, Promise, function* (_arguments) { return yield other.apply(this, _arguments); });
1515
}
1616
}

tests/baselines/reference/asyncArrowFunctionCapturesThis_es6.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ class C {
99
//// [asyncArrowFunctionCapturesThis_es6.js]
1010
class C {
1111
method() {
12-
var fn = () => __awaiter([this], function* () { return yield this; });
12+
var fn = () => __awaiter(this, void 0, Promise, function* () { return yield this; });
1313
}
1414
}

tests/baselines/reference/asyncAwaitIsolatedModules_es6.js

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,10 @@ module M {
4040
}
4141

4242
//// [asyncAwaitIsolatedModules_es6.js]
43-
var __awaiter = (this && this.__awaiter) || function (args, generator) {
44-
var PromiseConstructor = args[1] || Promise;
45-
return new PromiseConstructor(function (resolve, reject) {
46-
generator = generator.call(args[0], args[2]);
47-
function cast(value) { return value instanceof PromiseConstructor ? value : new PromiseConstructor(function (resolve) { resolve(value); }); }
43+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
44+
return new Promise(function (resolve, reject) {
45+
generator = generator.call(thisArg, _arguments);
46+
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
4847
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
4948
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
5049
function step(verb, value) {
@@ -55,65 +54,65 @@ var __awaiter = (this && this.__awaiter) || function (args, generator) {
5554
});
5655
};
5756
function f0() {
58-
return __awaiter([this], function* () { });
57+
return __awaiter(this, void 0, Promise, function* () { });
5958
}
6059
function f1() {
61-
return __awaiter([this, Promise], function* () { });
60+
return __awaiter(this, void 0, Promise, function* () { });
6261
}
6362
function f3() {
64-
return __awaiter([this, MyPromise], function* () { });
63+
return __awaiter(this, void 0, MyPromise, function* () { });
6564
}
6665
let f4 = function () {
67-
return __awaiter([this], function* () { });
66+
return __awaiter(this, void 0, Promise, function* () { });
6867
};
6968
let f5 = function () {
70-
return __awaiter([this, Promise], function* () { });
69+
return __awaiter(this, void 0, Promise, function* () { });
7170
};
7271
let f6 = function () {
73-
return __awaiter([this, MyPromise], function* () { });
72+
return __awaiter(this, void 0, MyPromise, function* () { });
7473
};
75-
let f7 = () => __awaiter([this], function* () { });
76-
let f8 = () => __awaiter([this, Promise], function* () { });
77-
let f9 = () => __awaiter([this, MyPromise], function* () { });
78-
let f10 = () => __awaiter([this], function* () { return p; });
79-
let f11 = () => __awaiter([this], function* () { return mp; });
80-
let f12 = () => __awaiter([this, Promise], function* () { return mp; });
81-
let f13 = () => __awaiter([this, MyPromise], function* () { return p; });
74+
let f7 = () => __awaiter(this, void 0, Promise, function* () { });
75+
let f8 = () => __awaiter(this, void 0, Promise, function* () { });
76+
let f9 = () => __awaiter(this, void 0, MyPromise, function* () { });
77+
let f10 = () => __awaiter(this, void 0, Promise, function* () { return p; });
78+
let f11 = () => __awaiter(this, void 0, Promise, function* () { return mp; });
79+
let f12 = () => __awaiter(this, void 0, Promise, function* () { return mp; });
80+
let f13 = () => __awaiter(this, void 0, MyPromise, function* () { return p; });
8281
let o = {
8382
m1() {
84-
return __awaiter([this], function* () { });
83+
return __awaiter(this, void 0, Promise, function* () { });
8584
},
8685
m2() {
87-
return __awaiter([this, Promise], function* () { });
86+
return __awaiter(this, void 0, Promise, function* () { });
8887
},
8988
m3() {
90-
return __awaiter([this, MyPromise], function* () { });
89+
return __awaiter(this, void 0, MyPromise, function* () { });
9190
}
9291
};
9392
class C {
9493
m1() {
95-
return __awaiter([this], function* () { });
94+
return __awaiter(this, void 0, Promise, function* () { });
9695
}
9796
m2() {
98-
return __awaiter([this, Promise], function* () { });
97+
return __awaiter(this, void 0, Promise, function* () { });
9998
}
10099
m3() {
101-
return __awaiter([this, MyPromise], function* () { });
100+
return __awaiter(this, void 0, MyPromise, function* () { });
102101
}
103102
static m4() {
104-
return __awaiter([this], function* () { });
103+
return __awaiter(this, void 0, Promise, function* () { });
105104
}
106105
static m5() {
107-
return __awaiter([this, Promise], function* () { });
106+
return __awaiter(this, void 0, Promise, function* () { });
108107
}
109108
static m6() {
110-
return __awaiter([this, MyPromise], function* () { });
109+
return __awaiter(this, void 0, MyPromise, function* () { });
111110
}
112111
}
113112
var M;
114113
(function (M) {
115114
function f1() {
116-
return __awaiter([this], function* () { });
115+
return __awaiter(this, void 0, Promise, function* () { });
117116
}
118117
M.f1 = f1;
119118
})(M || (M = {}));

0 commit comments

Comments
 (0)