index.js 2.9 KB

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