index.js 3.8 KB

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