index.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = wrapFunction;
  6. var _helperFunctionName = _interopRequireDefault(require("@babel/helper-function-name"));
  7. var _template = _interopRequireDefault(require("@babel/template"));
  8. var t = _interopRequireWildcard(require("@babel/types"));
  9. function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
  10. 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; }
  11. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  12. const buildAnonymousExpressionWrapper = _template.default.expression(`
  13. (function () {
  14. var REF = FUNCTION;
  15. return function NAME(PARAMS) {
  16. return REF.apply(this, arguments);
  17. };
  18. })()
  19. `);
  20. const buildNamedExpressionWrapper = _template.default.expression(`
  21. (function () {
  22. var REF = FUNCTION;
  23. function NAME(PARAMS) {
  24. return REF.apply(this, arguments);
  25. }
  26. return NAME;
  27. })()
  28. `);
  29. const buildDeclarationWrapper = (0, _template.default)(`
  30. function NAME(PARAMS) { return REF.apply(this, arguments); }
  31. function REF() {
  32. REF = FUNCTION;
  33. return REF.apply(this, arguments);
  34. }
  35. `);
  36. function classOrObjectMethod(path, callId) {
  37. const node = path.node;
  38. const body = node.body;
  39. const container = t.functionExpression(null, [], t.blockStatement(body.body), true);
  40. body.body = [t.returnStatement(t.callExpression(t.callExpression(callId, [container]), []))];
  41. node.async = false;
  42. node.generator = false;
  43. path.get("body.body.0.argument.callee.arguments.0").unwrapFunctionEnvironment();
  44. }
  45. function plainFunction(path, callId, noNewArrows) {
  46. const node = path.node;
  47. const isDeclaration = path.isFunctionDeclaration();
  48. const functionId = node.id;
  49. const wrapper = isDeclaration ? buildDeclarationWrapper : functionId ? buildNamedExpressionWrapper : buildAnonymousExpressionWrapper;
  50. if (path.isArrowFunctionExpression()) {
  51. path.arrowFunctionToExpression({
  52. noNewArrows
  53. });
  54. }
  55. node.id = null;
  56. if (isDeclaration) {
  57. node.type = "FunctionExpression";
  58. }
  59. const built = t.callExpression(callId, [node]);
  60. const container = wrapper({
  61. NAME: functionId || null,
  62. REF: path.scope.generateUidIdentifier(functionId ? functionId.name : "ref"),
  63. FUNCTION: built,
  64. PARAMS: node.params.reduce((acc, param) => {
  65. acc.done = acc.done || t.isAssignmentPattern(param) || t.isRestElement(param);
  66. if (!acc.done) {
  67. acc.params.push(path.scope.generateUidIdentifier("x"));
  68. }
  69. return acc;
  70. }, {
  71. params: [],
  72. done: false
  73. }).params
  74. });
  75. if (isDeclaration) {
  76. path.replaceWith(container[0]);
  77. path.insertAfter(container[1]);
  78. } else {
  79. const retFunction = container.callee.body.body[1].argument;
  80. if (!functionId) {
  81. (0, _helperFunctionName.default)({
  82. node: retFunction,
  83. parent: path.parent,
  84. scope: path.scope
  85. });
  86. }
  87. if (!retFunction || retFunction.id || node.params.length) {
  88. path.replaceWith(container);
  89. } else {
  90. path.replaceWith(built);
  91. }
  92. }
  93. }
  94. function wrapFunction(path, callId, noNewArrows = true) {
  95. if (path.isMethod()) {
  96. classOrObjectMethod(path, callId);
  97. } else {
  98. plainFunction(path, callId, noNewArrows);
  99. }
  100. }