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.

135 lines
3.7 KiB

4 years ago
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = memberExpressionToFunctions;
  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. class AssignmentMemoiser {
  10. constructor() {
  11. this._map = new WeakMap();
  12. }
  13. has(key) {
  14. return this._map.has(key);
  15. }
  16. get(key) {
  17. if (!this.has(key)) return;
  18. const record = this._map.get(key);
  19. const {
  20. value
  21. } = record;
  22. record.count--;
  23. if (record.count === 0) {
  24. return t.assignmentExpression("=", value, key);
  25. }
  26. return value;
  27. }
  28. set(key, value, count) {
  29. return this._map.set(key, {
  30. count,
  31. value
  32. });
  33. }
  34. }
  35. const handle = {
  36. memoise() {},
  37. handle(member) {
  38. const {
  39. node,
  40. parent,
  41. parentPath
  42. } = member;
  43. if (parentPath.isUpdateExpression({
  44. argument: node
  45. })) {
  46. const {
  47. operator,
  48. prefix
  49. } = parent;
  50. this.memoise(member, 2);
  51. const value = t.binaryExpression(operator[0], t.unaryExpression("+", this.get(member)), t.numericLiteral(1));
  52. if (prefix) {
  53. parentPath.replaceWith(this.set(member, value));
  54. } else {
  55. const {
  56. scope
  57. } = member;
  58. const ref = scope.generateUidIdentifierBasedOnNode(node);
  59. scope.push({
  60. id: ref
  61. });
  62. value.left = t.assignmentExpression("=", t.cloneNode(ref), value.left);
  63. parentPath.replaceWith(t.sequenceExpression([this.set(member, value), t.cloneNode(ref)]));
  64. }
  65. return;
  66. }
  67. if (parentPath.isAssignmentExpression({
  68. left: node
  69. })) {
  70. const {
  71. operator,
  72. right
  73. } = parent;
  74. let value = right;
  75. if (operator !== "=") {
  76. this.memoise(member, 2);
  77. value = t.binaryExpression(operator.slice(0, -1), this.get(member), value);
  78. }
  79. parentPath.replaceWith(this.set(member, value));
  80. return;
  81. }
  82. if (parentPath.isCallExpression({
  83. callee: node
  84. })) {
  85. const {
  86. arguments: args
  87. } = parent;
  88. parentPath.replaceWith(this.call(member, args));
  89. return;
  90. }
  91. if (parentPath.isObjectProperty({
  92. value: node
  93. }) && parentPath.parentPath.isObjectPattern() || parentPath.isAssignmentPattern({
  94. left: node
  95. }) && parentPath.parentPath.isObjectProperty({
  96. value: parent
  97. }) && parentPath.parentPath.parentPath.isObjectPattern() || parentPath.isArrayPattern() || parentPath.isAssignmentPattern({
  98. left: node
  99. }) && parentPath.parentPath.isArrayPattern() || parentPath.isRestElement()) {
  100. member.replaceWith(this.destructureSet(member));
  101. return;
  102. }
  103. member.replaceWith(this.get(member));
  104. }
  105. };
  106. function memberExpressionToFunctions(path, visitor, state) {
  107. path.traverse(visitor, Object.assign({}, handle, {}, state, {
  108. memoiser: new AssignmentMemoiser()
  109. }));
  110. }