index.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = simplifyAccess;
  6. var t = require("@babel/types");
  7. function simplifyAccess(path, bindingNames) {
  8. path.traverse(simpleAssignmentVisitor, {
  9. scope: path.scope,
  10. bindingNames,
  11. seen: new WeakSet()
  12. });
  13. }
  14. const simpleAssignmentVisitor = {
  15. UpdateExpression: {
  16. exit(path) {
  17. const {
  18. scope,
  19. bindingNames
  20. } = this;
  21. const arg = path.get("argument");
  22. if (!arg.isIdentifier()) return;
  23. const localName = arg.node.name;
  24. if (!bindingNames.has(localName)) return;
  25. if (scope.getBinding(localName) !== path.scope.getBinding(localName)) {
  26. return;
  27. }
  28. if (path.parentPath.isExpressionStatement() && !path.isCompletionRecord()) {
  29. const operator = path.node.operator == "++" ? "+=" : "-=";
  30. path.replaceWith(t.assignmentExpression(operator, arg.node, t.numericLiteral(1)));
  31. } else if (path.node.prefix) {
  32. path.replaceWith(t.assignmentExpression("=", t.identifier(localName), t.binaryExpression(path.node.operator[0], t.unaryExpression("+", arg.node), t.numericLiteral(1))));
  33. } else {
  34. const old = path.scope.generateUidIdentifierBasedOnNode(arg.node, "old");
  35. const varName = old.name;
  36. path.scope.push({
  37. id: old
  38. });
  39. const binary = t.binaryExpression(path.node.operator[0], t.identifier(varName), t.numericLiteral(1));
  40. path.replaceWith(t.sequenceExpression([t.assignmentExpression("=", t.identifier(varName), t.unaryExpression("+", arg.node)), t.assignmentExpression("=", t.cloneNode(arg.node), binary), t.identifier(varName)]));
  41. }
  42. }
  43. },
  44. AssignmentExpression: {
  45. exit(path) {
  46. const {
  47. scope,
  48. seen,
  49. bindingNames
  50. } = this;
  51. if (path.node.operator === "=") return;
  52. if (seen.has(path.node)) return;
  53. seen.add(path.node);
  54. const left = path.get("left");
  55. if (!left.isIdentifier()) return;
  56. const localName = left.node.name;
  57. if (!bindingNames.has(localName)) return;
  58. if (scope.getBinding(localName) !== path.scope.getBinding(localName)) {
  59. return;
  60. }
  61. path.node.right = t.binaryExpression(path.node.operator.slice(0, -1), t.cloneNode(path.node.left), path.node.right);
  62. path.node.operator = "=";
  63. }
  64. }
  65. };