| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531 | "use strict";Object.defineProperty(exports, "__esModule", {  value: true});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,  assignmentExpression,  binaryExpression,  blockStatement,  callExpression,  conditionalExpression,  expressionStatement,  identifier,  isIdentifier,  jsxIdentifier,  logicalExpression,  LOGICAL_OPERATORS,  memberExpression,  metaProperty,  numericLiteral,  objectExpression,  restElement,  returnStatement,  sequenceExpression,  spreadElement,  stringLiteral,  super: _super,  thisExpression,  toExpression,  unaryExpression} = _t;function toComputedKey() {  let key;  if (this.isMemberExpression()) {    key = this.node.property;  } else if (this.isProperty() || this.isMethod()) {    key = this.node.key;  } else {    throw new ReferenceError("todo");  }  if (!this.node.computed) {    if (isIdentifier(key)) key = stringLiteral(key.name);  }  return key;}function ensureBlock() {  const body = this.get("body");  const bodyNode = body.node;  if (Array.isArray(body)) {    throw new Error("Can't convert array path to a block statement");  }  if (!bodyNode) {    throw new Error("Can't convert node without a body");  }  if (body.isBlockStatement()) {    return bodyNode;  }  const statements = [];  let stringPath = "body";  let key;  let listKey;  if (body.isStatement()) {    listKey = "body";    key = 0;    statements.push(body.node);  } else {    stringPath += ".body.0";    if (this.isFunction()) {      key = "argument";      statements.push(returnStatement(body.node));    } else {      key = "expression";      statements.push(expressionStatement(body.node));    }  }  this.node.body = blockStatement(statements);  const parentPath = this.get(stringPath);  body.setup(parentPath, listKey ? parentPath.node[listKey] : parentPath.node, listKey, key);  return this.node;}function arrowFunctionToShadowed() {  if (!this.isArrowFunctionExpression()) return;  this.arrowFunctionToExpression();}function unwrapFunctionEnvironment() {  if (!this.isArrowFunctionExpression() && !this.isFunctionExpression() && !this.isFunctionDeclaration()) {    throw this.buildCodeFrameError("Can only unwrap the environment of a function.");  }  hoistFunctionEnvironment(this);}function arrowFunctionToExpression({  allowInsertArrow = true,  specCompliant = false,  noNewArrows = !specCompliant} = {}) {  if (!this.isArrowFunctionExpression()) {    throw this.buildCodeFrameError("Cannot convert non-arrow function to a function expression.");  }  const {    thisBinding,    fnPath: fn  } = hoistFunctionEnvironment(this, noNewArrows, allowInsertArrow);  fn.ensureBlock();  fn.node.type = "FunctionExpression";  if (!noNewArrows) {    const checkBinding = thisBinding ? null : fn.scope.generateUidIdentifier("arrowCheckId");    if (checkBinding) {      fn.parentPath.scope.push({        id: checkBinding,        init: objectExpression([])      });    }    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) {  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.isClassMethod({    kind: "constructor"  });  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 {    thisPaths,    argumentsPaths,    newTargetPaths,    superProps,    superCalls  } = getScopeInformation(fnPath);  if (inConstructor && superCalls.length > 0) {    if (!allowInsertArrow) {      throw superCalls[0].buildCodeFrameError("Unable to handle nested super() usage in arrow");    }    const allSuperCalls = [];    thisEnvFn.traverse(getSuperCallsVisitor, {      allSuperCalls    });    const superBinding = getSuperBinding(thisEnvFn);    allSuperCalls.forEach(superCall => {      const callee = identifier(superBinding);      callee.loc = superCall.node.callee.loc;      superCall.get("callee").replaceWith(callee);    });  }  if (argumentsPaths.length > 0) {    const argumentsBinding = getBinding(thisEnvFn, "arguments", () => {      const args = () => identifier("arguments");      if (thisEnvFn.scope.path.isProgram()) {        return conditionalExpression(binaryExpression("===", unaryExpression("typeof", args()), stringLiteral("undefined")), thisEnvFn.scope.buildUndefinedNode(), args());      } else {        return args();      }    });    argumentsPaths.forEach(argumentsChild => {      const argsRef = identifier(argumentsBinding);      argsRef.loc = argumentsChild.node.loc;      argumentsChild.replaceWith(argsRef);    });  }  if (newTargetPaths.length > 0) {    const newTargetBinding = getBinding(thisEnvFn, "newtarget", () => metaProperty(identifier("new"), identifier("target")));    newTargetPaths.forEach(targetChild => {      const targetRef = identifier(newTargetBinding);      targetRef.loc = targetChild.node.loc;      targetChild.replaceWith(targetRef);    });  }  if (superProps.length > 0) {    if (!allowInsertArrow) {      throw superProps[0].buildCodeFrameError("Unable to handle nested super.prop usage");    }    const flatSuperProps = superProps.reduce((acc, superProp) => acc.concat(standardizeSuperProperty(superProp)), []);    flatSuperProps.forEach(superProp => {      const key = superProp.node.computed ? "" : superProp.get("property").node.name;      const isAssignment = superProp.parentPath.isAssignmentExpression({        left: superProp.node      });      const isCall = superProp.parentPath.isCallExpression({        callee: superProp.node      });      const superBinding = getSuperPropBinding(thisEnvFn, isAssignment, key);      const args = [];      if (superProp.node.computed) {        args.push(superProp.get("property").node);      }      if (isAssignment) {        const value = superProp.parentPath.node.right;        args.push(value);      }      const call = callExpression(identifier(superBinding), args);      if (isCall) {        superProp.parentPath.unshiftContainer("arguments", thisExpression());        superProp.replaceWith(memberExpression(call, identifier("call")));        thisPaths.push(superProp.parentPath.get("arguments.0"));      } else if (isAssignment) {        superProp.parentPath.replaceWith(call);      } else {        superProp.replaceWith(call);      }    });  }  let thisBinding;  if (thisPaths.length > 0 || !noNewArrows) {    thisBinding = getThisBinding(thisEnvFn, inConstructor);    if (noNewArrows || inConstructor && hasSuperClass(thisEnvFn)) {      thisPaths.forEach(thisChild => {        const thisRef = thisChild.isJSX() ? jsxIdentifier(thisBinding) : identifier(thisBinding);        thisRef.loc = thisChild.node.loc;        thisChild.replaceWith(thisRef);      });      if (!noNewArrows) thisBinding = null;    }  }  return {    thisBinding,    fnPath  };}function isLogicalOp(op) {  return LOGICAL_OPERATORS.includes(op);}function standardizeSuperProperty(superProp) {  if (superProp.parentPath.isAssignmentExpression() && superProp.parentPath.node.operator !== "=") {    const assignmentPath = superProp.parentPath;    const op = assignmentPath.node.operator.slice(0, -1);    const value = assignmentPath.node.right;    const isLogicalAssignment = isLogicalOp(op);    if (superProp.node.computed) {      const tmp = superProp.scope.generateDeclaredUidIdentifier("tmp");      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 {      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")];  } else if (superProp.parentPath.isUpdateExpression()) {    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(superProp.parentPath.node.operator[0], identifier(tmp.name), numericLiteral(1)))];    if (!superProp.parentPath.node.prefix) {      parts.push(identifier(tmp.name));    }    updateExpr.replaceWith(sequenceExpression(parts));    const left = updateExpr.get("expressions.0.right");    const right = updateExpr.get("expressions.1.left");    return [left, right];  }  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();    thisEnvFn.traverse(assignSuperThisVisitor, {      supers: new WeakSet(),      thisBinding    });  });}function getSuperBinding(thisEnvFn) {  return getBinding(thisEnvFn, "supercall", () => {    const argsBinding = thisEnvFn.scope.generateUidIdentifier("args");    return arrowFunctionExpression([restElement(argsBinding)], callExpression(_super(), [spreadElement(identifier(argsBinding.name))]));  });}function getSuperPropBinding(thisEnvFn, isAssignment, propName) {  const op = isAssignment ? "set" : "get";  return getBinding(thisEnvFn, `superprop_${op}:${propName || ""}`, () => {    const argsList = [];    let fnBody;    if (propName) {      fnBody = memberExpression(_super(), identifier(propName));    } else {      const method = thisEnvFn.scope.generateUidIdentifier("prop");      argsList.unshift(method);      fnBody = memberExpression(_super(), identifier(method.name), true);    }    if (isAssignment) {      const valueIdent = thisEnvFn.scope.generateUidIdentifier("value");      argsList.push(valueIdent);      fnBody = assignmentExpression("=", fnBody, identifier(valueIdent.name));    }    return arrowFunctionExpression(argsList, fnBody);  });}function getBinding(thisEnvFn, key, init) {  const cacheKey = "binding:" + key;  let data = thisEnvFn.getData(cacheKey);  if (!data) {    const id = thisEnvFn.scope.generateUidIdentifier(key);    data = id.name;    thisEnvFn.setData(cacheKey, data);    thisEnvFn.scope.push({      id: id,      init: init(data)    });  }  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(getScopeInformationVisitor, {    thisPaths,    argumentsPaths,    newTargetPaths,    superProps,    superCalls  });  return {    thisPaths,    argumentsPaths,    newTargetPaths,    superProps,    superCalls  };}
 |