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.

161 lines
4.1 KiB

4 years ago
  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. function getSpreadLiteral(spread, scope) {
  14. if (loose && !_core.types.isIdentifier(spread.argument, {
  15. name: "arguments"
  16. })) {
  17. return spread.argument;
  18. } else {
  19. return scope.toArray(spread.argument, true);
  20. }
  21. }
  22. function hasSpread(nodes) {
  23. for (let i = 0; i < nodes.length; i++) {
  24. if (_core.types.isSpreadElement(nodes[i])) {
  25. return true;
  26. }
  27. }
  28. return false;
  29. }
  30. function push(_props, nodes) {
  31. if (!_props.length) return _props;
  32. nodes.push(_core.types.arrayExpression(_props));
  33. return [];
  34. }
  35. function build(props, scope) {
  36. const nodes = [];
  37. let _props = [];
  38. for (const prop of props) {
  39. if (_core.types.isSpreadElement(prop)) {
  40. _props = push(_props, nodes);
  41. nodes.push(getSpreadLiteral(prop, scope));
  42. } else {
  43. _props.push(prop);
  44. }
  45. }
  46. push(_props, nodes);
  47. return nodes;
  48. }
  49. return {
  50. name: "transform-spread",
  51. visitor: {
  52. ArrayExpression(path) {
  53. const {
  54. node,
  55. scope
  56. } = path;
  57. const elements = node.elements;
  58. if (!hasSpread(elements)) return;
  59. const nodes = build(elements, scope);
  60. let first = nodes[0];
  61. if (nodes.length === 1 && first !== elements[0].argument) {
  62. path.replaceWith(first);
  63. return;
  64. }
  65. if (!_core.types.isArrayExpression(first)) {
  66. first = _core.types.arrayExpression([]);
  67. } else {
  68. nodes.shift();
  69. }
  70. path.replaceWith(_core.types.callExpression(_core.types.memberExpression(first, _core.types.identifier("concat")), nodes));
  71. },
  72. CallExpression(path) {
  73. const {
  74. node,
  75. scope
  76. } = path;
  77. const args = node.arguments;
  78. if (!hasSpread(args)) return;
  79. const calleePath = path.get("callee");
  80. if (calleePath.isSuper()) return;
  81. let contextLiteral = scope.buildUndefinedNode();
  82. node.arguments = [];
  83. let nodes;
  84. if (args.length === 1 && args[0].argument.name === "arguments") {
  85. nodes = [args[0].argument];
  86. } else {
  87. nodes = build(args, scope);
  88. }
  89. const first = nodes.shift();
  90. if (nodes.length) {
  91. node.arguments.push(_core.types.callExpression(_core.types.memberExpression(first, _core.types.identifier("concat")), nodes));
  92. } else {
  93. node.arguments.push(first);
  94. }
  95. const callee = node.callee;
  96. if (calleePath.isMemberExpression()) {
  97. const temp = scope.maybeGenerateMemoised(callee.object);
  98. if (temp) {
  99. callee.object = _core.types.assignmentExpression("=", temp, callee.object);
  100. contextLiteral = temp;
  101. } else {
  102. contextLiteral = _core.types.cloneNode(callee.object);
  103. }
  104. _core.types.appendToMemberExpression(callee, _core.types.identifier("apply"));
  105. } else {
  106. node.callee = _core.types.memberExpression(node.callee, _core.types.identifier("apply"));
  107. }
  108. if (_core.types.isSuper(contextLiteral)) {
  109. contextLiteral = _core.types.thisExpression();
  110. }
  111. node.arguments.unshift(_core.types.cloneNode(contextLiteral));
  112. },
  113. NewExpression(path) {
  114. const {
  115. node,
  116. scope
  117. } = path;
  118. let args = node.arguments;
  119. if (!hasSpread(args)) return;
  120. const nodes = build(args, scope);
  121. const first = nodes.shift();
  122. if (nodes.length) {
  123. args = _core.types.callExpression(_core.types.memberExpression(first, _core.types.identifier("concat")), nodes);
  124. } else {
  125. args = first;
  126. }
  127. path.replaceWith(_core.types.callExpression(path.hub.addHelper("construct"), [node.callee, args]));
  128. }
  129. }
  130. };
  131. });
  132. exports.default = _default;