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.

119 lines
4.0 KiB

4 years ago
  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) {
  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. }
  53. node.id = null;
  54. if (isDeclaration) {
  55. node.type = "FunctionExpression";
  56. }
  57. const built = t.callExpression(callId, [node]);
  58. const container = wrapper({
  59. NAME: functionId || null,
  60. REF: path.scope.generateUidIdentifier(functionId ? functionId.name : "ref"),
  61. FUNCTION: built,
  62. PARAMS: node.params.reduce((acc, param) => {
  63. acc.done = acc.done || t.isAssignmentPattern(param) || t.isRestElement(param);
  64. if (!acc.done) {
  65. acc.params.push(path.scope.generateUidIdentifier("x"));
  66. }
  67. return acc;
  68. }, {
  69. params: [],
  70. done: false
  71. }).params
  72. });
  73. if (isDeclaration) {
  74. path.replaceWith(container[0]);
  75. path.insertAfter(container[1]);
  76. } else {
  77. const retFunction = container.callee.body.body[1].argument;
  78. if (!functionId) {
  79. (0, _helperFunctionName.default)({
  80. node: retFunction,
  81. parent: path.parent,
  82. scope: path.scope
  83. });
  84. }
  85. if (!retFunction || retFunction.id || node.params.length) {
  86. path.replaceWith(container);
  87. } else {
  88. path.replaceWith(built);
  89. }
  90. }
  91. }
  92. function wrapFunction(path, callId) {
  93. if (path.isClassMethod() || path.isObjectMethod()) {
  94. classOrObjectMethod(path, callId);
  95. } else {
  96. plainFunction(path, callId);
  97. }
  98. }