index.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _helperPluginUtils = require("@babel/helper-plugin-utils");
  7. var _core = require("@babel/core");
  8. var _default = (0, _helperPluginUtils.declare)((api, options) => {
  9. api.assertVersion(7);
  10. const {
  11. loose
  12. } = options;
  13. const pushComputedProps = loose ? pushComputedPropsLoose : pushComputedPropsSpec;
  14. const buildMutatorMapAssign = (0, _core.template)(`
  15. MUTATOR_MAP_REF[KEY] = MUTATOR_MAP_REF[KEY] || {};
  16. MUTATOR_MAP_REF[KEY].KIND = VALUE;
  17. `);
  18. function getValue(prop) {
  19. if (_core.types.isObjectProperty(prop)) {
  20. return prop.value;
  21. } else if (_core.types.isObjectMethod(prop)) {
  22. return _core.types.functionExpression(null, prop.params, prop.body, prop.generator, prop.async);
  23. }
  24. }
  25. function pushAssign(objId, prop, body) {
  26. if (prop.kind === "get" && prop.kind === "set") {
  27. pushMutatorDefine(objId, prop, body);
  28. } else {
  29. body.push(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.memberExpression(_core.types.cloneNode(objId), prop.key, prop.computed || _core.types.isLiteral(prop.key)), getValue(prop))));
  30. }
  31. }
  32. function pushMutatorDefine({
  33. body,
  34. getMutatorId,
  35. scope
  36. }, prop) {
  37. let key = !prop.computed && _core.types.isIdentifier(prop.key) ? _core.types.stringLiteral(prop.key.name) : prop.key;
  38. const maybeMemoise = scope.maybeGenerateMemoised(key);
  39. if (maybeMemoise) {
  40. body.push(_core.types.expressionStatement(_core.types.assignmentExpression("=", maybeMemoise, key)));
  41. key = maybeMemoise;
  42. }
  43. body.push(...buildMutatorMapAssign({
  44. MUTATOR_MAP_REF: getMutatorId(),
  45. KEY: _core.types.cloneNode(key),
  46. VALUE: getValue(prop),
  47. KIND: _core.types.identifier(prop.kind)
  48. }));
  49. }
  50. function pushComputedPropsLoose(info) {
  51. for (const prop of info.computedProps) {
  52. if (prop.kind === "get" || prop.kind === "set") {
  53. pushMutatorDefine(info, prop);
  54. } else {
  55. pushAssign(_core.types.cloneNode(info.objId), prop, info.body);
  56. }
  57. }
  58. }
  59. function pushComputedPropsSpec(info) {
  60. const {
  61. objId,
  62. body,
  63. computedProps,
  64. state
  65. } = info;
  66. for (const prop of computedProps) {
  67. const key = _core.types.toComputedKey(prop);
  68. if (prop.kind === "get" || prop.kind === "set") {
  69. pushMutatorDefine(info, prop);
  70. } else if (_core.types.isStringLiteral(key, {
  71. value: "__proto__"
  72. })) {
  73. pushAssign(objId, prop, body);
  74. } else {
  75. if (computedProps.length === 1) {
  76. return _core.types.callExpression(state.addHelper("defineProperty"), [info.initPropExpression, key, getValue(prop)]);
  77. } else {
  78. body.push(_core.types.expressionStatement(_core.types.callExpression(state.addHelper("defineProperty"), [_core.types.cloneNode(objId), key, getValue(prop)])));
  79. }
  80. }
  81. }
  82. }
  83. return {
  84. name: "transform-computed-properties",
  85. visitor: {
  86. ObjectExpression: {
  87. exit(path, state) {
  88. const {
  89. node,
  90. parent,
  91. scope
  92. } = path;
  93. let hasComputed = false;
  94. for (const prop of node.properties) {
  95. hasComputed = prop.computed === true;
  96. if (hasComputed) break;
  97. }
  98. if (!hasComputed) return;
  99. const initProps = [];
  100. const computedProps = [];
  101. let foundComputed = false;
  102. for (const prop of node.properties) {
  103. if (prop.computed) {
  104. foundComputed = true;
  105. }
  106. if (foundComputed) {
  107. computedProps.push(prop);
  108. } else {
  109. initProps.push(prop);
  110. }
  111. }
  112. const objId = scope.generateUidIdentifierBasedOnNode(parent);
  113. const initPropExpression = _core.types.objectExpression(initProps);
  114. const body = [];
  115. body.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(objId, initPropExpression)]));
  116. let mutatorRef;
  117. const getMutatorId = function () {
  118. if (!mutatorRef) {
  119. mutatorRef = scope.generateUidIdentifier("mutatorMap");
  120. body.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(mutatorRef, _core.types.objectExpression([]))]));
  121. }
  122. return _core.types.cloneNode(mutatorRef);
  123. };
  124. const single = pushComputedProps({
  125. scope,
  126. objId,
  127. body,
  128. computedProps,
  129. initPropExpression,
  130. getMutatorId,
  131. state
  132. });
  133. if (mutatorRef) {
  134. body.push(_core.types.expressionStatement(_core.types.callExpression(state.addHelper("defineEnumerableProperties"), [_core.types.cloneNode(objId), _core.types.cloneNode(mutatorRef)])));
  135. }
  136. if (single) {
  137. path.replaceWith(single);
  138. } else {
  139. body.push(_core.types.expressionStatement(_core.types.cloneNode(objId)));
  140. path.replaceWithMultiple(body);
  141. }
  142. }
  143. }
  144. }
  145. };
  146. });
  147. exports.default = _default;