Skip to content

Commit 6793466

Browse files
authored
Merge pull request #15277 from Microsoft/fixAsynxIteration
Check and emit fixes for async iteration
2 parents 6f86625 + 73142ff commit 6793466

12 files changed

+249
-233
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19703,7 +19703,7 @@ namespace ts {
1970319703
}
1970419704

1970519705
let iteratorMethodSignatures: Signature[];
19706-
let mayBeIterable = false;
19706+
let isNonAsyncIterable = false;
1970719707
if (isAsyncIterable) {
1970819708
const iteratorMethod = getTypeOfPropertyOfType(type, getPropertyNameForKnownSymbolName("asyncIterator"));
1970919709
if (isTypeAny(iteratorMethod)) {
@@ -19718,17 +19718,17 @@ namespace ts {
1971819718
return undefined;
1971919719
}
1972019720
iteratorMethodSignatures = iteratorMethod && getSignaturesOfType(iteratorMethod, SignatureKind.Call);
19721-
mayBeIterable = true;
19721+
isNonAsyncIterable = true;
1972219722
}
1972319723

1972419724
if (some(iteratorMethodSignatures)) {
1972519725
const iteratorMethodReturnType = getUnionType(map(iteratorMethodSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
19726-
const iteratedType = getIteratedTypeOfIterator(iteratorMethodReturnType, errorNode, /*isAsyncIterator*/ false);
19726+
const iteratedType = getIteratedTypeOfIterator(iteratorMethodReturnType, errorNode, /*isAsyncIterator*/ !isNonAsyncIterable);
1972719727
if (checkAssignability && errorNode && iteratedType) {
1972819728
// If `checkAssignability` was specified, we were called from
1972919729
// `checkIteratedTypeOrElementType`. As such, we need to validate that
1973019730
// the type passed in is actually an Iterable.
19731-
checkTypeAssignableTo(type, mayBeIterable
19731+
checkTypeAssignableTo(type, isNonAsyncIterable
1973219732
? createIterableType(iteratedType)
1973319733
: createAsyncIterableType(iteratedType), errorNode);
1973419734
}

src/compiler/transformers/esnext.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -891,9 +891,8 @@ namespace ts {
891891
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
892892
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
893893
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
894-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
895-
function _yield(value) { settle(c[2], { value: value, done: false }); }
896-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
894+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
895+
function send(value) { settle(c[2], { value: value, done: false }); }
897896
function fulfill(value) { resume("next", value); }
898897
function reject(value) { resume("throw", value); }
899898
function settle(f, v) { c = void 0, f(v), next(); }
@@ -923,15 +922,16 @@ namespace ts {
923922
scoped: false,
924923
text: `
925924
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
926-
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) };
925+
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) }, p;
927926
return o = __asyncValues(o), i[Symbol.iterator] = function () { return this; }, i;
928-
function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; }
927+
function verb(n, f) { return function (v) { return v = p && n === "throw" ? f(v) : p && v.done ? v : { value: p ? ["yield", v.value] : ["await", (o[n] || f).call(o, v)], done: false }, p = !p, v; }; }
929928
};
930929
`
931930
};
932931

933932
function createAsyncDelegatorHelper(context: TransformationContext, expression: Expression, location?: TextRange) {
934933
context.requestEmitHelper(asyncDelegator);
934+
context.requestEmitHelper(asyncValues);
935935
return setTextRange(
936936
createCall(
937937
getHelperName("__asyncDelegator"),

tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
6868
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
6969
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
7070
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
71-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
72-
function _yield(value) { settle(c[2], { value: value, done: false }); }
73-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
71+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
72+
function send(value) { settle(c[2], { value: value, done: false }); }
7473
function fulfill(value) { resume("next", value); }
7574
function reject(value) { resume("throw", value); }
7675
function settle(f, v) { c = void 0, f(v), next(); }
@@ -89,9 +88,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
8988
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
9089
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
9190
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
92-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
93-
function _yield(value) { settle(c[2], { value: value, done: false }); }
94-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
91+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
92+
function send(value) { settle(c[2], { value: value, done: false }); }
9593
function fulfill(value) { resume("next", value); }
9694
function reject(value) { resume("throw", value); }
9795
function settle(f, v) { c = void 0, f(v), next(); }
@@ -111,9 +109,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
111109
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
112110
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
113111
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
114-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
115-
function _yield(value) { settle(c[2], { value: value, done: false }); }
116-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
112+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
113+
function send(value) { settle(c[2], { value: value, done: false }); }
117114
function fulfill(value) { resume("next", value); }
118115
function reject(value) { resume("throw", value); }
119116
function settle(f, v) { c = void 0, f(v), next(); }
@@ -127,9 +124,14 @@ class C3 {
127124
}
128125
//// [C4.js]
129126
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
130-
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) };
127+
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) }, p;
131128
return o = __asyncValues(o), i[Symbol.iterator] = function () { return this; }, i;
132-
function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; }
129+
function verb(n, f) { return function (v) { return v = p && n === "throw" ? f(v) : p && v.done ? v : { value: p ? ["yield", v.value] : ["await", (o[n] || f).call(o, v)], done: false }, p = !p, v; }; }
130+
};
131+
var __asyncValues = (this && this.__asyncIterator) || function (o) {
132+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
133+
var m = o[Symbol.asyncIterator];
134+
return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator]();
133135
};
134136
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
135137
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -138,9 +140,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
138140
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
139141
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
140142
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
141-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
142-
function _yield(value) { settle(c[2], { value: value, done: false }); }
143-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
143+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
144+
function send(value) { settle(c[2], { value: value, done: false }); }
144145
function fulfill(value) { resume("next", value); }
145146
function reject(value) { resume("throw", value); }
146147
function settle(f, v) { c = void 0, f(v), next(); }
@@ -160,17 +161,21 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
160161
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
161162
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
162163
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
163-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
164-
function _yield(value) { settle(c[2], { value: value, done: false }); }
165-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
164+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
165+
function send(value) { settle(c[2], { value: value, done: false }); }
166166
function fulfill(value) { resume("next", value); }
167167
function reject(value) { resume("throw", value); }
168168
function settle(f, v) { c = void 0, f(v), next(); }
169169
};
170170
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
171-
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) };
171+
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) }, p;
172172
return o = __asyncValues(o), i[Symbol.iterator] = function () { return this; }, i;
173-
function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; }
173+
function verb(n, f) { return function (v) { return v = p && n === "throw" ? f(v) : p && v.done ? v : { value: p ? ["yield", v.value] : ["await", (o[n] || f).call(o, v)], done: false }, p = !p, v; }; }
174+
};
175+
var __asyncValues = (this && this.__asyncIterator) || function (o) {
176+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
177+
var m = o[Symbol.asyncIterator];
178+
return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator]();
174179
};
175180
class C5 {
176181
f() {
@@ -187,9 +192,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
187192
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
188193
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
189194
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
190-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
191-
function _yield(value) { settle(c[2], { value: value, done: false }); }
192-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
195+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
196+
function send(value) { settle(c[2], { value: value, done: false }); }
193197
function fulfill(value) { resume("next", value); }
194198
function reject(value) { resume("throw", value); }
195199
function settle(f, v) { c = void 0, f(v), next(); }
@@ -209,9 +213,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
209213
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
210214
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
211215
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
212-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
213-
function _yield(value) { settle(c[2], { value: value, done: false }); }
214-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
216+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
217+
function send(value) { settle(c[2], { value: value, done: false }); }
215218
function fulfill(value) { resume("next", value); }
216219
function reject(value) { resume("throw", value); }
217220
function settle(f, v) { c = void 0, f(v), next(); }
@@ -231,9 +234,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
231234
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
232235
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
233236
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
234-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
235-
function _yield(value) { settle(c[2], { value: value, done: false }); }
236-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
237+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
238+
function send(value) { settle(c[2], { value: value, done: false }); }
237239
function fulfill(value) { resume("next", value); }
238240
function reject(value) { resume("throw", value); }
239241
function settle(f, v) { c = void 0, f(v), next(); }
@@ -255,9 +257,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
255257
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
256258
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
257259
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
258-
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? _yield : r.value[0] === "delegate" ? delegate : fulfill, reject); }
259-
function _yield(value) { settle(c[2], { value: value, done: false }); }
260-
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
260+
function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
261+
function send(value) { settle(c[2], { value: value, done: false }); }
261262
function fulfill(value) { resume("next", value); }
262263
function reject(value) { resume("throw", value); }
263264
function settle(f, v) { c = void 0, f(v), next(); }

0 commit comments

Comments
 (0)