index.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = wrapFunction;
  6. var _template = require("@babel/template");
  7. var _t = require("@babel/types");
  8. const {
  9. blockStatement,
  10. callExpression,
  11. functionExpression,
  12. isAssignmentPattern,
  13. isFunctionDeclaration,
  14. isRestElement,
  15. returnStatement,
  16. isCallExpression,
  17. memberExpression,
  18. identifier,
  19. thisExpression,
  20. isPattern
  21. } = _t;
  22. const buildAnonymousExpressionWrapper = _template.default.expression(`
  23. (function () {
  24. var REF = FUNCTION;
  25. return function NAME(PARAMS) {
  26. return REF.apply(this, arguments);
  27. };
  28. })()
  29. `);
  30. const buildNamedExpressionWrapper = _template.default.expression(`
  31. (function () {
  32. var REF = FUNCTION;
  33. function NAME(PARAMS) {
  34. return REF.apply(this, arguments);
  35. }
  36. return NAME;
  37. })()
  38. `);
  39. const buildDeclarationWrapper = _template.default.statements(`
  40. function NAME(PARAMS) { return REF.apply(this, arguments); }
  41. function REF() {
  42. REF = FUNCTION;
  43. return REF.apply(this, arguments);
  44. }
  45. `);
  46. function classOrObjectMethod(path, callId, ignoreFunctionLength) {
  47. const node = path.node;
  48. const body = node.body;
  49. let params = [];
  50. const shoudlForwardParams = node.params.some(p => isPattern(p));
  51. if (shoudlForwardParams) {
  52. params = node.params;
  53. node.params = [];
  54. if (!ignoreFunctionLength) {
  55. for (const param of params) {
  56. if (isAssignmentPattern(param) || isRestElement(param)) {
  57. break;
  58. }
  59. node.params.push(path.scope.generateUidIdentifier("x"));
  60. }
  61. }
  62. }
  63. const container = functionExpression(null, params, blockStatement(body.body), true);
  64. if (shoudlForwardParams) {
  65. body.body = [returnStatement(callExpression(memberExpression(callExpression(callId, [container]), identifier("apply")), [thisExpression(), identifier("arguments")]))];
  66. path.get("body.body.0.argument.callee.object.arguments.0").unwrapFunctionEnvironment();
  67. } else {
  68. body.body = [returnStatement(callExpression(callExpression(callId, [container]), []))];
  69. path.get("body.body.0.argument.callee.arguments.0").unwrapFunctionEnvironment();
  70. }
  71. node.async = false;
  72. node.generator = false;
  73. }
  74. function plainFunction(inPath, callId, noNewArrows, ignoreFunctionLength, hadName) {
  75. let path = inPath;
  76. let node;
  77. let functionId = null;
  78. const nodeParams = inPath.node.params;
  79. if (path.isArrowFunctionExpression()) {
  80. {
  81. var _path$arrowFunctionTo;
  82. path = (_path$arrowFunctionTo = path.arrowFunctionToExpression({
  83. noNewArrows
  84. })) != null ? _path$arrowFunctionTo : path;
  85. }
  86. node = path.node;
  87. } else {
  88. node = path.node;
  89. }
  90. const isDeclaration = isFunctionDeclaration(node);
  91. let built = node;
  92. if (!isCallExpression(node)) {
  93. functionId = node.id;
  94. node.id = null;
  95. node.type = "FunctionExpression";
  96. built = callExpression(callId, [node]);
  97. }
  98. const params = [];
  99. for (const param of nodeParams) {
  100. if (isAssignmentPattern(param) || isRestElement(param)) {
  101. break;
  102. }
  103. params.push(path.scope.generateUidIdentifier("x"));
  104. }
  105. const wrapperArgs = {
  106. NAME: functionId || null,
  107. REF: path.scope.generateUidIdentifier(hadName ? functionId.name : "ref"),
  108. FUNCTION: built,
  109. PARAMS: params
  110. };
  111. if (isDeclaration) {
  112. const container = buildDeclarationWrapper(wrapperArgs);
  113. path.replaceWith(container[0]);
  114. path.insertAfter(container[1]);
  115. } else {
  116. let container;
  117. if (hadName) {
  118. container = buildNamedExpressionWrapper(wrapperArgs);
  119. } else {
  120. container = buildAnonymousExpressionWrapper(wrapperArgs);
  121. }
  122. if (functionId || !ignoreFunctionLength && params.length) {
  123. path.replaceWith(container);
  124. } else {
  125. path.replaceWith(built);
  126. }
  127. }
  128. }
  129. function wrapFunction(path, callId, noNewArrows = true, ignoreFunctionLength = false) {
  130. if (path.isMethod()) {
  131. classOrObjectMethod(path, callId, ignoreFunctionLength);
  132. } else {
  133. const hadName = "id" in path.node && !!path.node.id;
  134. {
  135. var _path, _path$ensureFunctionN;
  136. (_path$ensureFunctionN = (_path = path).ensureFunctionName) != null ? _path$ensureFunctionN : _path.ensureFunctionName = require("@babel/traverse").NodePath.prototype.ensureFunctionName;
  137. }
  138. path = path.ensureFunctionName(false);
  139. plainFunction(path, callId, noNewArrows, ignoreFunctionLength, hadName);
  140. }
  141. }
  142. //# sourceMappingURL=index.js.map