params.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = convertFunctionParams;
  6. function _helperCallDelegate() {
  7. const data = _interopRequireDefault(require("@babel/helper-call-delegate"));
  8. _helperCallDelegate = function () {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _core() {
  14. const data = require("@babel/core");
  15. _core = function () {
  16. return data;
  17. };
  18. return data;
  19. }
  20. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  21. const buildDefaultParam = (0, _core().template)(`
  22. let VARIABLE_NAME =
  23. arguments.length > ARGUMENT_KEY && arguments[ARGUMENT_KEY] !== undefined ?
  24. arguments[ARGUMENT_KEY]
  25. :
  26. DEFAULT_VALUE;
  27. `);
  28. const buildLooseDefaultParam = (0, _core().template)(`
  29. if (ASSIGNMENT_IDENTIFIER === UNDEFINED) {
  30. ASSIGNMENT_IDENTIFIER = DEFAULT_VALUE;
  31. }
  32. `);
  33. const buildLooseDestructuredDefaultParam = (0, _core().template)(`
  34. let ASSIGNMENT_IDENTIFIER = PARAMETER_NAME === UNDEFINED ? DEFAULT_VALUE : PARAMETER_NAME ;
  35. `);
  36. const buildSafeArgumentsAccess = (0, _core().template)(`
  37. let $0 = arguments.length > $1 ? arguments[$1] : undefined;
  38. `);
  39. function isSafeBinding(scope, node) {
  40. if (!scope.hasOwnBinding(node.name)) return true;
  41. const {
  42. kind
  43. } = scope.getOwnBinding(node.name);
  44. return kind === "param" || kind === "local";
  45. }
  46. const iifeVisitor = {
  47. ReferencedIdentifier(path, state) {
  48. const {
  49. scope,
  50. node
  51. } = path;
  52. if (node.name === "eval" || !isSafeBinding(scope, node)) {
  53. state.iife = true;
  54. path.stop();
  55. }
  56. },
  57. Scope(path) {
  58. path.skip();
  59. }
  60. };
  61. function convertFunctionParams(path, loose) {
  62. const {
  63. node,
  64. scope
  65. } = path;
  66. const state = {
  67. iife: false,
  68. scope: scope
  69. };
  70. const body = [];
  71. const params = path.get("params");
  72. let firstOptionalIndex = null;
  73. for (let i = 0; i < params.length; i++) {
  74. const param = params[i];
  75. const paramIsAssignmentPattern = param.isAssignmentPattern();
  76. if (paramIsAssignmentPattern && (loose || node.kind === "set")) {
  77. const left = param.get("left");
  78. const right = param.get("right");
  79. const undefinedNode = scope.buildUndefinedNode();
  80. if (left.isIdentifier()) {
  81. body.push(buildLooseDefaultParam({
  82. ASSIGNMENT_IDENTIFIER: _core().types.cloneNode(left.node),
  83. DEFAULT_VALUE: right.node,
  84. UNDEFINED: undefinedNode
  85. }));
  86. param.replaceWith(left.node);
  87. } else if (left.isObjectPattern() || left.isArrayPattern()) {
  88. const paramName = scope.generateUidIdentifier();
  89. body.push(buildLooseDestructuredDefaultParam({
  90. ASSIGNMENT_IDENTIFIER: left.node,
  91. DEFAULT_VALUE: right.node,
  92. PARAMETER_NAME: _core().types.cloneNode(paramName),
  93. UNDEFINED: undefinedNode
  94. }));
  95. param.replaceWith(paramName);
  96. }
  97. } else if (paramIsAssignmentPattern) {
  98. if (firstOptionalIndex === null) firstOptionalIndex = i;
  99. const left = param.get("left");
  100. const right = param.get("right");
  101. if (!state.iife) {
  102. if (right.isIdentifier() && !isSafeBinding(scope, right.node)) {
  103. state.iife = true;
  104. } else {
  105. right.traverse(iifeVisitor, state);
  106. }
  107. }
  108. const defNode = buildDefaultParam({
  109. VARIABLE_NAME: left.node,
  110. DEFAULT_VALUE: right.node,
  111. ARGUMENT_KEY: _core().types.numericLiteral(i)
  112. });
  113. body.push(defNode);
  114. } else if (firstOptionalIndex !== null) {
  115. const defNode = buildSafeArgumentsAccess([param.node, _core().types.numericLiteral(i)]);
  116. body.push(defNode);
  117. } else if (param.isObjectPattern() || param.isArrayPattern()) {
  118. const uid = path.scope.generateUidIdentifier("ref");
  119. const defNode = _core().types.variableDeclaration("let", [_core().types.variableDeclarator(param.node, uid)]);
  120. body.push(defNode);
  121. param.replaceWith(_core().types.cloneNode(uid));
  122. }
  123. if (!state.iife && !param.isIdentifier()) {
  124. param.traverse(iifeVisitor, state);
  125. }
  126. }
  127. if (body.length === 0) return false;
  128. if (firstOptionalIndex !== null) {
  129. node.params = node.params.slice(0, firstOptionalIndex);
  130. }
  131. path.ensureBlock();
  132. if (state.iife) {
  133. body.push((0, _helperCallDelegate().default)(path, scope));
  134. path.set("body", _core().types.blockStatement(body));
  135. } else {
  136. path.get("body").unshiftContainer("body", body);
  137. }
  138. return true;
  139. }