params.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = convertFunctionParams;
  6. var _core = require("@babel/core");
  7. var _shadowUtils = require("./shadow-utils");
  8. const buildDefaultParam = _core.template.statement(`
  9. let VARIABLE_NAME =
  10. arguments.length > ARGUMENT_KEY && arguments[ARGUMENT_KEY] !== undefined ?
  11. arguments[ARGUMENT_KEY]
  12. :
  13. DEFAULT_VALUE;
  14. `);
  15. const buildLooseDefaultParam = _core.template.statement(`
  16. if (ASSIGNMENT_IDENTIFIER === UNDEFINED) {
  17. ASSIGNMENT_IDENTIFIER = DEFAULT_VALUE;
  18. }
  19. `);
  20. const buildLooseDestructuredDefaultParam = _core.template.statement(`
  21. let ASSIGNMENT_IDENTIFIER = PARAMETER_NAME === UNDEFINED ? DEFAULT_VALUE : PARAMETER_NAME ;
  22. `);
  23. const buildSafeArgumentsAccess = _core.template.statement(`
  24. let $0 = arguments.length > $1 ? arguments[$1] : undefined;
  25. `);
  26. function convertFunctionParams(path, ignoreFunctionLength, shouldTransformParam, replaceRestElement) {
  27. const params = path.get("params");
  28. const isSimpleParameterList = params.every(param => param.isIdentifier());
  29. if (isSimpleParameterList) return false;
  30. const {
  31. node,
  32. scope
  33. } = path;
  34. const body = [];
  35. const shadowedParams = new Set();
  36. for (const param of params) {
  37. (0, _shadowUtils.collectShadowedParamsNames)(param, scope, shadowedParams);
  38. }
  39. const state = {
  40. needsOuterBinding: false,
  41. scope
  42. };
  43. if (shadowedParams.size === 0) {
  44. for (const param of params) {
  45. if (!param.isIdentifier()) param.traverse(_shadowUtils.iifeVisitor, state);
  46. if (state.needsOuterBinding) break;
  47. }
  48. }
  49. let firstOptionalIndex = null;
  50. for (let i = 0; i < params.length; i++) {
  51. const param = params[i];
  52. if (shouldTransformParam && !shouldTransformParam(i)) {
  53. continue;
  54. }
  55. const transformedRestNodes = [];
  56. if (replaceRestElement) {
  57. replaceRestElement(path, param, transformedRestNodes);
  58. }
  59. const paramIsAssignmentPattern = param.isAssignmentPattern();
  60. if (paramIsAssignmentPattern && (ignoreFunctionLength || _core.types.isMethod(node, {
  61. kind: "set"
  62. }))) {
  63. const left = param.get("left");
  64. const right = param.get("right");
  65. const undefinedNode = scope.buildUndefinedNode();
  66. if (left.isIdentifier()) {
  67. body.push(buildLooseDefaultParam({
  68. ASSIGNMENT_IDENTIFIER: _core.types.cloneNode(left.node),
  69. DEFAULT_VALUE: right.node,
  70. UNDEFINED: undefinedNode
  71. }));
  72. param.replaceWith(left.node);
  73. } else if (left.isObjectPattern() || left.isArrayPattern()) {
  74. const paramName = scope.generateUidIdentifier();
  75. body.push(buildLooseDestructuredDefaultParam({
  76. ASSIGNMENT_IDENTIFIER: left.node,
  77. DEFAULT_VALUE: right.node,
  78. PARAMETER_NAME: _core.types.cloneNode(paramName),
  79. UNDEFINED: undefinedNode
  80. }));
  81. param.replaceWith(paramName);
  82. }
  83. } else if (paramIsAssignmentPattern) {
  84. if (firstOptionalIndex === null) firstOptionalIndex = i;
  85. const left = param.get("left");
  86. const right = param.get("right");
  87. const defNode = buildDefaultParam({
  88. VARIABLE_NAME: left.node,
  89. DEFAULT_VALUE: right.node,
  90. ARGUMENT_KEY: _core.types.numericLiteral(i)
  91. });
  92. body.push(defNode);
  93. } else if (firstOptionalIndex !== null) {
  94. const defNode = buildSafeArgumentsAccess([param.node, _core.types.numericLiteral(i)]);
  95. body.push(defNode);
  96. } else if (param.isObjectPattern() || param.isArrayPattern()) {
  97. const uid = path.scope.generateUidIdentifier("ref");
  98. uid.typeAnnotation = param.node.typeAnnotation;
  99. const defNode = _core.types.variableDeclaration("let", [_core.types.variableDeclarator(param.node, uid)]);
  100. body.push(defNode);
  101. param.replaceWith(_core.types.cloneNode(uid));
  102. }
  103. if (transformedRestNodes) {
  104. for (const transformedNode of transformedRestNodes) {
  105. body.push(transformedNode);
  106. }
  107. }
  108. }
  109. if (firstOptionalIndex !== null) {
  110. node.params = node.params.slice(0, firstOptionalIndex);
  111. }
  112. path.ensureBlock();
  113. const {
  114. async,
  115. generator
  116. } = node;
  117. if (generator || state.needsOuterBinding || shadowedParams.size > 0) {
  118. body.push((0, _shadowUtils.buildScopeIIFE)(shadowedParams, path.node.body));
  119. path.set("body", _core.types.blockStatement(body));
  120. const bodyPath = path.get("body.body");
  121. const arrowPath = bodyPath[bodyPath.length - 1].get("argument.callee");
  122. arrowPath.arrowFunctionToExpression();
  123. arrowPath.node.generator = generator;
  124. arrowPath.node.async = async;
  125. node.generator = false;
  126. node.async = false;
  127. if (async) {
  128. path.node.body = _core.template.statement.ast`{
  129. try {
  130. ${path.node.body.body}
  131. } catch (e) {
  132. return Promise.reject(e);
  133. }
  134. }`;
  135. }
  136. } else {
  137. path.get("body").unshiftContainer("body", body);
  138. }
  139. return true;
  140. }
  141. //# sourceMappingURL=params.js.map