Skip to content

Commit

Permalink
review
Browse files Browse the repository at this point in the history
  • Loading branch information
liuxingbaoyu committed Dec 2, 2023
1 parent f54850b commit 469755a
Show file tree
Hide file tree
Showing 34 changed files with 167 additions and 251 deletions.
12 changes: 6 additions & 6 deletions packages/babel-helper-remap-async-to-generator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const {
} = t;

const awaitVisitor = traverse.visitors.merge<{
wrapAwait: t.Expression | string;
wrapAwait: t.Expression | (() => t.Expression);
}>([
{
ArrowFunctionExpression(path) {
Expand All @@ -26,8 +26,8 @@ const awaitVisitor = traverse.visitors.merge<{
yieldExpression(
wrapAwait
? callExpression(
typeof wrapAwait === "string"
? path.hub.addHelper(wrapAwait)
typeof wrapAwait === "function"
? wrapAwait()
: cloneNode(wrapAwait),
[argument.node],
)
Expand All @@ -42,9 +42,9 @@ const awaitVisitor = traverse.visitors.merge<{
export default function (
path: NodePath<t.Function>,
helpers: {
wrapAsync: t.Expression | string;
wrapAwait?: t.Expression | string;
callAsync?: string;
wrapAsync: t.Expression | (() => t.Expression);
wrapAwait?: t.Expression | (() => t.Expression);
callAsync?: () => t.Expression;
},
noNewArrows?: boolean,
ignoreFunctionLength?: boolean,
Expand Down
32 changes: 15 additions & 17 deletions packages/babel-helper-wrap-function/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ const buildWrapper = template.statement(`
replacements: Parameters<ReturnType<typeof template.expression>>[0],
) => t.FunctionDeclaration;

const wrappedFns = new WeakMap<t.CallExpression, t.Function>();

function markCallWrapped(path: NodePath<t.Function>) {
(path.get("body.body.0.argument") as NodePath).setData(
"babel-helper-wrap-function_wrapped_function",
(path.get("body.body.0.argument.callee") as NodePath).node,
wrappedFns.set(
(path.get("body.body.0.argument") as NodePath<t.CallExpression>).node,
(path.get("body.body.0.argument.callee") as NodePath<t.Function>).node,
);
}

Expand Down Expand Up @@ -198,11 +200,11 @@ function plainFunction(

export default function wrapFunction(
path: NodePath<t.Function>,
callId: t.Expression | string,
callId: t.Expression | (() => t.Expression),
// TODO(Babel 8): Consider defaulting to false for spec compliance
noNewArrows: boolean = true,
ignoreFunctionLength: boolean = false,
callAsync?: string,
callAsync?: () => t.Expression,
) {
if (callAsync) {
if (path.isMethod()) {
Expand All @@ -215,11 +217,7 @@ export default function wrapFunction(
blockStatement(body.body),
true,
);
body.body = [
returnStatement(
callExpression(path.hub.addHelper(callAsync), [container]),
),
];
body.body = [returnStatement(callExpression(callAsync(), [container]))];

// Regardless of whether or not the wrapped function is an async method
// or generator the outer function should not be
Expand All @@ -239,7 +237,9 @@ export default function wrapFunction(
let path2 = path.arrowFunctionToExpression({ noNewArrows });
if (!process.env.BABEL_8_BREAKING) {
// arrowFunctionToExpression returns undefined in @babel/traverse < 7.18.10
path2 ??= path;
path2 ??= path as unknown as NodePath<
t.FunctionDeclaration | t.FunctionExpression | t.CallExpression
>;
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
node = path2.node as
Expand All @@ -254,7 +254,7 @@ export default function wrapFunction(
let built = node;
if (!isCallExpression(node)) {
functionId = node.id;
built = callExpression(path.hub.addHelper(callAsync), [
built = callExpression(callAsync(), [
functionExpression(null, node.params, node.body, node.generator),
identifier("this"),
identifier("arguments"),
Expand Down Expand Up @@ -294,7 +294,7 @@ export default function wrapFunction(
} else {
// we can omit this wrapper as the conditions it protects for do not apply
path.replaceWith(
callExpression(path.hub.addHelper(callId as string), [
callExpression((callId as () => t.Expression)(), [
node as t.FunctionExpression,
]),
);
Expand Down Expand Up @@ -322,10 +322,8 @@ export function buildOnCallExpression(helperName: string) {
if (!state.availableHelper(helperName)) {
return;
}
if (path.parentPath.isCallExpression()) {
const wrappedFn = path.parentPath.getData(
"babel-helper-wrap-function_wrapped_function",
);
if (isCallExpression(path.parent)) {
const wrappedFn = wrappedFns.get(path.parent);

if (!wrappedFn || wrappedFn === path.node.callee) return;

Expand Down
64 changes: 2 additions & 62 deletions packages/babel-helpers/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,41 +34,6 @@ helpers.wrapAsyncGenerator = helper("7.0.0-beta.0")`
}
`;

helpers.asyncToGenerator = helper("7.0.0-beta.0")`
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
export default function _asyncToGenerator(fn) {
return function () {
var self = this, args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
`;

helpers.callAsyncGenerator = helper("7.23.0")`
import AsyncGenerator from "AsyncGenerator";
Expand All @@ -77,9 +42,9 @@ helpers.callAsyncGenerator = helper("7.23.0")`
}
`;

helpers.asyncToGenerator2 = helper("7.23.0")`
helpers.asyncToGenerator = helper("7.23.0")`
import callAsync from "callAsync";
export default function _asyncToGenerator2(fn) {
export default function _asyncToGenerator(fn) {
return function () {
return callAsync(fn, this, arguments);
};
Expand Down Expand Up @@ -915,31 +880,6 @@ helpers.callSkipFirstGeneratorNext = helper("7.23.0")`
}
`;

helpers.toPrimitive = helper("7.1.5")`
export default function _toPrimitive(
input,
hint /*: "default" | "string" | "number" | void */
) {
if (typeof input !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (typeof res !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
`;

helpers.toPropertyKey = helper("7.1.5")`
import toPrimitive from "toPrimitive";
export default function _toPropertyKey(arg) {
var key = toPrimitive(arg, "string");
return typeof key === "symbol" ? key : String(key);
}
`;

/**
* Add a helper that will throw a useful error if the transform fails to detect the class
* property assignment, so users know something failed.
Expand Down
64 changes: 33 additions & 31 deletions packages/babel-plugin-proposal-function-sent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,42 +46,44 @@ export default declare(api => {
name: "proposal-function-sent",
inherits: syntaxFunctionSent,

visitor: {
...wrapFunction.buildOnCallExpression("callSkipFirstGeneratorNext"),
MetaProperty(path, state) {
if (!isFunctionSent(path.node)) return;
visitor: api.traverse.visitors.merge([
wrapFunction.buildOnCallExpression("callSkipFirstGeneratorNext"),
{
MetaProperty(path, state) {
if (!isFunctionSent(path.node)) return;

const fnPath = path.getFunctionParent();
const fnPath = path.getFunctionParent();

if (!fnPath.node.generator) {
throw new Error("Parent generator function not found");
}
if (!fnPath.node.generator) {
throw new Error("Parent generator function not found");
}

const sentId = path.scope.generateUid("function.sent");
const sentId = path.scope.generateUid("function.sent");

fnPath.traverse(yieldVisitor, { sentId });
// @ts-expect-error A generator must not be an arrow function
fnPath.node.body.body.unshift(
t.variableDeclaration("let", [
t.variableDeclarator(t.identifier(sentId), t.yieldExpression()),
]),
);

if (state.availableHelper("callSkipFirstGeneratorNext")) {
wrapFunction.default(
fnPath,
"skipFirstGeneratorNext",
undefined,
undefined,
"callSkipFirstGeneratorNext",
);
} else {
wrapFunction.default(
fnPath,
state.addHelper("skipFirstGeneratorNext"),
fnPath.traverse(yieldVisitor, { sentId });
// @ts-expect-error A generator must not be an arrow function
fnPath.node.body.body.unshift(
t.variableDeclaration("let", [
t.variableDeclarator(t.identifier(sentId), t.yieldExpression()),
]),
);
}

if (state.availableHelper("callSkipFirstGeneratorNext")) {
wrapFunction.default(
fnPath,
() => state.addHelper("skipFirstGeneratorNext"),
undefined,
undefined,
() => state.addHelper("callSkipFirstGeneratorNext"),
);
} else {
wrapFunction.default(
fnPath,
state.addHelper("skipFirstGeneratorNext"),
);
}
},
},
},
]),
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ export default declare(api => {
path,
state.availableHelper("callAsyncGenerator")
? {
wrapAsync: "wrapAsyncGenerator",
wrapAwait: "awaitAsyncGenerator",
callAsync: "callAsyncGenerator",
wrapAsync: () => state.addHelper("wrapAsyncGenerator"),
wrapAwait: () => state.addHelper("awaitAsyncGenerator"),
callAsync: () => state.addHelper("callAsyncGenerator"),
}
: {
wrapAsync: state.addHelper("wrapAsyncGenerator"),
Expand All @@ -114,18 +114,20 @@ export default declare(api => {
: // eslint-disable-next-line no-restricted-globals
require("@babel/plugin-syntax-async-generators").default,

visitor: {
...remapAsyncToGenerator.buildOnCallExpression("callAsyncGenerator"),
Program(path, state) {
// We need to traverse the ast here (instead of just vising Function
// in the top level visitor) because for-await needs to run before the
// async-to-generator plugin. This is because for-await is transpiled
// using "await" expressions, which are then converted to "yield".
//
// This is bad for performance, but plugin ordering will allow as to
// directly visit Function in the top level visitor.
path.traverse(visitor, state);
visitor: api.traverse.visitors.merge([
remapAsyncToGenerator.buildOnCallExpression("callAsyncGenerator"),
{
Program(path, state) {
// We need to traverse the ast here (instead of just vising Function
// in the top level visitor) because for-await needs to run before the
// async-to-generator plugin. This is because for-await is transpiled
// using "await" expressions, which are then converted to "yield".
//
// This is bad for performance, but plugin ordering will allow as to
// directly visit Function in the top level visitor.
path.traverse(visitor, state);
},
},
},
]),
};
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*#__PURE__*/babelHelpers.asyncToGenerator2(function* () {
/*#__PURE__*/babelHelpers.asyncToGenerator(function* () {
var _iteratorAbruptCompletion = false;
var _didIteratorError = false;
var _iteratorError;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
babelHelpers.asyncToGenerator2(function* () {
babelHelpers.asyncToGenerator(function* () {
var _iteratorAbruptCompletion = false;
var _didIteratorError = false;
var _iteratorError;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*#__PURE__*/babelHelpers.asyncToGenerator2(function* () {
/*#__PURE__*/babelHelpers.asyncToGenerator(function* () {
var _iteratorAbruptCompletion = false;
var _didIteratorError = false;
var _iteratorError;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function g() {
function f() {
() => this;
}
/*#__PURE__*/babelHelpers.asyncToGenerator2(function* () {
/*#__PURE__*/babelHelpers.asyncToGenerator(function* () {
_this;
yield 1;
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function g() {
return babelHelpers.callAsyncGenerator(function* (x = /*#__PURE__*/babelHelpers.asyncToGenerator2(function* () {
return babelHelpers.callAsyncGenerator(function* (x = /*#__PURE__*/babelHelpers.asyncToGenerator(function* () {
yield 1;
})) {
yield babelHelpers.awaitAsyncGenerator(2);
Expand Down

0 comments on commit 469755a

Please sign in to comment.