| | |
| | | Object.defineProperty(exports, "__esModule", { |
| | | value: true |
| | | }); |
| | | exports.toComputedKey = toComputedKey; |
| | | exports.ensureBlock = ensureBlock; |
| | | exports.arrowFunctionToShadowed = arrowFunctionToShadowed; |
| | | exports.unwrapFunctionEnvironment = unwrapFunctionEnvironment; |
| | | exports.arrowFunctionToExpression = arrowFunctionToExpression; |
| | | exports.arrowFunctionToShadowed = arrowFunctionToShadowed; |
| | | exports.ensureBlock = ensureBlock; |
| | | exports.toComputedKey = toComputedKey; |
| | | exports.unwrapFunctionEnvironment = unwrapFunctionEnvironment; |
| | | |
| | | var _t = require("@babel/types"); |
| | | |
| | | var _helperEnvironmentVisitor = require("@babel/helper-environment-visitor"); |
| | | |
| | | var _helperFunctionName = require("@babel/helper-function-name"); |
| | | |
| | | var _visitors = require("../visitors"); |
| | | |
| | | const { |
| | | arrowFunctionExpression, |
| | |
| | | identifier, |
| | | isIdentifier, |
| | | jsxIdentifier, |
| | | logicalExpression, |
| | | LOGICAL_OPERATORS, |
| | | memberExpression, |
| | | metaProperty, |
| | | numericLiteral, |
| | |
| | | stringLiteral, |
| | | super: _super, |
| | | thisExpression, |
| | | toExpression, |
| | | unaryExpression |
| | | } = _t; |
| | | |
| | |
| | | throw this.buildCodeFrameError("Cannot convert non-arrow function to a function expression."); |
| | | } |
| | | |
| | | const thisBinding = hoistFunctionEnvironment(this, noNewArrows, allowInsertArrow); |
| | | this.ensureBlock(); |
| | | this.node.type = "FunctionExpression"; |
| | | const { |
| | | thisBinding, |
| | | fnPath: fn |
| | | } = hoistFunctionEnvironment(this, noNewArrows, allowInsertArrow); |
| | | fn.ensureBlock(); |
| | | fn.node.type = "FunctionExpression"; |
| | | |
| | | if (!noNewArrows) { |
| | | const checkBinding = thisBinding ? null : this.parentPath.scope.generateUidIdentifier("arrowCheckId"); |
| | | const checkBinding = thisBinding ? null : fn.scope.generateUidIdentifier("arrowCheckId"); |
| | | |
| | | if (checkBinding) { |
| | | this.parentPath.scope.push({ |
| | | fn.parentPath.scope.push({ |
| | | id: checkBinding, |
| | | init: objectExpression([]) |
| | | }); |
| | | } |
| | | |
| | | this.get("body").unshiftContainer("body", expressionStatement(callExpression(this.hub.addHelper("newArrowCheck"), [thisExpression(), checkBinding ? identifier(checkBinding.name) : identifier(thisBinding)]))); |
| | | this.replaceWith(callExpression(memberExpression((0, _helperFunctionName.default)(this, true) || this.node, identifier("bind")), [checkBinding ? identifier(checkBinding.name) : thisExpression()])); |
| | | fn.get("body").unshiftContainer("body", expressionStatement(callExpression(this.hub.addHelper("newArrowCheck"), [thisExpression(), checkBinding ? identifier(checkBinding.name) : identifier(thisBinding)]))); |
| | | fn.replaceWith(callExpression(memberExpression((0, _helperFunctionName.default)(this, true) || fn.node, identifier("bind")), [checkBinding ? identifier(checkBinding.name) : thisExpression()])); |
| | | } |
| | | } |
| | | |
| | | const getSuperCallsVisitor = (0, _visitors.merge)([{ |
| | | CallExpression(child, { |
| | | allSuperCalls |
| | | }) { |
| | | if (!child.get("callee").isSuper()) return; |
| | | allSuperCalls.push(child); |
| | | } |
| | | |
| | | }, _helperEnvironmentVisitor.default]); |
| | | |
| | | function hoistFunctionEnvironment(fnPath, noNewArrows = true, allowInsertArrow = true) { |
| | | const thisEnvFn = fnPath.findParent(p => { |
| | | return p.isFunction() && !p.isArrowFunctionExpression() || p.isProgram() || p.isClassProperty({ |
| | | let arrowParent; |
| | | let thisEnvFn = fnPath.findParent(p => { |
| | | if (p.isArrowFunctionExpression()) { |
| | | var _arrowParent; |
| | | |
| | | (_arrowParent = arrowParent) != null ? _arrowParent : arrowParent = p; |
| | | return false; |
| | | } |
| | | |
| | | return p.isFunction() || p.isProgram() || p.isClassProperty({ |
| | | static: false |
| | | }) || p.isClassPrivateProperty({ |
| | | static: false |
| | | }); |
| | | }); |
| | | const inConstructor = (thisEnvFn == null ? void 0 : thisEnvFn.node.kind) === "constructor"; |
| | | const inConstructor = thisEnvFn.isClassMethod({ |
| | | kind: "constructor" |
| | | }); |
| | | |
| | | if (thisEnvFn.isClassProperty()) { |
| | | throw fnPath.buildCodeFrameError("Unable to transform arrow inside class property"); |
| | | if (thisEnvFn.isClassProperty() || thisEnvFn.isClassPrivateProperty()) { |
| | | if (arrowParent) { |
| | | thisEnvFn = arrowParent; |
| | | } else if (allowInsertArrow) { |
| | | fnPath.replaceWith(callExpression(arrowFunctionExpression([], toExpression(fnPath.node)), [])); |
| | | thisEnvFn = fnPath.get("callee"); |
| | | fnPath = thisEnvFn.get("body"); |
| | | } else { |
| | | throw fnPath.buildCodeFrameError("Unable to transform arrow inside class property"); |
| | | } |
| | | } |
| | | |
| | | const { |
| | |
| | | } |
| | | |
| | | const allSuperCalls = []; |
| | | thisEnvFn.traverse({ |
| | | Function(child) { |
| | | if (child.isArrowFunctionExpression()) return; |
| | | child.skip(); |
| | | }, |
| | | |
| | | ClassProperty(child) { |
| | | child.skip(); |
| | | }, |
| | | |
| | | CallExpression(child) { |
| | | if (!child.get("callee").isSuper()) return; |
| | | allSuperCalls.push(child); |
| | | } |
| | | |
| | | thisEnvFn.traverse(getSuperCallsVisitor, { |
| | | allSuperCalls |
| | | }); |
| | | const superBinding = getSuperBinding(thisEnvFn); |
| | | allSuperCalls.forEach(superCall => { |
| | |
| | | } |
| | | } |
| | | |
| | | return thisBinding; |
| | | return { |
| | | thisBinding, |
| | | fnPath |
| | | }; |
| | | } |
| | | |
| | | function isLogicalOp(op) { |
| | | return LOGICAL_OPERATORS.includes(op); |
| | | } |
| | | |
| | | function standardizeSuperProperty(superProp) { |
| | |
| | | const assignmentPath = superProp.parentPath; |
| | | const op = assignmentPath.node.operator.slice(0, -1); |
| | | const value = assignmentPath.node.right; |
| | | assignmentPath.node.operator = "="; |
| | | const isLogicalAssignment = isLogicalOp(op); |
| | | |
| | | if (superProp.node.computed) { |
| | | const tmp = superProp.scope.generateDeclaredUidIdentifier("tmp"); |
| | | assignmentPath.get("left").replaceWith(memberExpression(superProp.node.object, assignmentExpression("=", tmp, superProp.node.property), true)); |
| | | assignmentPath.get("right").replaceWith(binaryExpression(op, memberExpression(superProp.node.object, identifier(tmp.name), true), value)); |
| | | const object = superProp.node.object; |
| | | const property = superProp.node.property; |
| | | assignmentPath.get("left").replaceWith(memberExpression(object, assignmentExpression("=", tmp, property), true)); |
| | | assignmentPath.get("right").replaceWith(rightExpression(isLogicalAssignment ? "=" : op, memberExpression(object, identifier(tmp.name), true), value)); |
| | | } else { |
| | | assignmentPath.get("left").replaceWith(memberExpression(superProp.node.object, superProp.node.property)); |
| | | assignmentPath.get("right").replaceWith(binaryExpression(op, memberExpression(superProp.node.object, identifier(superProp.node.property.name)), value)); |
| | | const object = superProp.node.object; |
| | | const property = superProp.node.property; |
| | | assignmentPath.get("left").replaceWith(memberExpression(object, property)); |
| | | assignmentPath.get("right").replaceWith(rightExpression(isLogicalAssignment ? "=" : op, memberExpression(object, identifier(property.name)), value)); |
| | | } |
| | | |
| | | if (isLogicalAssignment) { |
| | | assignmentPath.replaceWith(logicalExpression(op, assignmentPath.node.left, assignmentPath.node.right)); |
| | | } else { |
| | | assignmentPath.node.operator = "="; |
| | | } |
| | | |
| | | return [assignmentPath.get("left"), assignmentPath.get("right").get("left")]; |
| | |
| | | const updateExpr = superProp.parentPath; |
| | | const tmp = superProp.scope.generateDeclaredUidIdentifier("tmp"); |
| | | const computedKey = superProp.node.computed ? superProp.scope.generateDeclaredUidIdentifier("prop") : null; |
| | | const parts = [assignmentExpression("=", tmp, memberExpression(superProp.node.object, computedKey ? assignmentExpression("=", computedKey, superProp.node.property) : superProp.node.property, superProp.node.computed)), assignmentExpression("=", memberExpression(superProp.node.object, computedKey ? identifier(computedKey.name) : superProp.node.property, superProp.node.computed), binaryExpression("+", identifier(tmp.name), numericLiteral(1)))]; |
| | | const parts = [assignmentExpression("=", tmp, memberExpression(superProp.node.object, computedKey ? assignmentExpression("=", computedKey, superProp.node.property) : superProp.node.property, superProp.node.computed)), assignmentExpression("=", memberExpression(superProp.node.object, computedKey ? identifier(computedKey.name) : superProp.node.property, superProp.node.computed), binaryExpression(superProp.parentPath.node.operator[0], identifier(tmp.name), numericLiteral(1)))]; |
| | | |
| | | if (!superProp.parentPath.node.prefix) { |
| | | parts.push(identifier(tmp.name)); |
| | |
| | | } |
| | | |
| | | return [superProp]; |
| | | |
| | | function rightExpression(op, left, right) { |
| | | if (op === "=") { |
| | | return assignmentExpression("=", left, right); |
| | | } else { |
| | | return binaryExpression(op, left, right); |
| | | } |
| | | } |
| | | } |
| | | |
| | | function hasSuperClass(thisEnvFn) { |
| | | return thisEnvFn.isClassMethod() && !!thisEnvFn.parentPath.parentPath.node.superClass; |
| | | } |
| | | |
| | | const assignSuperThisVisitor = (0, _visitors.merge)([{ |
| | | CallExpression(child, { |
| | | supers, |
| | | thisBinding |
| | | }) { |
| | | if (!child.get("callee").isSuper()) return; |
| | | if (supers.has(child.node)) return; |
| | | supers.add(child.node); |
| | | child.replaceWithMultiple([child.node, assignmentExpression("=", identifier(thisBinding), identifier("this"))]); |
| | | } |
| | | |
| | | }, _helperEnvironmentVisitor.default]); |
| | | |
| | | function getThisBinding(thisEnvFn, inConstructor) { |
| | | return getBinding(thisEnvFn, "this", thisBinding => { |
| | | if (!inConstructor || !hasSuperClass(thisEnvFn)) return thisExpression(); |
| | | const supers = new WeakSet(); |
| | | thisEnvFn.traverse({ |
| | | Function(child) { |
| | | if (child.isArrowFunctionExpression()) return; |
| | | child.skip(); |
| | | }, |
| | | |
| | | ClassProperty(child) { |
| | | child.skip(); |
| | | }, |
| | | |
| | | CallExpression(child) { |
| | | if (!child.get("callee").isSuper()) return; |
| | | if (supers.has(child.node)) return; |
| | | supers.add(child.node); |
| | | child.replaceWithMultiple([child.node, assignmentExpression("=", identifier(thisBinding), identifier("this"))]); |
| | | } |
| | | |
| | | thisEnvFn.traverse(assignSuperThisVisitor, { |
| | | supers: new WeakSet(), |
| | | thisBinding |
| | | }); |
| | | }); |
| | | } |
| | |
| | | return data; |
| | | } |
| | | |
| | | const getScopeInformationVisitor = (0, _visitors.merge)([{ |
| | | ThisExpression(child, { |
| | | thisPaths |
| | | }) { |
| | | thisPaths.push(child); |
| | | }, |
| | | |
| | | JSXIdentifier(child, { |
| | | thisPaths |
| | | }) { |
| | | if (child.node.name !== "this") return; |
| | | |
| | | if (!child.parentPath.isJSXMemberExpression({ |
| | | object: child.node |
| | | }) && !child.parentPath.isJSXOpeningElement({ |
| | | name: child.node |
| | | })) { |
| | | return; |
| | | } |
| | | |
| | | thisPaths.push(child); |
| | | }, |
| | | |
| | | CallExpression(child, { |
| | | superCalls |
| | | }) { |
| | | if (child.get("callee").isSuper()) superCalls.push(child); |
| | | }, |
| | | |
| | | MemberExpression(child, { |
| | | superProps |
| | | }) { |
| | | if (child.get("object").isSuper()) superProps.push(child); |
| | | }, |
| | | |
| | | Identifier(child, { |
| | | argumentsPaths |
| | | }) { |
| | | if (!child.isReferencedIdentifier({ |
| | | name: "arguments" |
| | | })) return; |
| | | let curr = child.scope; |
| | | |
| | | do { |
| | | if (curr.hasOwnBinding("arguments")) { |
| | | curr.rename("arguments"); |
| | | return; |
| | | } |
| | | |
| | | if (curr.path.isFunction() && !curr.path.isArrowFunctionExpression()) { |
| | | break; |
| | | } |
| | | } while (curr = curr.parent); |
| | | |
| | | argumentsPaths.push(child); |
| | | }, |
| | | |
| | | MetaProperty(child, { |
| | | newTargetPaths |
| | | }) { |
| | | if (!child.get("meta").isIdentifier({ |
| | | name: "new" |
| | | })) return; |
| | | if (!child.get("property").isIdentifier({ |
| | | name: "target" |
| | | })) return; |
| | | newTargetPaths.push(child); |
| | | } |
| | | |
| | | }, _helperEnvironmentVisitor.default]); |
| | | |
| | | function getScopeInformation(fnPath) { |
| | | const thisPaths = []; |
| | | const argumentsPaths = []; |
| | | const newTargetPaths = []; |
| | | const superProps = []; |
| | | const superCalls = []; |
| | | fnPath.traverse({ |
| | | ClassProperty(child) { |
| | | child.skip(); |
| | | }, |
| | | |
| | | Function(child) { |
| | | if (child.isArrowFunctionExpression()) return; |
| | | child.skip(); |
| | | }, |
| | | |
| | | ThisExpression(child) { |
| | | thisPaths.push(child); |
| | | }, |
| | | |
| | | JSXIdentifier(child) { |
| | | if (child.node.name !== "this") return; |
| | | |
| | | if (!child.parentPath.isJSXMemberExpression({ |
| | | object: child.node |
| | | }) && !child.parentPath.isJSXOpeningElement({ |
| | | name: child.node |
| | | })) { |
| | | return; |
| | | } |
| | | |
| | | thisPaths.push(child); |
| | | }, |
| | | |
| | | CallExpression(child) { |
| | | if (child.get("callee").isSuper()) superCalls.push(child); |
| | | }, |
| | | |
| | | MemberExpression(child) { |
| | | if (child.get("object").isSuper()) superProps.push(child); |
| | | }, |
| | | |
| | | ReferencedIdentifier(child) { |
| | | if (child.node.name !== "arguments") return; |
| | | let curr = child.scope; |
| | | |
| | | do { |
| | | if (curr.hasOwnBinding("arguments")) { |
| | | curr.rename("arguments"); |
| | | return; |
| | | } |
| | | |
| | | if (curr.path.isFunction() && !curr.path.isArrowFunctionExpression()) { |
| | | break; |
| | | } |
| | | } while (curr = curr.parent); |
| | | |
| | | argumentsPaths.push(child); |
| | | }, |
| | | |
| | | MetaProperty(child) { |
| | | if (!child.get("meta").isIdentifier({ |
| | | name: "new" |
| | | })) return; |
| | | if (!child.get("property").isIdentifier({ |
| | | name: "target" |
| | | })) return; |
| | | newTargetPaths.push(child); |
| | | } |
| | | |
| | | fnPath.traverse(getScopeInformationVisitor, { |
| | | thisPaths, |
| | | argumentsPaths, |
| | | newTargetPaths, |
| | | superProps, |
| | | superCalls |
| | | }); |
| | | return { |
| | | thisPaths, |