You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
3.3 KiB

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