index.js 2.9 KB

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