Fix _step.value access in for await (#13491)
This commit is contained in:
parent
b67ea12c4d
commit
2b6acada3c
@ -2,26 +2,22 @@ import { types as t, template } from "@babel/core";
|
||||
|
||||
const buildForAwait = template(`
|
||||
async function wrapper() {
|
||||
var ITERATOR_COMPLETION = true;
|
||||
var ITERATOR_ABRUPT_COMPLETION = false;
|
||||
var ITERATOR_HAD_ERROR_KEY = false;
|
||||
var ITERATOR_ERROR_KEY;
|
||||
try {
|
||||
for (
|
||||
var ITERATOR_KEY = GET_ITERATOR(OBJECT), STEP_KEY, STEP_VALUE;
|
||||
(
|
||||
STEP_KEY = await ITERATOR_KEY.next(),
|
||||
ITERATOR_COMPLETION = STEP_KEY.done,
|
||||
STEP_VALUE = await STEP_KEY.value,
|
||||
!ITERATOR_COMPLETION
|
||||
);
|
||||
ITERATOR_COMPLETION = true) {
|
||||
var ITERATOR_KEY = GET_ITERATOR(OBJECT), STEP_KEY;
|
||||
ITERATOR_ABRUPT_COMPLETION = !(STEP_KEY = await ITERATOR_KEY.next()).done;
|
||||
ITERATOR_ABRUPT_COMPLETION = false
|
||||
) {
|
||||
}
|
||||
} catch (err) {
|
||||
ITERATOR_HAD_ERROR_KEY = true;
|
||||
ITERATOR_ERROR_KEY = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!ITERATOR_COMPLETION && ITERATOR_KEY.return != null) {
|
||||
if (ITERATOR_ABRUPT_COMPLETION && ITERATOR_KEY.return != null) {
|
||||
await ITERATOR_KEY.return();
|
||||
}
|
||||
} finally {
|
||||
@ -37,7 +33,7 @@ export default function (path, { getAsyncIterator }) {
|
||||
const { node, scope, parent } = path;
|
||||
|
||||
const stepKey = scope.generateUidIdentifier("step");
|
||||
const stepValue = scope.generateUidIdentifier("value");
|
||||
const stepValue = t.memberExpression(stepKey, t.identifier("value"));
|
||||
const left = node.left;
|
||||
let declar;
|
||||
|
||||
@ -54,15 +50,14 @@ export default function (path, { getAsyncIterator }) {
|
||||
}
|
||||
let template = buildForAwait({
|
||||
ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
|
||||
ITERATOR_COMPLETION: scope.generateUidIdentifier(
|
||||
"iteratorNormalCompletion",
|
||||
ITERATOR_ABRUPT_COMPLETION: scope.generateUidIdentifier(
|
||||
"iteratorAbruptCompletion",
|
||||
),
|
||||
ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
|
||||
ITERATOR_KEY: scope.generateUidIdentifier("iterator"),
|
||||
GET_ITERATOR: getAsyncIterator,
|
||||
OBJECT: node.right,
|
||||
STEP_VALUE: t.cloneNode(stepValue),
|
||||
STEP_KEY: stepKey,
|
||||
STEP_KEY: t.cloneNode(stepKey),
|
||||
});
|
||||
|
||||
// remove async function wrapper
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
/*#__PURE__*/
|
||||
babelHelpers.asyncToGenerator(function* () {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _iteratorAbruptCompletion = false;
|
||||
var _didIteratorError = false;
|
||||
|
||||
var _iteratorError;
|
||||
|
||||
try {
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
|
||||
let x = _value;
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step; _iteratorAbruptCompletion = !(_step = yield _iterator.next()).done; _iteratorAbruptCompletion = false) {
|
||||
let x = _step.value;
|
||||
f(x);
|
||||
}
|
||||
} catch (err) {
|
||||
@ -15,7 +15,7 @@ babelHelpers.asyncToGenerator(function* () {
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
||||
if (_iteratorAbruptCompletion && _iterator.return != null) {
|
||||
yield _iterator.return();
|
||||
}
|
||||
} finally {
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
async function foo() {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _iteratorAbruptCompletion = false;
|
||||
var _didIteratorError = false;
|
||||
|
||||
var _iteratorError;
|
||||
|
||||
try {
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = await _iterator.next(), _iteratorNormalCompletion = _step.done, _value = await _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
|
||||
const x = _value;
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step; _iteratorAbruptCompletion = !(_step = await _iterator.next()).done; _iteratorAbruptCompletion = false) {
|
||||
const x = _step.value;
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
||||
if (_iteratorAbruptCompletion && _iterator.return != null) {
|
||||
await _iterator.return();
|
||||
}
|
||||
} finally {
|
||||
|
||||
@ -4,14 +4,14 @@ function f() {
|
||||
|
||||
function _f() {
|
||||
_f = babelHelpers.asyncToGenerator(function* () {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _iteratorAbruptCompletion = false;
|
||||
var _didIteratorError = false;
|
||||
|
||||
var _iteratorError;
|
||||
|
||||
try {
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
|
||||
let x = _value;
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step; _iteratorAbruptCompletion = !(_step = yield _iterator.next()).done; _iteratorAbruptCompletion = false) {
|
||||
let x = _step.value;
|
||||
g(x);
|
||||
}
|
||||
} catch (err) {
|
||||
@ -19,7 +19,7 @@ function _f() {
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
||||
if (_iteratorAbruptCompletion && _iterator.return != null) {
|
||||
yield _iterator.return();
|
||||
}
|
||||
} finally {
|
||||
|
||||
@ -4,14 +4,14 @@ function g() {
|
||||
|
||||
function _g() {
|
||||
_g = babelHelpers.wrapAsyncGenerator(function* () {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _iteratorAbruptCompletion = false;
|
||||
var _didIteratorError = false;
|
||||
|
||||
var _iteratorError;
|
||||
|
||||
try {
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield babelHelpers.awaitAsyncGenerator(_iterator.next()), _iteratorNormalCompletion = _step.done, _value = yield babelHelpers.awaitAsyncGenerator(_step.value), !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
|
||||
let x = _value;
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step; _iteratorAbruptCompletion = !(_step = yield babelHelpers.awaitAsyncGenerator(_iterator.next())).done; _iteratorAbruptCompletion = false) {
|
||||
let x = _step.value;
|
||||
f(x);
|
||||
}
|
||||
} catch (err) {
|
||||
@ -19,7 +19,7 @@ function _g() {
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
||||
if (_iteratorAbruptCompletion && _iterator.return != null) {
|
||||
yield babelHelpers.awaitAsyncGenerator(_iterator.return());
|
||||
}
|
||||
} finally {
|
||||
|
||||
@ -4,17 +4,17 @@ function f() {
|
||||
|
||||
function _f() {
|
||||
_f = babelHelpers.asyncToGenerator(function* () {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _iteratorAbruptCompletion = false;
|
||||
var _didIteratorError = false;
|
||||
|
||||
var _iteratorError;
|
||||
|
||||
try {
|
||||
for (var _iterator = babelHelpers.asyncIterator(a), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
|
||||
for (var _iterator = babelHelpers.asyncIterator(a), _step; _iteratorAbruptCompletion = !(_step = yield _iterator.next()).done; _iteratorAbruptCompletion = false) {
|
||||
let {
|
||||
x,
|
||||
y: [z]
|
||||
} = _value;
|
||||
} = _step.value;
|
||||
g(x, z);
|
||||
}
|
||||
} catch (err) {
|
||||
@ -22,7 +22,7 @@ function _f() {
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
||||
if (_iteratorAbruptCompletion && _iterator.return != null) {
|
||||
yield _iterator.return();
|
||||
}
|
||||
} finally {
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
return async function () {
|
||||
let obj = {};
|
||||
for await (obj.x of [1, 2]);
|
||||
|
||||
expect(obj.x).toBe(2);
|
||||
}();
|
||||
@ -0,0 +1,3 @@
|
||||
(async function () {
|
||||
for await (obj.x of y) {}
|
||||
})();
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"parserOpts": {
|
||||
"allowReturnOutsideFunction": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
babelHelpers.asyncToGenerator(function* () {
|
||||
var _iteratorAbruptCompletion = false;
|
||||
var _didIteratorError = false;
|
||||
|
||||
var _iteratorError;
|
||||
|
||||
try {
|
||||
for (var _iterator = babelHelpers.asyncIterator(y), _step; _iteratorAbruptCompletion = !(_step = yield _iterator.next()).done; _iteratorAbruptCompletion = false) {
|
||||
obj.x = _step.value;
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (_iteratorAbruptCompletion && _iterator.return != null) {
|
||||
yield _iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
@ -0,0 +1,31 @@
|
||||
let resolve;
|
||||
let promise = new Promise((r) => (resolve = r));
|
||||
let iterable = {
|
||||
[Symbol.asyncIterator || "@@asyncIterator"]() {
|
||||
return {
|
||||
next: () => promise,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
let values = [];
|
||||
|
||||
return Promise.all([
|
||||
async function () {
|
||||
for await (let value of iterable) {
|
||||
values.push(value);
|
||||
}
|
||||
}(),
|
||||
async function () {
|
||||
resolve({ value: 0, done: false });
|
||||
promise = new Promise((r) => (resolve = r));
|
||||
|
||||
await null;
|
||||
resolve({ value: 1, done: false });
|
||||
promise = new Promise((r) => (resolve = r));
|
||||
|
||||
resolve({ value: undefined, done: true });
|
||||
}(),
|
||||
]).then(() => {
|
||||
expect(values).toEqual([0, 1]);
|
||||
});
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"parserOpts": {
|
||||
"allowReturnOutsideFunction": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
let steps = [
|
||||
{ done: false, value: Promise.resolve(1) },
|
||||
{ done: true, value: undefined }
|
||||
];
|
||||
|
||||
let iterable = {
|
||||
[Symbol.asyncIterator || "@@asyncIterator"]() {
|
||||
return {
|
||||
next: () => steps.shift(),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
let values = [];
|
||||
|
||||
return async function () {
|
||||
let value;
|
||||
for await (value of iterable);
|
||||
|
||||
expect(value).toBeInstanceOf(Promise);
|
||||
await expect(value).resolves.toBe(1);
|
||||
}();
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"parserOpts": {
|
||||
"allowReturnOutsideFunction": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
let gotValue = false;
|
||||
|
||||
let iterable = {
|
||||
[Symbol.asyncIterator || "@@asyncIterator"]() {
|
||||
return {
|
||||
next: () => Promise.resolve({
|
||||
get value() { gotValue = true },
|
||||
done: true
|
||||
})
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
return async function () {
|
||||
for await (let value of iterable) {}
|
||||
|
||||
expect(gotValue).toBe(false);
|
||||
}();
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"parserOpts": {
|
||||
"allowReturnOutsideFunction": true
|
||||
}
|
||||
}
|
||||
@ -1,21 +1,20 @@
|
||||
(async () => {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _iteratorAbruptCompletion = false;
|
||||
var _didIteratorError = false;
|
||||
|
||||
var _iteratorError;
|
||||
|
||||
try {
|
||||
for (var _iterator = babelHelpers.asyncIterator(iterable), _step, _value; _step = await _iterator.next(), _iteratorNormalCompletion = _step.done, _value = await _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
|
||||
const _value2 = _value,
|
||||
_value3 = babelHelpers.slicedToArray(_value2, 1),
|
||||
value = _value3[0];
|
||||
for (var _iterator = babelHelpers.asyncIterator(iterable), _step; _iteratorAbruptCompletion = !(_step = await _iterator.next()).done; _iteratorAbruptCompletion = false) {
|
||||
const _step$value = babelHelpers.slicedToArray(_step.value, 1),
|
||||
value = _step$value[0];
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
||||
if (_iteratorAbruptCompletion && _iterator.return != null) {
|
||||
await _iterator.return();
|
||||
}
|
||||
} finally {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user