Visitar URL original
chore: Clean up `transform-regenerator` by liuxingbaoyu · Pull Request #17455 · babel/babel · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/babel-plugin-transform-regenerator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export default declare(({ types: t, traverse, assertVersion }) => {
name: "transform-regenerator",

visitor: process.env.BABEL_8_BREAKING
? getVisitor(t)
? getVisitor()
: traverse.visitors.merge([
getVisitor(t),
getVisitor(),
{
// We visit CallExpression so that we always transform
// regeneratorRuntime.*() before babel-plugin-polyfill-regenerator.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,17 @@ function getDeclError(node: t.Node) {
);
}

const catchParamVisitor: Visitor = {
Identifier: function (path, state: any) {
const catchParamVisitor: Visitor<{
getSafeParam: () => t.Identifier;
catchParamName: string;
}> = {
Identifier: function (path, state) {
if (path.node.name === state.catchParamName && util.isReference(path)) {
util.replaceWithOrRemove(path, state.getSafeParam());
path.replaceWith(state.getSafeParam());
}
},

Scope: function (path, state: any) {
Scope: function (path, state) {
if (path.scope.hasOwnBinding(state.catchParamName)) {
// Don't descend into nested scopes that shadow the catch
// parameter with their own declarations.
Expand Down Expand Up @@ -716,7 +719,7 @@ export class Emitter {
}

const discriminant = path.get("discriminant");
util.replaceWithOrRemove(discriminant, condition);
discriminant.replaceWith(condition);
self.jump(self.explodeExpression(discriminant));

self.leapManager.withEntry(new leap.SwitchEntry(after), function () {
Expand Down Expand Up @@ -1469,7 +1472,7 @@ export class Emitter {
});

const hasLeapingChildren = explodingChildren.some(child =>
meta.containsLeap(child),
meta.containsLeap(child.node),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fix.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test? :)

);

for (let i = 0; i < explodingChildren.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import * as util from "./util.ts";
const hasOwn = Object.prototype.hasOwnProperty;
import type { NodePath } from "@babel/core";
import { types as t } from "@babel/core";

// The hoist function takes a FunctionExpression or FunctionDeclaration
// and replaces any Declaration nodes in its body with assignments, then
// returns a VariableDeclaration containing just the names of the removed
// declarations.
export function hoist(funPath: any) {
const t = util.getTypes();
export function hoist(
funPath: NodePath<t.FunctionExpression | t.FunctionDeclaration>,
) {
t.assertFunction(funPath.node);

const vars: Record<string, any> = {};
const vars: Record<string, t.Identifier> = { __proto__: null };

function varDeclToExpr({ node: vdec, scope }: any, includeIdentifiers: any) {
function varDeclToExpr(
{ node: vdec, scope }: NodePath,
includeIdentifiers: boolean,
) {
t.assertVariableDeclaration(vdec);
// TODO assert.equal(vdec.kind, "var");
const exprs: any[] = [];
const exprs: t.Expression[] = [];

vdec.declarations.forEach(function (dec: any) {
vdec.declarations.forEach(function (
dec: t.VariableDeclarator & { id: t.Identifier },
) {
// Note: We duplicate 'dec.id' here to ensure that the variable declaration IDs don't
// have the same 'loc' value, since that can make sourcemaps and retainLines behave poorly.
vars[dec.id.name] = t.identifier(dec.id.name);
Expand All @@ -41,14 +47,14 @@ export function hoist(funPath: any) {

funPath.get("body").traverse({
VariableDeclaration: {
exit: function (path: any) {
exit: function (path) {
const expr = varDeclToExpr(path, false);
if (expr === null) {
path.remove();
} else {
// We don't need to traverse this expression any further because
// there can't be any new declarations inside an expression.
util.replaceWithOrRemove(path, t.expressionStatement(expr));
path.replaceWith(t.expressionStatement(expr));
}

// Since the original node has been either removed or replaced,
Expand All @@ -57,34 +63,39 @@ export function hoist(funPath: any) {
},
},

ForStatement: function (path: any) {
ForStatement: function (path) {
const init = path.get("init");
if (init.isVariableDeclaration()) {
util.replaceWithOrRemove(init, varDeclToExpr(init, false));
const expr = varDeclToExpr(init, false);
if (expr) {
init.replaceWith(expr);
} else {
init.remove();
}
}
},

ForXStatement: function (path: any) {
ForXStatement: function (path) {
const left = path.get("left");
if (left.isVariableDeclaration()) {
util.replaceWithOrRemove(left, varDeclToExpr(left, true));
left.replaceWith(varDeclToExpr(left, true));
}
},

FunctionDeclaration: function (path: any) {
FunctionDeclaration: function (path) {
const node = path.node;
vars[node.id.name] = node.id;

const assignment = t.expressionStatement(
t.assignmentExpression(
"=",
t.clone(node.id),
t.cloneNode(node.id),
t.functionExpression(
path.scope.generateUidIdentifierBasedOnNode(node),
node.params,
node.body,
node.generator,
node.expression,
node.async,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fix, but no tests appear to be affected.

),
),
);
Expand All @@ -101,7 +112,7 @@ export function hoist(funPath: any) {
// If the parent node is not a block statement, then we can just
// replace the declaration with the equivalent assignment form
// without worrying about hoisting it.
util.replaceWithOrRemove(path, assignment);
path.replaceWith(assignment);
}

// Remove the binding, to avoid "duplicate declaration" errors when it will
Expand All @@ -112,19 +123,19 @@ export function hoist(funPath: any) {
path.skip();
},

FunctionExpression: function (path: any) {
FunctionExpression: function (path) {
// Don't descend into nested function expressions.
path.skip();
},

ArrowFunctionExpression: function (path: any) {
ArrowFunctionExpression: function (path) {
// Don't descend into nested function expressions.
path.skip();
},
});

const paramNames: Record<string, any> = {};
funPath.get("params").forEach(function (paramPath: any) {
const paramNames: Record<string, t.Identifier> = { __proto__: null };
funPath.get("params").forEach(function (paramPath) {
const param = paramPath.node;
if (t.isIdentifier(param)) {
paramNames[param.name] = param;
Expand All @@ -134,10 +145,10 @@ export function hoist(funPath: any) {
}
});

const declarations: any[] = [];
const declarations: t.VariableDeclarator[] = [];

Object.keys(vars).forEach(function (name: any) {
if (!hasOwn.call(paramNames, name)) {
Object.keys(vars).forEach(function (name) {
if (!Object.hasOwn(paramNames, name)) {
declarations.push(t.variableDeclarator(vars[name], null));
}
});
Expand Down
29 changes: 15 additions & 14 deletions packages/babel-plugin-transform-regenerator/src/regenerator/meta.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import assert from "node:assert";
import { getTypes } from "./util.ts";
import { types as t } from "@babel/core";

const mMap = new WeakMap();
function m(node: any) {
function m(node: t.Node) {
if (!mMap.has(node)) {
mMap.set(node, {});
}
return mMap.get(node);
}

const hasOwn = Object.prototype.hasOwnProperty;

function makePredicate(propertyName: any, knownTypes: any) {
function onlyChildren(node: any) {
const t = getTypes();
function makePredicate(
propertyName: string,
knownTypes: Record<string, boolean>,
) {
function onlyChildren(node: t.Node) {
t.assertNode(node);

// Assume no side effects until we find out otherwise.
Expand All @@ -35,27 +35,28 @@ function makePredicate(propertyName: any, knownTypes: any) {
if (keys) {
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const child = node[key];
const child = node[key as keyof typeof node];
check(child);
}
}

return result;
}

function predicate(node: any) {
getTypes().assertNode(node);
function predicate(node: t.Node) {
t.assertNode(node);

const meta = m(node);
if (hasOwn.call(meta, propertyName)) return meta[propertyName];
if (Object.hasOwn(meta, propertyName)) return meta[propertyName];

// Certain types are "opaque," which means they have no side
// effects or leaps and we don't care about their subexpressions.
// eslint-disable-next-line @typescript-eslint/no-use-before-define
if (hasOwn.call(opaqueTypes, node.type))
if (Object.hasOwn(opaqueTypes, node.type))
return (meta[propertyName] = false);

if (hasOwn.call(knownTypes, node.type)) return (meta[propertyName] = true);
if (Object.hasOwn(knownTypes, node.type))
return (meta[propertyName] = true);

return (meta[propertyName] = onlyChildren(node));
}
Expand Down Expand Up @@ -93,7 +94,7 @@ const leapTypes = {

// All leap types are also side effect types.
for (const type in leapTypes) {
if (hasOwn.call(leapTypes, type)) {
if (Object.hasOwn(leapTypes, type)) {
sideEffectTypes[type as keyof typeof sideEffectTypes] =
leapTypes[type as keyof typeof leapTypes];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as util from "./util.ts";
import type { NodePath } from "@babel/core";
import { types as t } from "@babel/core";

// this function converts a shorthand object generator method into a normal
// (non-shorthand) object property which is a generator function expression. for
Expand Down Expand Up @@ -28,9 +29,7 @@ import * as util from "./util.ts";
//
// If this function is called with an AST node path that is not a Function (or with an
// argument that isn't an AST node path), it will throw an error.
export default function replaceShorthandObjectMethod(path: any) {
const t = util.getTypes();

export default function replaceShorthandObjectMethod(path: NodePath): NodePath {
if (!path.node || !t.isFunction(path.node)) {
throw new Error(
"replaceShorthandObjectMethod can only be called on Function AST node paths.",
Expand All @@ -49,21 +48,20 @@ export default function replaceShorthandObjectMethod(path: any) {
}

const parameters = path.node.params.map(function (param: any) {
return t.cloneDeep(param);
return t.cloneNode(param);
});

const functionExpression = t.functionExpression(
null, // id
parameters, // params
t.cloneDeep(path.node.body), // body
t.cloneNode(path.node.body), // body
path.node.generator,
path.node.async,
);

util.replaceWithOrRemove(
path,
path.replaceWith(
t.objectProperty(
t.cloneDeep(path.node.key), // key
t.cloneNode(path.node.key), // key
functionExpression, //value
path.node.computed, // computed
false, // shorthand
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,5 @@
import type { PluginPass } from "@babel/core";

let currentTypes: any = null;

export function wrapWithTypes<This, Args extends unknown[]>(
types: any,
fn: (this: This, ...args: Args) => unknown,
) {
return function (this: This, ...args: Args) {
const oldTypes = currentTypes;
currentTypes = types;
try {
return fn.apply(this, args);
} finally {
currentTypes = oldTypes;
}
};
}

export function getTypes() {
return currentTypes;
}
import { types as t } from "@babel/core";

export let newHelpersAvailable: (file: PluginPass) => boolean;
if (!process.env.BABEL_8_BREAKING) {
Expand All @@ -33,7 +13,7 @@ if (!process.env.BABEL_8_BREAKING) {
// At this point, we can safely try to inject the `regenerator` helper.
// If this plugin tries to inject any helper, than we are sure that
// `regenerator` is one of them.
!getTypes().isIdentifier(file.addHelper("regenerator"), {
!t.isIdentifier(file.addHelper("regenerator"), {
// This is a special marker returned by transform-runtime, which means
// "the version of `@babel/runtime` does not have the helper".
// Normally transform-runtime will fallback to just injecting the
Expand All @@ -48,7 +28,6 @@ if (!process.env.BABEL_8_BREAKING) {
export let runtimeProperty: (file: PluginPass, name: any) => any;
if (!process.env.BABEL_8_BREAKING) {
runtimeProperty = function (file, name) {
const t = getTypes();
const helper = file.addHelper("regeneratorRuntime");
return t.memberExpression(
// In some cases, `helper` will be (() => regeneratorRuntime).
Expand All @@ -69,11 +48,3 @@ export function isReference(path: any) {
path.parentPath.isAssignmentExpression({ left: path.node })
);
}

export function replaceWithOrRemove(path: any, replacement: any) {
if (replacement) {
path.replaceWith(replacement);
} else {
path.remove();
}
}
Loading