@babel/plugin-transform-regenerator
Advanced tools
+1129
-16
| import { declare } from '@babel/helper-plugin-utils'; | ||
| import regeneratorTransform from 'regenerator-transform'; | ||
| import assert from 'node:assert'; | ||
| import { types } from '@babel/core'; | ||
| let currentTypes = null; | ||
| function wrapWithTypes(types, fn) { | ||
| return function (...args) { | ||
| const oldTypes = currentTypes; | ||
| currentTypes = types; | ||
| try { | ||
| return fn.apply(this, args); | ||
| } finally { | ||
| currentTypes = oldTypes; | ||
| } | ||
| }; | ||
| } | ||
| function getTypes() { | ||
| return currentTypes; | ||
| } | ||
| function isReference(path) { | ||
| return path.isReferenced() || path.parentPath.isAssignmentExpression({ | ||
| left: path.node | ||
| }); | ||
| } | ||
| function replaceWithOrRemove(path, replacement) { | ||
| if (replacement) { | ||
| path.replaceWith(replacement); | ||
| } else { | ||
| path.remove(); | ||
| } | ||
| } | ||
| const hasOwn$1 = Object.prototype.hasOwnProperty; | ||
| function hoist(funPath) { | ||
| const t = getTypes(); | ||
| t.assertFunction(funPath.node); | ||
| const vars = {}; | ||
| function varDeclToExpr({ | ||
| node: vdec, | ||
| scope | ||
| }, includeIdentifiers) { | ||
| t.assertVariableDeclaration(vdec); | ||
| const exprs = []; | ||
| vdec.declarations.forEach(function (dec) { | ||
| vars[dec.id.name] = t.identifier(dec.id.name); | ||
| scope.removeBinding(dec.id.name); | ||
| if (dec.init) { | ||
| exprs.push(t.assignmentExpression("=", dec.id, dec.init)); | ||
| } else if (includeIdentifiers) { | ||
| exprs.push(dec.id); | ||
| } | ||
| }); | ||
| if (exprs.length === 0) return null; | ||
| if (exprs.length === 1) return exprs[0]; | ||
| return t.sequenceExpression(exprs); | ||
| } | ||
| funPath.get("body").traverse({ | ||
| VariableDeclaration: { | ||
| exit: function (path) { | ||
| const expr = varDeclToExpr(path, false); | ||
| if (expr === null) { | ||
| path.remove(); | ||
| } else { | ||
| replaceWithOrRemove(path, t.expressionStatement(expr)); | ||
| } | ||
| path.skip(); | ||
| } | ||
| }, | ||
| ForStatement: function (path) { | ||
| const init = path.get("init"); | ||
| if (init.isVariableDeclaration()) { | ||
| replaceWithOrRemove(init, varDeclToExpr(init, false)); | ||
| } | ||
| }, | ||
| ForXStatement: function (path) { | ||
| const left = path.get("left"); | ||
| if (left.isVariableDeclaration()) { | ||
| replaceWithOrRemove(left, varDeclToExpr(left, true)); | ||
| } | ||
| }, | ||
| FunctionDeclaration: function (path) { | ||
| const node = path.node; | ||
| vars[node.id.name] = node.id; | ||
| const assignment = t.expressionStatement(t.assignmentExpression("=", t.clone(node.id), t.functionExpression(path.scope.generateUidIdentifierBasedOnNode(node), node.params, node.body, node.generator, node.expression))); | ||
| if (path.parentPath.isBlockStatement()) { | ||
| path.parentPath.unshiftContainer("body", assignment); | ||
| path.remove(); | ||
| } else { | ||
| replaceWithOrRemove(path, assignment); | ||
| } | ||
| path.scope.removeBinding(node.id.name); | ||
| path.skip(); | ||
| }, | ||
| FunctionExpression: function (path) { | ||
| path.skip(); | ||
| }, | ||
| ArrowFunctionExpression: function (path) { | ||
| path.skip(); | ||
| } | ||
| }); | ||
| const paramNames = {}; | ||
| funPath.get("params").forEach(function (paramPath) { | ||
| const param = paramPath.node; | ||
| if (t.isIdentifier(param)) { | ||
| paramNames[param.name] = param; | ||
| } | ||
| }); | ||
| const declarations = []; | ||
| Object.keys(vars).forEach(function (name) { | ||
| if (!hasOwn$1.call(paramNames, name)) { | ||
| declarations.push(t.variableDeclarator(vars[name], null)); | ||
| } | ||
| }); | ||
| return declarations; | ||
| } | ||
| class Entry {} | ||
| class FunctionEntry extends Entry { | ||
| returnLoc; | ||
| constructor(returnLoc) { | ||
| super(); | ||
| this.returnLoc = returnLoc; | ||
| } | ||
| } | ||
| class LoopEntry extends Entry { | ||
| breakLoc; | ||
| continueLoc; | ||
| label; | ||
| constructor(breakLoc, continueLoc, label = null) { | ||
| super(); | ||
| this.breakLoc = breakLoc; | ||
| this.continueLoc = continueLoc; | ||
| this.label = label; | ||
| } | ||
| } | ||
| class SwitchEntry extends Entry { | ||
| breakLoc; | ||
| constructor(breakLoc) { | ||
| super(); | ||
| this.breakLoc = breakLoc; | ||
| } | ||
| } | ||
| class TryEntry extends Entry { | ||
| firstLoc; | ||
| catchEntry; | ||
| finallyEntry; | ||
| constructor(firstLoc, catchEntry = null, finallyEntry = null) { | ||
| super(); | ||
| assert.ok(catchEntry || finallyEntry); | ||
| this.firstLoc = firstLoc; | ||
| this.catchEntry = catchEntry; | ||
| this.finallyEntry = finallyEntry; | ||
| } | ||
| } | ||
| class CatchEntry extends Entry { | ||
| firstLoc; | ||
| paramId; | ||
| constructor(firstLoc, paramId) { | ||
| super(); | ||
| this.firstLoc = firstLoc; | ||
| this.paramId = paramId; | ||
| } | ||
| } | ||
| class FinallyEntry extends Entry { | ||
| firstLoc; | ||
| afterLoc; | ||
| constructor(firstLoc, afterLoc) { | ||
| super(); | ||
| this.firstLoc = firstLoc; | ||
| this.afterLoc = afterLoc; | ||
| } | ||
| } | ||
| class LabeledEntry extends Entry { | ||
| breakLoc; | ||
| label; | ||
| constructor(breakLoc, label) { | ||
| super(); | ||
| this.breakLoc = breakLoc; | ||
| this.label = label; | ||
| } | ||
| } | ||
| class LeapManager { | ||
| emitter; | ||
| entryStack; | ||
| constructor(emitter) { | ||
| this.emitter = emitter; | ||
| this.entryStack = [new FunctionEntry(emitter.finalLoc)]; | ||
| } | ||
| withEntry(entry, callback) { | ||
| this.entryStack.push(entry); | ||
| try { | ||
| callback.call(this.emitter); | ||
| } finally { | ||
| const popped = this.entryStack.pop(); | ||
| assert.strictEqual(popped, entry); | ||
| } | ||
| } | ||
| _findLeapLocation(property, label) { | ||
| for (let i = this.entryStack.length - 1; i >= 0; --i) { | ||
| const entry = this.entryStack[i]; | ||
| const loc = entry[property]; | ||
| if (loc) { | ||
| if (label) { | ||
| if (entry.label && entry.label.name === label.name) { | ||
| return loc; | ||
| } | ||
| } else if (entry instanceof LabeledEntry) ; else { | ||
| return loc; | ||
| } | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| getBreakLoc(label) { | ||
| return this._findLeapLocation("breakLoc", label); | ||
| } | ||
| getContinueLoc(label) { | ||
| return this._findLeapLocation("continueLoc", label); | ||
| } | ||
| } | ||
| const mMap = new WeakMap(); | ||
| function m(node) { | ||
| if (!mMap.has(node)) { | ||
| mMap.set(node, {}); | ||
| } | ||
| return mMap.get(node); | ||
| } | ||
| const hasOwn = Object.prototype.hasOwnProperty; | ||
| function makePredicate(propertyName, knownTypes) { | ||
| function onlyChildren(node) { | ||
| const t = getTypes(); | ||
| t.assertNode(node); | ||
| let result = false; | ||
| function check(child) { | ||
| if (result) ; else if (Array.isArray(child)) { | ||
| child.some(check); | ||
| } else if (t.isNode(child)) { | ||
| assert.strictEqual(result, false); | ||
| result = predicate(child); | ||
| } | ||
| return result; | ||
| } | ||
| const keys = t.VISITOR_KEYS[node.type]; | ||
| if (keys) { | ||
| for (let i = 0; i < keys.length; i++) { | ||
| const key = keys[i]; | ||
| const child = node[key]; | ||
| check(child); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function predicate(node) { | ||
| getTypes().assertNode(node); | ||
| const meta = m(node); | ||
| if (hasOwn.call(meta, propertyName)) return meta[propertyName]; | ||
| if (hasOwn.call(opaqueTypes, node.type)) return meta[propertyName] = false; | ||
| if (hasOwn.call(knownTypes, node.type)) return meta[propertyName] = true; | ||
| return meta[propertyName] = onlyChildren(node); | ||
| } | ||
| predicate.onlyChildren = onlyChildren; | ||
| return predicate; | ||
| } | ||
| const opaqueTypes = { | ||
| FunctionExpression: true, | ||
| ArrowFunctionExpression: true | ||
| }; | ||
| const sideEffectTypes = { | ||
| CallExpression: true, | ||
| ForInStatement: true, | ||
| UnaryExpression: true, | ||
| BinaryExpression: true, | ||
| AssignmentExpression: true, | ||
| UpdateExpression: true, | ||
| NewExpression: true | ||
| }; | ||
| const leapTypes = { | ||
| YieldExpression: true, | ||
| BreakStatement: true, | ||
| ContinueStatement: true, | ||
| ReturnStatement: true, | ||
| ThrowStatement: true | ||
| }; | ||
| for (const type in leapTypes) { | ||
| if (hasOwn.call(leapTypes, type)) { | ||
| sideEffectTypes[type] = leapTypes[type]; | ||
| } | ||
| } | ||
| makePredicate("hasSideEffects", sideEffectTypes); | ||
| const containsLeap = makePredicate("containsLeap", leapTypes); | ||
| const PENDING_LOCATION = Number.MAX_VALUE; | ||
| function getDeclError(node) { | ||
| return new Error("all declarations should have been transformed into " + "assignments before the Exploder began its work: " + JSON.stringify(node)); | ||
| } | ||
| const catchParamVisitor = { | ||
| Identifier: function (path, state) { | ||
| if (path.node.name === state.catchParamName && isReference(path)) { | ||
| replaceWithOrRemove(path, state.getSafeParam()); | ||
| } | ||
| }, | ||
| Scope: function (path, state) { | ||
| if (path.scope.hasOwnBinding(state.catchParamName)) { | ||
| path.skip(); | ||
| } | ||
| } | ||
| }; | ||
| class Emitter { | ||
| nextTempId; | ||
| contextId; | ||
| index; | ||
| indexMap; | ||
| listing; | ||
| returns; | ||
| lastDefaultIndex; | ||
| marked; | ||
| insertedLocs; | ||
| finalLoc; | ||
| tryEntries; | ||
| leapManager; | ||
| scope; | ||
| vars; | ||
| pluginPass; | ||
| constructor(contextId, scope, vars, pluginPass) { | ||
| this.pluginPass = pluginPass; | ||
| this.scope = scope; | ||
| this.vars = vars; | ||
| this.nextTempId = 0; | ||
| this.contextId = contextId; | ||
| this.listing = []; | ||
| this.index = 0; | ||
| this.indexMap = new Map([[0, 0]]); | ||
| this.returns = new Set(); | ||
| this.marked = [true]; | ||
| this.insertedLocs = new Set(); | ||
| this.finalLoc = this.loc(); | ||
| this.tryEntries = []; | ||
| this.leapManager = new LeapManager(this); | ||
| } | ||
| loc() { | ||
| const l = types.numericLiteral(PENDING_LOCATION); | ||
| this.insertedLocs.add(l); | ||
| return l; | ||
| } | ||
| getInsertedLocs() { | ||
| return this.insertedLocs; | ||
| } | ||
| getContextId() { | ||
| return types.cloneNode(this.contextId); | ||
| } | ||
| getIndex() { | ||
| if (!this.indexMap.has(this.listing.length)) { | ||
| this.indexMap.set(this.listing.length, ++this.index); | ||
| } | ||
| return this.index; | ||
| } | ||
| mark(loc) { | ||
| if (loc.value === PENDING_LOCATION) { | ||
| loc.value = this.getIndex(); | ||
| } else { | ||
| assert.strictEqual(loc.value, this.index); | ||
| } | ||
| this.marked[this.listing.length] = true; | ||
| return loc; | ||
| } | ||
| emit(node) { | ||
| if (types.isExpression(node)) { | ||
| node = types.expressionStatement(node); | ||
| } | ||
| types.assertStatement(node); | ||
| this.listing.push(node); | ||
| } | ||
| emitAssign(lhs, rhs) { | ||
| this.emit(this.assign(lhs, rhs)); | ||
| return lhs; | ||
| } | ||
| assign(lhs, rhs) { | ||
| return types.expressionStatement(types.assignmentExpression("=", types.cloneNode(lhs), rhs)); | ||
| } | ||
| contextProperty(name) { | ||
| const computed = name === "catch"; | ||
| return types.memberExpression(this.getContextId(), computed ? types.stringLiteral(name) : types.identifier(name), !!computed); | ||
| } | ||
| clearPendingException(tryLoc, assignee) { | ||
| const catchCall = types.callExpression(this.contextProperty("catch"), [types.cloneNode(tryLoc)]); | ||
| if (assignee) { | ||
| this.emitAssign(assignee, catchCall); | ||
| } else { | ||
| this.emit(catchCall); | ||
| } | ||
| } | ||
| jump(toLoc) { | ||
| this.emitAssign(this.contextProperty("n"), toLoc); | ||
| this.emit(types.breakStatement()); | ||
| } | ||
| jumpIf(test, toLoc) { | ||
| this.emit(types.ifStatement(test, types.blockStatement([this.assign(this.contextProperty("n"), toLoc), types.breakStatement()]))); | ||
| } | ||
| jumpIfNot(test, toLoc) { | ||
| let negatedTest; | ||
| if (types.isUnaryExpression(test) && test.operator === "!") { | ||
| negatedTest = test.argument; | ||
| } else { | ||
| negatedTest = types.unaryExpression("!", test); | ||
| } | ||
| this.emit(types.ifStatement(negatedTest, types.blockStatement([this.assign(this.contextProperty("n"), toLoc), types.breakStatement()]))); | ||
| } | ||
| makeContextTempVar() { | ||
| return this.contextProperty("t" + this.nextTempId++); | ||
| } | ||
| makeTempVar() { | ||
| const id = this.scope.generateUidIdentifier("t"); | ||
| this.vars.push(types.variableDeclarator(id)); | ||
| return types.cloneNode(id); | ||
| } | ||
| getContextFunction() { | ||
| return types.functionExpression(null, [this.getContextId()], types.blockStatement([this.getDispatchLoop()]), false, false); | ||
| } | ||
| getDispatchLoop() { | ||
| const self = this; | ||
| const cases = []; | ||
| let current; | ||
| let alreadyEnded = false; | ||
| self.listing.forEach(function (stmt, i) { | ||
| if (self.marked[i]) { | ||
| cases.push(types.switchCase(types.numericLiteral(self.indexMap.get(i)), current = [])); | ||
| alreadyEnded = false; | ||
| } | ||
| if (!alreadyEnded) { | ||
| current.push(stmt); | ||
| if (types.isCompletionStatement(stmt)) alreadyEnded = true; | ||
| } | ||
| }); | ||
| this.finalLoc.value = this.getIndex(); | ||
| { | ||
| if (this.lastDefaultIndex === this.index || !this.returns.has(this.listing.length)) { | ||
| cases.push(types.switchCase(this.finalLoc, [types.returnStatement(types.callExpression(this.contextProperty("a"), [types.numericLiteral(2)]))])); | ||
| } | ||
| } | ||
| return types.whileStatement(types.numericLiteral(1), types.switchStatement(this.contextProperty("n"), cases)); | ||
| } | ||
| getTryLocsList() { | ||
| if (this.tryEntries.length === 0) { | ||
| return null; | ||
| } | ||
| let lastLocValue = 0; | ||
| const arrayExpression = types.arrayExpression(this.tryEntries.map(function (tryEntry) { | ||
| const thisLocValue = tryEntry.firstLoc.value; | ||
| assert.ok(thisLocValue >= lastLocValue, "try entries out of order"); | ||
| lastLocValue = thisLocValue; | ||
| const ce = tryEntry.catchEntry; | ||
| const fe = tryEntry.finallyEntry; | ||
| const locs = [tryEntry.firstLoc, ce ? ce.firstLoc : null]; | ||
| if (fe) { | ||
| locs[2] = fe.firstLoc; | ||
| locs[3] = fe.afterLoc; | ||
| } | ||
| return types.arrayExpression(locs.map(loc => loc && types.cloneNode(loc))); | ||
| })); | ||
| { | ||
| arrayExpression.elements.reverse(); | ||
| } | ||
| return arrayExpression; | ||
| } | ||
| explode(path, ignoreResult) { | ||
| const node = path.node; | ||
| const self = this; | ||
| if (types.isDeclaration(node)) throw getDeclError(node); | ||
| if (path.isStatement()) return self.explodeStatement(path); | ||
| if (path.isExpression()) return self.explodeExpression(path, ignoreResult); | ||
| switch (node.type) { | ||
| case "VariableDeclarator": | ||
| throw getDeclError(node); | ||
| case "ObjectProperty": | ||
| case "SwitchCase": | ||
| case "CatchClause": | ||
| throw new Error(node.type + " nodes should be handled by their parents"); | ||
| default: | ||
| throw new Error("unknown Node of type " + JSON.stringify(node.type)); | ||
| } | ||
| } | ||
| explodeStatement(path, labelId = null) { | ||
| const stmt = path.node; | ||
| const self = this; | ||
| let before, after, head; | ||
| if (path.isBlockStatement()) { | ||
| path.get("body").forEach(function (path) { | ||
| self.explodeStatement(path); | ||
| }); | ||
| return; | ||
| } | ||
| if (!containsLeap(stmt)) { | ||
| self.emit(stmt); | ||
| return; | ||
| } | ||
| switch (path.type) { | ||
| case "ExpressionStatement": | ||
| self.explodeExpression(path.get("expression"), true); | ||
| break; | ||
| case "LabeledStatement": | ||
| after = this.loc(); | ||
| self.leapManager.withEntry(new LabeledEntry(after, path.node.label), function () { | ||
| self.explodeStatement(path.get("body"), path.node.label); | ||
| }); | ||
| self.mark(after); | ||
| break; | ||
| case "WhileStatement": | ||
| before = this.loc(); | ||
| after = this.loc(); | ||
| self.mark(before); | ||
| self.jumpIfNot(self.explodeExpression(path.get("test")), after); | ||
| self.leapManager.withEntry(new LoopEntry(after, before, labelId), function () { | ||
| self.explodeStatement(path.get("body")); | ||
| }); | ||
| self.jump(before); | ||
| self.mark(after); | ||
| break; | ||
| case "DoWhileStatement": | ||
| const first = this.loc(); | ||
| const test = this.loc(); | ||
| after = this.loc(); | ||
| self.mark(first); | ||
| self.leapManager.withEntry(new LoopEntry(after, test, labelId), function () { | ||
| self.explode(path.get("body")); | ||
| }); | ||
| self.mark(test); | ||
| self.jumpIf(self.explodeExpression(path.get("test")), first); | ||
| self.mark(after); | ||
| break; | ||
| case "ForStatement": | ||
| head = this.loc(); | ||
| const update = this.loc(); | ||
| after = this.loc(); | ||
| if (path.node.init) { | ||
| self.explode(path.get("init"), true); | ||
| } | ||
| self.mark(head); | ||
| if (path.node.test) { | ||
| self.jumpIfNot(self.explodeExpression(path.get("test")), after); | ||
| } | ||
| self.leapManager.withEntry(new LoopEntry(after, update, labelId), function () { | ||
| self.explodeStatement(path.get("body")); | ||
| }); | ||
| self.mark(update); | ||
| if (path.node.update) { | ||
| self.explode(path.get("update"), true); | ||
| } | ||
| self.jump(head); | ||
| self.mark(after); | ||
| break; | ||
| case "TypeCastExpression": | ||
| return self.explodeExpression(path.get("expression")); | ||
| case "ForInStatement": | ||
| head = this.loc(); | ||
| after = this.loc(); | ||
| const keyIterNextFn = self.makeTempVar(); | ||
| const helper = this.pluginPass.addHelper("regeneratorKeys"); | ||
| self.emitAssign(keyIterNextFn, types.callExpression(helper, [self.explodeExpression(path.get("right"))])); | ||
| self.mark(head); | ||
| const keyInfoTmpVar = self.makeTempVar(); | ||
| self.jumpIf(types.memberExpression(types.assignmentExpression("=", keyInfoTmpVar, types.callExpression(types.cloneNode(keyIterNextFn), [])), types.identifier("done"), false), after); | ||
| self.emitAssign(path.node.left, types.memberExpression(types.cloneNode(keyInfoTmpVar), types.identifier("value"), false)); | ||
| self.leapManager.withEntry(new LoopEntry(after, head, labelId), function () { | ||
| self.explodeStatement(path.get("body")); | ||
| }); | ||
| self.jump(head); | ||
| self.mark(after); | ||
| break; | ||
| case "BreakStatement": | ||
| self.emitAbruptCompletion({ | ||
| type: 3, | ||
| target: self.leapManager.getBreakLoc(path.node.label) | ||
| }); | ||
| break; | ||
| case "ContinueStatement": | ||
| self.emitAbruptCompletion({ | ||
| type: 3, | ||
| target: self.leapManager.getContinueLoc(path.node.label) | ||
| }); | ||
| break; | ||
| case "SwitchStatement": | ||
| const disc = self.emitAssign(self.makeTempVar(), self.explodeExpression(path.get("discriminant"))); | ||
| after = this.loc(); | ||
| const defaultLoc = this.loc(); | ||
| let condition = defaultLoc; | ||
| const caseLocs = []; | ||
| const cases = path.node.cases || []; | ||
| for (let i = cases.length - 1; i >= 0; --i) { | ||
| const c = cases[i]; | ||
| if (c.test) { | ||
| condition = types.conditionalExpression(types.binaryExpression("===", types.cloneNode(disc), c.test), caseLocs[i] = this.loc(), condition); | ||
| } else { | ||
| caseLocs[i] = defaultLoc; | ||
| } | ||
| } | ||
| const discriminant = path.get("discriminant"); | ||
| replaceWithOrRemove(discriminant, condition); | ||
| self.jump(self.explodeExpression(discriminant)); | ||
| self.leapManager.withEntry(new SwitchEntry(after), function () { | ||
| path.get("cases").forEach(function (casePath) { | ||
| const i = casePath.key; | ||
| self.mark(caseLocs[i]); | ||
| casePath.get("consequent").forEach(function (path) { | ||
| self.explodeStatement(path); | ||
| }); | ||
| }); | ||
| }); | ||
| self.mark(after); | ||
| if (defaultLoc.value === PENDING_LOCATION) { | ||
| self.mark(defaultLoc); | ||
| assert.strictEqual(after.value, defaultLoc.value); | ||
| this.lastDefaultIndex = this.index; | ||
| } | ||
| break; | ||
| case "IfStatement": | ||
| const elseLoc = path.node.alternate && this.loc(); | ||
| after = this.loc(); | ||
| self.jumpIfNot(self.explodeExpression(path.get("test")), elseLoc || after); | ||
| self.explodeStatement(path.get("consequent")); | ||
| if (elseLoc) { | ||
| self.jump(after); | ||
| self.mark(elseLoc); | ||
| self.explodeStatement(path.get("alternate")); | ||
| } | ||
| self.mark(after); | ||
| break; | ||
| case "ReturnStatement": | ||
| self.emitAbruptCompletion({ | ||
| type: 2, | ||
| value: self.explodeExpression(path.get("argument")) | ||
| }); | ||
| break; | ||
| case "WithStatement": | ||
| throw new Error("WithStatement not supported in generator functions."); | ||
| case "TryStatement": | ||
| after = this.loc(); | ||
| const handler = path.node.handler; | ||
| const catchLoc = handler && this.loc(); | ||
| const catchEntry = catchLoc && new CatchEntry(catchLoc, handler.param); | ||
| const finallyLoc = path.node.finalizer && this.loc(); | ||
| const finallyEntry = finallyLoc && new FinallyEntry(finallyLoc, after); | ||
| const tryEntry = new TryEntry(self.getUnmarkedCurrentLoc(), catchEntry, finallyEntry); | ||
| self.tryEntries.push(tryEntry); | ||
| self.updateContextPrevLoc(tryEntry.firstLoc); | ||
| self.leapManager.withEntry(tryEntry, () => { | ||
| self.explodeStatement(path.get("block")); | ||
| if (catchLoc) { | ||
| if (finallyLoc) { | ||
| self.jump(finallyLoc); | ||
| } else { | ||
| self.jump(after); | ||
| } | ||
| self.updateContextPrevLoc(self.mark(catchLoc)); | ||
| const bodyPath = path.get("handler.body"); | ||
| const safeParam = self.makeTempVar(); | ||
| { | ||
| this.emitAssign(safeParam, self.contextProperty("v")); | ||
| } | ||
| bodyPath.traverse(catchParamVisitor, { | ||
| getSafeParam: () => types.cloneNode(safeParam), | ||
| catchParamName: handler.param.name | ||
| }); | ||
| self.leapManager.withEntry(catchEntry, function () { | ||
| self.explodeStatement(bodyPath); | ||
| }); | ||
| } | ||
| if (finallyLoc) { | ||
| self.updateContextPrevLoc(self.mark(finallyLoc)); | ||
| self.leapManager.withEntry(finallyEntry, function () { | ||
| self.explodeStatement(path.get("finalizer")); | ||
| }); | ||
| self.emit(types.returnStatement(types.callExpression(self.contextProperty("f"), [finallyEntry.firstLoc]))); | ||
| } | ||
| }); | ||
| self.mark(after); | ||
| break; | ||
| case "ThrowStatement": | ||
| self.emit(types.throwStatement(self.explodeExpression(path.get("argument")))); | ||
| break; | ||
| case "ClassDeclaration": | ||
| self.emit(self.explodeClass(path)); | ||
| break; | ||
| default: | ||
| throw new Error("unknown Statement of type " + JSON.stringify(stmt.type)); | ||
| } | ||
| } | ||
| emitAbruptCompletion(record) { | ||
| const abruptArgs = [types.numericLiteral(record.type)]; | ||
| if (record.type === 3) { | ||
| abruptArgs[1] = this.insertedLocs.has(record.target) ? record.target : types.cloneNode(record.target); | ||
| } else if (record.type === 2) { | ||
| if (record.value) { | ||
| abruptArgs[1] = types.cloneNode(record.value); | ||
| } | ||
| } | ||
| this.emit(types.returnStatement(types.callExpression(this.contextProperty("a"), abruptArgs))); | ||
| if (record.type === 2) { | ||
| this.returns.add(this.listing.length); | ||
| } | ||
| } | ||
| getUnmarkedCurrentLoc() { | ||
| return types.numericLiteral(this.getIndex()); | ||
| } | ||
| updateContextPrevLoc(loc) { | ||
| if (loc) { | ||
| if (loc.value === PENDING_LOCATION) { | ||
| loc.value = this.getIndex(); | ||
| } else { | ||
| assert.strictEqual(loc.value, this.index); | ||
| } | ||
| } else { | ||
| loc = this.getUnmarkedCurrentLoc(); | ||
| } | ||
| this.emitAssign(this.contextProperty("p"), loc); | ||
| } | ||
| explodeViaTempVar(tempVar, childPath, hasLeapingChildren, ignoreChildResult) { | ||
| assert.ok(!ignoreChildResult || !tempVar, "Ignoring the result of a child expression but forcing it to " + "be assigned to a temporary variable?"); | ||
| let result = this.explodeExpression(childPath, ignoreChildResult); | ||
| if (ignoreChildResult) ; else if (tempVar || hasLeapingChildren && !types.isLiteral(result)) { | ||
| result = this.emitAssign(tempVar || this.makeTempVar(), result); | ||
| } | ||
| return result; | ||
| } | ||
| explodeExpression(path, ignoreResult) { | ||
| const expr = path.node; | ||
| if (!expr) { | ||
| return expr; | ||
| } | ||
| const self = this; | ||
| let result; | ||
| let after; | ||
| function finish(expr) { | ||
| if (ignoreResult) { | ||
| self.emit(expr); | ||
| } | ||
| return expr; | ||
| } | ||
| if (!containsLeap(expr)) { | ||
| return finish(expr); | ||
| } | ||
| const hasLeapingChildren = containsLeap.onlyChildren(expr); | ||
| switch (path.type) { | ||
| case "MemberExpression": | ||
| return finish(types.memberExpression(self.explodeExpression(path.get("object")), path.node.computed ? self.explodeViaTempVar(null, path.get("property"), hasLeapingChildren) : path.node.property, path.node.computed)); | ||
| case "CallExpression": | ||
| const calleePath = path.get("callee"); | ||
| const argsPath = path.get("arguments"); | ||
| let newCallee; | ||
| let newArgs; | ||
| const hasLeapingArgs = argsPath.some(argPath => containsLeap(argPath.node)); | ||
| let injectFirstArg = null; | ||
| if (types.isMemberExpression(calleePath.node)) { | ||
| if (hasLeapingArgs) { | ||
| const newObject = self.explodeViaTempVar(self.makeTempVar(), calleePath.get("object"), hasLeapingChildren); | ||
| const newProperty = calleePath.node.computed ? self.explodeViaTempVar(null, calleePath.get("property"), hasLeapingChildren) : calleePath.node.property; | ||
| injectFirstArg = newObject; | ||
| newCallee = types.memberExpression(types.memberExpression(types.cloneNode(newObject), newProperty, calleePath.node.computed), types.identifier("call"), false); | ||
| } else { | ||
| newCallee = self.explodeExpression(calleePath); | ||
| } | ||
| } else { | ||
| newCallee = self.explodeViaTempVar(null, calleePath, hasLeapingChildren); | ||
| if (types.isMemberExpression(newCallee)) { | ||
| newCallee = types.sequenceExpression([types.numericLiteral(0), types.cloneNode(newCallee)]); | ||
| } | ||
| } | ||
| if (hasLeapingArgs) { | ||
| newArgs = argsPath.map(argPath => self.explodeViaTempVar(null, argPath, hasLeapingChildren)); | ||
| if (injectFirstArg) newArgs.unshift(injectFirstArg); | ||
| newArgs = newArgs.map(arg => types.cloneNode(arg)); | ||
| } else { | ||
| newArgs = path.node.arguments; | ||
| } | ||
| return finish(types.callExpression(newCallee, newArgs)); | ||
| case "NewExpression": | ||
| return finish(types.newExpression(self.explodeViaTempVar(null, path.get("callee"), hasLeapingChildren), path.get("arguments").map(function (argPath) { | ||
| return self.explodeViaTempVar(null, argPath, hasLeapingChildren); | ||
| }))); | ||
| case "ObjectExpression": | ||
| return finish(types.objectExpression(path.get("properties").map(function (propPath) { | ||
| if (propPath.isObjectProperty()) { | ||
| return types.objectProperty(propPath.node.key, self.explodeViaTempVar(null, propPath.get("value"), hasLeapingChildren), propPath.node.computed); | ||
| } else { | ||
| return propPath.node; | ||
| } | ||
| }))); | ||
| case "ArrayExpression": | ||
| return finish(types.arrayExpression(path.get("elements").map(function (elemPath) { | ||
| if (!elemPath.node) { | ||
| return null; | ||
| } | ||
| if (elemPath.isSpreadElement()) { | ||
| return types.spreadElement(self.explodeViaTempVar(null, elemPath.get("argument"), hasLeapingChildren)); | ||
| } else { | ||
| return self.explodeViaTempVar(null, elemPath, hasLeapingChildren); | ||
| } | ||
| }))); | ||
| case "SequenceExpression": | ||
| const lastIndex = path.node.expressions.length - 1; | ||
| path.get("expressions").forEach(function (exprPath) { | ||
| if (exprPath.key === lastIndex) { | ||
| result = self.explodeExpression(exprPath, ignoreResult); | ||
| } else { | ||
| self.explodeExpression(exprPath, true); | ||
| } | ||
| }); | ||
| return result; | ||
| case "LogicalExpression": | ||
| after = this.loc(); | ||
| if (!ignoreResult) { | ||
| result = self.makeTempVar(); | ||
| } | ||
| const left = self.explodeViaTempVar(result, path.get("left"), hasLeapingChildren); | ||
| if (path.node.operator === "&&") { | ||
| self.jumpIfNot(left, after); | ||
| } else { | ||
| assert.strictEqual(path.node.operator, "||"); | ||
| self.jumpIf(left, after); | ||
| } | ||
| self.explodeViaTempVar(result, path.get("right"), hasLeapingChildren, ignoreResult); | ||
| self.mark(after); | ||
| return result; | ||
| case "ConditionalExpression": | ||
| const elseLoc = this.loc(); | ||
| after = this.loc(); | ||
| const test = self.explodeExpression(path.get("test")); | ||
| self.jumpIfNot(test, elseLoc); | ||
| if (!ignoreResult) { | ||
| result = self.makeTempVar(); | ||
| } | ||
| self.explodeViaTempVar(result, path.get("consequent"), hasLeapingChildren, ignoreResult); | ||
| self.jump(after); | ||
| self.mark(elseLoc); | ||
| self.explodeViaTempVar(result, path.get("alternate"), hasLeapingChildren, ignoreResult); | ||
| self.mark(after); | ||
| return result; | ||
| case "UnaryExpression": | ||
| return finish(types.unaryExpression(path.node.operator, self.explodeExpression(path.get("argument")), !!path.node.prefix)); | ||
| case "BinaryExpression": | ||
| return finish(types.binaryExpression(path.node.operator, self.explodeViaTempVar(null, path.get("left"), hasLeapingChildren), self.explodeViaTempVar(null, path.get("right"), hasLeapingChildren))); | ||
| case "AssignmentExpression": | ||
| if (path.node.operator === "=") { | ||
| return finish(types.assignmentExpression(path.node.operator, self.explodeExpression(path.get("left")), self.explodeExpression(path.get("right")))); | ||
| } | ||
| const lhs = self.explodeExpression(path.get("left")); | ||
| const temp = self.emitAssign(self.makeTempVar(), lhs); | ||
| return finish(types.assignmentExpression("=", types.cloneNode(lhs), types.assignmentExpression(path.node.operator, types.cloneNode(temp), self.explodeExpression(path.get("right"))))); | ||
| case "UpdateExpression": | ||
| return finish(types.updateExpression(path.node.operator, self.explodeExpression(path.get("argument")), path.node.prefix)); | ||
| case "YieldExpression": | ||
| after = this.loc(); | ||
| const arg = path.node.argument && self.explodeExpression(path.get("argument")); | ||
| if (arg && path.node.delegate) { | ||
| { | ||
| const ret = types.returnStatement(types.callExpression(self.contextProperty("d"), [types.callExpression(this.pluginPass.addHelper("regeneratorValues"), [arg]), after])); | ||
| ret.loc = expr.loc; | ||
| self.emit(ret); | ||
| self.mark(after); | ||
| return self.contextProperty("v"); | ||
| } | ||
| } | ||
| self.emitAssign(self.contextProperty("n"), after); | ||
| const ret = types.returnStatement(types.cloneNode(arg) || null); | ||
| ret.loc = expr.loc; | ||
| self.emit(ret); | ||
| self.mark(after); | ||
| return self.contextProperty("v"); | ||
| case "ClassExpression": | ||
| return finish(self.explodeClass(path)); | ||
| default: | ||
| throw new Error("unknown Expression of type " + JSON.stringify(expr.type)); | ||
| } | ||
| } | ||
| explodeClass(path) { | ||
| const explodingChildren = []; | ||
| if (path.node.superClass) { | ||
| explodingChildren.push(path.get("superClass")); | ||
| } | ||
| path.get("body.body").forEach(member => { | ||
| if (member.node.computed) { | ||
| explodingChildren.push(member.get("key")); | ||
| } | ||
| }); | ||
| const hasLeapingChildren = explodingChildren.some(child => containsLeap(child)); | ||
| for (let i = 0; i < explodingChildren.length; i++) { | ||
| const child = explodingChildren[i]; | ||
| const isLast = i === explodingChildren.length - 1; | ||
| if (isLast) { | ||
| child.replaceWith(this.explodeExpression(child)); | ||
| } else { | ||
| child.replaceWith(this.explodeViaTempVar(null, child, hasLeapingChildren)); | ||
| } | ||
| } | ||
| return path.node; | ||
| } | ||
| } | ||
| function replaceShorthandObjectMethod(path) { | ||
| const t = getTypes(); | ||
| if (!path.node || !t.isFunction(path.node)) { | ||
| throw new Error("replaceShorthandObjectMethod can only be called on Function AST node paths."); | ||
| } | ||
| if (!t.isObjectMethod(path.node)) { | ||
| return path; | ||
| } | ||
| if (!path.node.generator) { | ||
| return path; | ||
| } | ||
| const parameters = path.node.params.map(function (param) { | ||
| return t.cloneDeep(param); | ||
| }); | ||
| const functionExpression = t.functionExpression(null, parameters, t.cloneDeep(path.node.body), path.node.generator, path.node.async); | ||
| replaceWithOrRemove(path, t.objectProperty(t.cloneDeep(path.node.key), functionExpression, path.node.computed, false)); | ||
| return path.get("value"); | ||
| } | ||
| const getVisitor = t => ({ | ||
| Method(path, state) { | ||
| const node = path.node; | ||
| if (!shouldRegenerate(node, state)) return; | ||
| const container = t.functionExpression(null, [], t.cloneNode(node.body, false), node.generator, node.async); | ||
| path.get("body").set("body", [t.returnStatement(t.callExpression(container, []))]); | ||
| node.async = false; | ||
| node.generator = false; | ||
| path.get("body.body.0.argument.callee").unwrapFunctionEnvironment(); | ||
| }, | ||
| Function: { | ||
| exit: wrapWithTypes(t, function (path, state) { | ||
| let node = path.node; | ||
| if (!shouldRegenerate(node, state)) return; | ||
| path = replaceShorthandObjectMethod(path); | ||
| node = path.node; | ||
| const contextId = path.scope.generateUidIdentifier("context"); | ||
| const argsId = path.scope.generateUidIdentifier("args"); | ||
| path.ensureBlock(); | ||
| const bodyBlockPath = path.get("body"); | ||
| if (node.async) { | ||
| bodyBlockPath.traverse(awaitVisitor, this); | ||
| } | ||
| bodyBlockPath.traverse(functionSentVisitor, { | ||
| context: contextId, | ||
| pluginPass: this | ||
| }); | ||
| const outerBody = []; | ||
| const innerBody = []; | ||
| bodyBlockPath.get("body").forEach(function (childPath) { | ||
| const node = childPath.node; | ||
| if (t.isExpressionStatement(node) && t.isStringLiteral(node.expression)) { | ||
| outerBody.push(node); | ||
| } else if (node?._blockHoist != null) { | ||
| outerBody.push(node); | ||
| } else { | ||
| innerBody.push(node); | ||
| } | ||
| }); | ||
| if (outerBody.length > 0) { | ||
| bodyBlockPath.node.body = innerBody; | ||
| } | ||
| const outerFnExpr = getOuterFnExpr(this, path); | ||
| t.assertIdentifier(node.id); | ||
| const vars = hoist(path); | ||
| const context = { | ||
| usesThis: false, | ||
| usesArguments: false, | ||
| getArgsId: () => t.clone(argsId) | ||
| }; | ||
| path.traverse(argumentsThisVisitor, context); | ||
| if (context.usesArguments) { | ||
| vars.push(t.variableDeclarator(t.clone(argsId), t.identifier("arguments"))); | ||
| } | ||
| const emitter = new Emitter(contextId, path.scope, vars, this); | ||
| emitter.explode(path.get("body")); | ||
| if (vars.length > 0) { | ||
| outerBody.push(t.variableDeclaration("var", vars)); | ||
| } | ||
| const wrapArgs = [emitter.getContextFunction()]; | ||
| const tryLocsList = emitter.getTryLocsList(); | ||
| if (node.generator) { | ||
| wrapArgs.push(outerFnExpr); | ||
| } else if (context.usesThis || tryLocsList || node.async) { | ||
| wrapArgs.push(t.nullLiteral()); | ||
| } | ||
| if (context.usesThis) { | ||
| wrapArgs.push(t.thisExpression()); | ||
| } else if (tryLocsList || node.async) { | ||
| wrapArgs.push(t.nullLiteral()); | ||
| } | ||
| if (tryLocsList) { | ||
| wrapArgs.push(tryLocsList); | ||
| } else if (node.async) { | ||
| wrapArgs.push(t.nullLiteral()); | ||
| } | ||
| if (node.async) { | ||
| let currentScope = path.scope; | ||
| do { | ||
| if (currentScope.hasOwnBinding("Promise")) currentScope.rename("Promise"); | ||
| } while (currentScope = currentScope.parent); | ||
| wrapArgs.push(t.identifier("Promise")); | ||
| } | ||
| const wrapCall = t.callExpression(!node.async ? t.memberExpression(t.callExpression(this.addHelper("regenerator"), []), t.identifier("w")) : node.generator ? this.addHelper("regeneratorAsyncGen") : this.addHelper("regeneratorAsync"), wrapArgs); | ||
| outerBody.push(t.returnStatement(wrapCall)); | ||
| node.body = t.blockStatement(outerBody); | ||
| path.get("body.body").forEach(p => p.scope.registerDeclaration(p)); | ||
| const oldDirectives = bodyBlockPath.node.directives; | ||
| if (oldDirectives) { | ||
| node.body.directives = oldDirectives; | ||
| } | ||
| const wasGeneratorFunction = node.generator; | ||
| if (wasGeneratorFunction) { | ||
| node.generator = false; | ||
| } | ||
| if (node.async) { | ||
| node.async = false; | ||
| } | ||
| if (wasGeneratorFunction && t.isExpression(node)) { | ||
| replaceWithOrRemove(path, t.callExpression(t.memberExpression(t.callExpression(this.addHelper("regenerator"), []), t.identifier("m")), [node])); | ||
| path.addComment("leading", "#__PURE__"); | ||
| } | ||
| const insertedLocs = emitter.getInsertedLocs(); | ||
| path.traverse({ | ||
| NumericLiteral(path) { | ||
| if (!insertedLocs.has(path.node)) { | ||
| return; | ||
| } | ||
| path.replaceWith(t.numericLiteral(path.node.value)); | ||
| } | ||
| }); | ||
| path.requeue(); | ||
| }) | ||
| } | ||
| }); | ||
| function shouldRegenerate(node, state) { | ||
| if (node.generator) { | ||
| if (node.async) { | ||
| return state.opts.asyncGenerators !== false; | ||
| } else { | ||
| return state.opts.generators !== false; | ||
| } | ||
| } else if (node.async) { | ||
| return state.opts.async !== false; | ||
| } else { | ||
| return false; | ||
| } | ||
| } | ||
| function getOuterFnExpr(state, funPath) { | ||
| const t = getTypes(); | ||
| const node = funPath.node; | ||
| t.assertFunction(node); | ||
| if (!node.id) { | ||
| node.id = funPath.scope.parent.generateUidIdentifier("callee"); | ||
| } | ||
| if (node.generator && t.isFunctionDeclaration(node)) { | ||
| return getMarkedFunctionId(state, funPath); | ||
| } | ||
| return t.clone(node.id); | ||
| } | ||
| const markInfo = new WeakMap(); | ||
| function getMarkInfo(node) { | ||
| if (!markInfo.has(node)) { | ||
| markInfo.set(node, {}); | ||
| } | ||
| return markInfo.get(node); | ||
| } | ||
| function getMarkedFunctionId(state, funPath) { | ||
| const t = getTypes(); | ||
| const node = funPath.node; | ||
| t.assertIdentifier(node.id); | ||
| const blockPath = funPath.findParent(function (path) { | ||
| return path.isProgram() || path.isBlockStatement(); | ||
| }); | ||
| if (!blockPath) { | ||
| return node.id; | ||
| } | ||
| const block = blockPath.node; | ||
| assert.ok(Array.isArray(block.body)); | ||
| const info = getMarkInfo(block); | ||
| if (!info.decl) { | ||
| info.decl = t.variableDeclaration("var", []); | ||
| blockPath.unshiftContainer("body", info.decl); | ||
| info.declPath = blockPath.get("body.0"); | ||
| } | ||
| assert.strictEqual(info.declPath.node, info.decl); | ||
| const markedId = blockPath.scope.generateUidIdentifier("marked"); | ||
| const markCallExp = t.callExpression(t.memberExpression(t.callExpression(state.addHelper("regenerator"), []), t.identifier("m")), [t.clone(node.id)]); | ||
| const index = info.decl.declarations.push(t.variableDeclarator(markedId, markCallExp)) - 1; | ||
| const markCallExpPath = info.declPath.get("declarations." + index + ".init"); | ||
| assert.strictEqual(markCallExpPath.node, markCallExp); | ||
| markCallExpPath.addComment("leading", "#__PURE__"); | ||
| return t.clone(markedId); | ||
| } | ||
| const argumentsThisVisitor = { | ||
| "FunctionExpression|FunctionDeclaration|Method": function (path) { | ||
| path.skip(); | ||
| }, | ||
| Identifier: function (path, state) { | ||
| if (path.node.name === "arguments" && isReference(path)) { | ||
| replaceWithOrRemove(path, state.getArgsId()); | ||
| state.usesArguments = true; | ||
| } | ||
| }, | ||
| ThisExpression: function (path, state) { | ||
| state.usesThis = true; | ||
| } | ||
| }; | ||
| const functionSentVisitor = { | ||
| MetaProperty(path, state) { | ||
| const { | ||
| node | ||
| } = path; | ||
| if (node.meta.name === "function" && node.property.name === "sent") { | ||
| const t = getTypes(); | ||
| replaceWithOrRemove(path, t.memberExpression(t.clone(this.context), t.identifier("v"))); | ||
| } | ||
| } | ||
| }; | ||
| const awaitVisitor = { | ||
| Function: function (path) { | ||
| path.skip(); | ||
| }, | ||
| AwaitExpression: function (path) { | ||
| const t = getTypes(); | ||
| const argument = path.node.argument; | ||
| const helper = this.addHelper("awaitAsyncGenerator"); | ||
| replaceWithOrRemove(path, t.yieldExpression(t.callExpression(helper, [argument]), false)); | ||
| } | ||
| }; | ||
| var index = declare(({ | ||
| types: t, | ||
| traverse, | ||
| assertVersion | ||
| }) => { | ||
| assertVersion("8.0.0-alpha.17"); | ||
| assertVersion("8.0.0-beta.0"); | ||
| return { | ||
| name: "transform-regenerator", | ||
| inherits: regeneratorTransform.default, | ||
| visitor: { | ||
| CallExpression(path) { | ||
| const callee = path.get("callee"); | ||
| if (!callee.isMemberExpression()) return; | ||
| const obj = callee.get("object"); | ||
| if (obj.isIdentifier({ | ||
| name: "regeneratorRuntime" | ||
| })) { | ||
| const helper = this.addHelper("regeneratorRuntime"); | ||
| obj.replaceWith(t.callExpression(helper, [])); | ||
| } | ||
| } | ||
| } | ||
| visitor: getVisitor(t) | ||
| }; | ||
@@ -26,0 +1139,0 @@ }); |
+1
-0
| MIT License | ||
| Copyright (c) 2014-present Sebastian McKenzie and other contributors | ||
| Copyright (c) 2014-present Facebook, Inc. | ||
@@ -5,0 +6,0 @@ Permission is hereby granted, free of charge, to any person obtaining |
+19
-7
@@ -5,3 +5,3 @@ { | ||
| "description": "Explode async and generator functions into a state machine.", | ||
| "version": "8.0.0-alpha.17", | ||
| "version": "8.0.0-beta.0", | ||
| "homepage": "https://babel.dev/docs/en/next/babel-plugin-transform-regenerator", | ||
@@ -15,4 +15,3 @@ "repository": { | ||
| "dependencies": { | ||
| "@babel/helper-plugin-utils": "^8.0.0-alpha.17", | ||
| "regenerator-transform": "^0.15.2" | ||
| "@babel/helper-plugin-utils": "^8.0.0-beta.0" | ||
| }, | ||
@@ -24,10 +23,23 @@ "license": "MIT", | ||
| "peerDependencies": { | ||
| "@babel/core": "^8.0.0-alpha.17" | ||
| "@babel/core": "^8.0.0-beta.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@babel/core": "^8.0.0-alpha.17", | ||
| "@babel/helper-plugin-test-runner": "^8.0.0-alpha.17" | ||
| "@babel/core": "^8.0.0-beta.0", | ||
| "@babel/helper-check-duplicate-nodes": "^8.0.0-beta.0", | ||
| "@babel/helper-plugin-test-runner": "^8.0.0-beta.0", | ||
| "@babel/plugin-proposal-function-sent": "^8.0.0-beta.0", | ||
| "@babel/plugin-transform-arrow-functions": "^8.0.0-beta.0", | ||
| "@babel/plugin-transform-block-scoping": "^8.0.0-beta.0", | ||
| "@babel/plugin-transform-classes": "^8.0.0-beta.0", | ||
| "@babel/plugin-transform-for-of": "^8.0.0-beta.0", | ||
| "@babel/plugin-transform-modules-commonjs": "^8.0.0-beta.0", | ||
| "@babel/plugin-transform-parameters": "^8.0.0-beta.0", | ||
| "@babel/plugin-transform-runtime": "^8.0.0-beta.0", | ||
| "babel-plugin-polyfill-regenerator": "^0.6.1", | ||
| "mocha": "^10.0.0", | ||
| "recast": "^0.23.3", | ||
| "uglify-js": "^3.14.0" | ||
| }, | ||
| "engines": { | ||
| "node": "^18.20.0 || ^20.17.0 || >=22.8.0" | ||
| "node": "^20.19.0 || >=22.12.0" | ||
| }, | ||
@@ -34,0 +46,0 @@ "exports": { |
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
180472
2722.96%2
-33.33%1137
3567.74%15
650%1
Infinity%- Removed
- Removed
- Removed