Optimize transform-async-to-generator output (#14122)
* Optimize `transform-async-to-generator` output - remove wrapper if the function length is zero. - remove wrapper if the `assumptions.ignoreFunctionLength` is `true`. * chore: update test case and code style * chore: add test
This commit is contained in:
parent
213397be99
commit
910ece5e2a
@ -36,6 +36,7 @@ export default function (
|
|||||||
wrapAwait?: any;
|
wrapAwait?: any;
|
||||||
},
|
},
|
||||||
noNewArrows?: boolean,
|
noNewArrows?: boolean,
|
||||||
|
ignoreFunctionLength?: boolean,
|
||||||
) {
|
) {
|
||||||
path.traverse(awaitVisitor, {
|
path.traverse(awaitVisitor, {
|
||||||
wrapAwait: helpers.wrapAwait,
|
wrapAwait: helpers.wrapAwait,
|
||||||
@ -46,7 +47,12 @@ export default function (
|
|||||||
path.node.async = false;
|
path.node.async = false;
|
||||||
path.node.generator = true;
|
path.node.generator = true;
|
||||||
|
|
||||||
wrapFunction(path, cloneNode(helpers.wrapAsync), noNewArrows);
|
wrapFunction(
|
||||||
|
path,
|
||||||
|
cloneNode(helpers.wrapAsync),
|
||||||
|
noNewArrows,
|
||||||
|
ignoreFunctionLength,
|
||||||
|
);
|
||||||
|
|
||||||
const isProperty =
|
const isProperty =
|
||||||
path.isObjectMethod() ||
|
path.isObjectMethod() ||
|
||||||
|
|||||||
@ -66,7 +66,12 @@ function classOrObjectMethod(
|
|||||||
).unwrapFunctionEnvironment();
|
).unwrapFunctionEnvironment();
|
||||||
}
|
}
|
||||||
|
|
||||||
function plainFunction(path: NodePath<any>, callId: any, noNewArrows: boolean) {
|
function plainFunction(
|
||||||
|
path: NodePath<any>,
|
||||||
|
callId: any,
|
||||||
|
noNewArrows: boolean,
|
||||||
|
ignoreFunctionLength: boolean,
|
||||||
|
) {
|
||||||
const node = path.node;
|
const node = path.node;
|
||||||
const isDeclaration = path.isFunctionDeclaration();
|
const isDeclaration = path.isFunctionDeclaration();
|
||||||
const functionId = node.id;
|
const functionId = node.id;
|
||||||
@ -87,26 +92,20 @@ function plainFunction(path: NodePath<any>, callId: any, noNewArrows: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const built = callExpression(callId, [node]);
|
const built = callExpression(callId, [node]);
|
||||||
|
|
||||||
|
const params: t.Identifier[] = [];
|
||||||
|
for (const param of node.params) {
|
||||||
|
if (isAssignmentPattern(param) || isRestElement(param)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
params.push(path.scope.generateUidIdentifier("x"));
|
||||||
|
}
|
||||||
|
|
||||||
const container = wrapper({
|
const container = wrapper({
|
||||||
NAME: functionId || null,
|
NAME: functionId || null,
|
||||||
REF: path.scope.generateUidIdentifier(functionId ? functionId.name : "ref"),
|
REF: path.scope.generateUidIdentifier(functionId ? functionId.name : "ref"),
|
||||||
FUNCTION: built,
|
FUNCTION: built,
|
||||||
PARAMS: node.params.reduce(
|
PARAMS: params,
|
||||||
(acc, param) => {
|
|
||||||
acc.done =
|
|
||||||
acc.done || isAssignmentPattern(param) || isRestElement(param);
|
|
||||||
|
|
||||||
if (!acc.done) {
|
|
||||||
acc.params.push(path.scope.generateUidIdentifier("x"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
params: [],
|
|
||||||
done: false,
|
|
||||||
},
|
|
||||||
).params,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isDeclaration) {
|
if (isDeclaration) {
|
||||||
@ -123,7 +122,11 @@ function plainFunction(path: NodePath<any>, callId: any, noNewArrows: boolean) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!retFunction || retFunction.id || node.params.length) {
|
if (
|
||||||
|
!retFunction ||
|
||||||
|
retFunction.id ||
|
||||||
|
(!ignoreFunctionLength && params.length)
|
||||||
|
) {
|
||||||
// we have an inferred function id or params so we need this wrapper
|
// we have an inferred function id or params so we need this wrapper
|
||||||
// @ts-expect-error todo(flow->ts) separate `wrapper` for `isDeclaration` and `else` branches
|
// @ts-expect-error todo(flow->ts) separate `wrapper` for `isDeclaration` and `else` branches
|
||||||
path.replaceWith(container);
|
path.replaceWith(container);
|
||||||
@ -139,10 +142,11 @@ export default function wrapFunction(
|
|||||||
callId: any,
|
callId: any,
|
||||||
// TODO(Babel 8): Consider defaulting to false for spec compliancy
|
// TODO(Babel 8): Consider defaulting to false for spec compliancy
|
||||||
noNewArrows: boolean = true,
|
noNewArrows: boolean = true,
|
||||||
|
ignoreFunctionLength: boolean = false,
|
||||||
) {
|
) {
|
||||||
if (path.isMethod()) {
|
if (path.isMethod()) {
|
||||||
classOrObjectMethod(path, callId);
|
classOrObjectMethod(path, callId);
|
||||||
} else {
|
} else {
|
||||||
plainFunction(path, callId, noNewArrows);
|
plainFunction(path, callId, noNewArrows, ignoreFunctionLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ export default declare((api, options) => {
|
|||||||
|
|
||||||
const { method, module } = options;
|
const { method, module } = options;
|
||||||
const noNewArrows = api.assumption("noNewArrows");
|
const noNewArrows = api.assumption("noNewArrows");
|
||||||
|
const ignoreFunctionLength = api.assumption("ignoreFunctionLength");
|
||||||
|
|
||||||
if (method && module) {
|
if (method && module) {
|
||||||
return {
|
return {
|
||||||
@ -24,7 +25,12 @@ export default declare((api, options) => {
|
|||||||
wrapAsync = state.methodWrapper = addNamed(path, method, module);
|
wrapAsync = state.methodWrapper = addNamed(path, method, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
remapAsyncToGenerator(path, { wrapAsync }, noNewArrows);
|
remapAsyncToGenerator(
|
||||||
|
path,
|
||||||
|
{ wrapAsync },
|
||||||
|
noNewArrows,
|
||||||
|
ignoreFunctionLength,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -41,6 +47,7 @@ export default declare((api, options) => {
|
|||||||
path,
|
path,
|
||||||
{ wrapAsync: state.addHelper("asyncToGenerator") },
|
{ wrapAsync: state.addHelper("asyncToGenerator") },
|
||||||
noNewArrows,
|
noNewArrows,
|
||||||
|
ignoreFunctionLength,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
foo(async (x) => {});
|
||||||
|
foo(async ([x]) => {});
|
||||||
|
foo(async ({ x }) => {});
|
||||||
|
|
||||||
|
foo(async function (x) {});
|
||||||
|
foo(async function ([x]) {});
|
||||||
|
foo(async function ({ x }) {});
|
||||||
|
|
||||||
|
foo(async ([]) => {});
|
||||||
|
foo(async ({}) => {});
|
||||||
|
|
||||||
|
foo(async function ([]) {});
|
||||||
|
foo(async function ({}) {});
|
||||||
|
|
||||||
|
export default async ([...x]) => {};
|
||||||
|
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["transform-async-to-generator"],
|
||||||
|
"assumptions": {
|
||||||
|
"ignoreFunctionLength": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* (x) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* ([x]) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* ({
|
||||||
|
x
|
||||||
|
}) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* (x) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* ([x]) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* ({
|
||||||
|
x
|
||||||
|
}) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* ([]) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* ({}) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* ([]) {}));
|
||||||
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* ({}) {}));
|
||||||
|
export default /*#__PURE__*/babelHelpers.asyncToGenerator(function* ([...x]) {});
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export default async function (x) {}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["transform-async-to-generator"],
|
||||||
|
"assumptions": {
|
||||||
|
"ignoreFunctionLength": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
export default function (_x) {
|
||||||
|
return _ref.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _ref() {
|
||||||
|
_ref = babelHelpers.asyncToGenerator(function* (x) {});
|
||||||
|
return _ref.apply(this, arguments);
|
||||||
|
}
|
||||||
@ -1,3 +1,11 @@
|
|||||||
foo(async function () {
|
foo(async function () {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bar(async function (x = 1) {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
baz(async function (...y) {
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@ -1 +1,5 @@
|
|||||||
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* () {}));
|
foo( /*#__PURE__*/babelHelpers.asyncToGenerator(function* () {}));
|
||||||
|
bar( /*#__PURE__*/babelHelpers.asyncToGenerator(function* () {
|
||||||
|
let x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
|
||||||
|
}));
|
||||||
|
baz( /*#__PURE__*/babelHelpers.asyncToGenerator(function* () {}));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user