1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = convertFunctionParams;
|
7 |
|
8 | var _core = require("@babel/core");
|
9 |
|
10 | const buildDefaultParam = (0, _core.template)(`
|
11 | let VARIABLE_NAME =
|
12 | arguments.length > ARGUMENT_KEY && arguments[ARGUMENT_KEY] !== undefined ?
|
13 | arguments[ARGUMENT_KEY]
|
14 | :
|
15 | DEFAULT_VALUE;
|
16 | `);
|
17 | const buildLooseDefaultParam = (0, _core.template)(`
|
18 | if (ASSIGNMENT_IDENTIFIER === UNDEFINED) {
|
19 | ASSIGNMENT_IDENTIFIER = DEFAULT_VALUE;
|
20 | }
|
21 | `);
|
22 | const buildLooseDestructuredDefaultParam = (0, _core.template)(`
|
23 | let ASSIGNMENT_IDENTIFIER = PARAMETER_NAME === UNDEFINED ? DEFAULT_VALUE : PARAMETER_NAME ;
|
24 | `);
|
25 | const buildSafeArgumentsAccess = (0, _core.template)(`
|
26 | let $0 = arguments.length > $1 ? arguments[$1] : undefined;
|
27 | `);
|
28 | const iifeVisitor = {
|
29 | "ReferencedIdentifier|BindingIdentifier"(path, state) {
|
30 | const {
|
31 | scope,
|
32 | node
|
33 | } = path;
|
34 | const {
|
35 | name
|
36 | } = node;
|
37 |
|
38 | if (name === "eval" || scope.getBinding(name) === state.scope.parent.getBinding(name) && state.scope.hasOwnBinding(name)) {
|
39 | state.needsOuterBinding = true;
|
40 | path.stop();
|
41 | }
|
42 | },
|
43 |
|
44 | "TypeAnnotation|TSTypeAnnotation|TypeParameterDeclaration|TSTypeParameterDeclaration": path => path.skip()
|
45 | };
|
46 |
|
47 | function convertFunctionParams(path, ignoreFunctionLength, shouldTransformParam, replaceRestElement) {
|
48 | const params = path.get("params");
|
49 | const isSimpleParameterList = params.every(param => param.isIdentifier());
|
50 | if (isSimpleParameterList) return false;
|
51 | const {
|
52 | node,
|
53 | scope
|
54 | } = path;
|
55 | const state = {
|
56 | stop: false,
|
57 | needsOuterBinding: false,
|
58 | scope
|
59 | };
|
60 | const body = [];
|
61 | const shadowedParams = new Set();
|
62 |
|
63 | for (const param of params) {
|
64 | for (const name of Object.keys(param.getBindingIdentifiers())) {
|
65 | var _scope$bindings$name;
|
66 |
|
67 | const constantViolations = (_scope$bindings$name = scope.bindings[name]) == null ? void 0 : _scope$bindings$name.constantViolations;
|
68 |
|
69 | if (constantViolations) {
|
70 | for (const redeclarator of constantViolations) {
|
71 | const node = redeclarator.node;
|
72 |
|
73 | switch (node.type) {
|
74 | case "VariableDeclarator":
|
75 | {
|
76 | if (node.init === null) {
|
77 | const declaration = redeclarator.parentPath;
|
78 |
|
79 | if (!declaration.parentPath.isFor() || declaration.parentPath.get("body") === declaration) {
|
80 | redeclarator.remove();
|
81 | break;
|
82 | }
|
83 | }
|
84 |
|
85 | shadowedParams.add(name);
|
86 | break;
|
87 | }
|
88 |
|
89 | case "FunctionDeclaration":
|
90 | shadowedParams.add(name);
|
91 | break;
|
92 | }
|
93 | }
|
94 | }
|
95 | }
|
96 | }
|
97 |
|
98 | if (shadowedParams.size === 0) {
|
99 | for (const param of params) {
|
100 | if (!param.isIdentifier()) param.traverse(iifeVisitor, state);
|
101 | if (state.needsOuterBinding) break;
|
102 | }
|
103 | }
|
104 |
|
105 | let firstOptionalIndex = null;
|
106 |
|
107 | for (let i = 0; i < params.length; i++) {
|
108 | const param = params[i];
|
109 |
|
110 | if (shouldTransformParam && !shouldTransformParam(i)) {
|
111 | continue;
|
112 | }
|
113 |
|
114 | const transformedRestNodes = [];
|
115 |
|
116 | if (replaceRestElement) {
|
117 | replaceRestElement(param.parentPath, param, transformedRestNodes);
|
118 | }
|
119 |
|
120 | const paramIsAssignmentPattern = param.isAssignmentPattern();
|
121 |
|
122 | if (paramIsAssignmentPattern && (ignoreFunctionLength || node.kind === "set")) {
|
123 | const left = param.get("left");
|
124 | const right = param.get("right");
|
125 | const undefinedNode = scope.buildUndefinedNode();
|
126 |
|
127 | if (left.isIdentifier()) {
|
128 | body.push(buildLooseDefaultParam({
|
129 | ASSIGNMENT_IDENTIFIER: _core.types.cloneNode(left.node),
|
130 | DEFAULT_VALUE: right.node,
|
131 | UNDEFINED: undefinedNode
|
132 | }));
|
133 | param.replaceWith(left.node);
|
134 | } else if (left.isObjectPattern() || left.isArrayPattern()) {
|
135 | const paramName = scope.generateUidIdentifier();
|
136 | body.push(buildLooseDestructuredDefaultParam({
|
137 | ASSIGNMENT_IDENTIFIER: left.node,
|
138 | DEFAULT_VALUE: right.node,
|
139 | PARAMETER_NAME: _core.types.cloneNode(paramName),
|
140 | UNDEFINED: undefinedNode
|
141 | }));
|
142 | param.replaceWith(paramName);
|
143 | }
|
144 | } else if (paramIsAssignmentPattern) {
|
145 | if (firstOptionalIndex === null) firstOptionalIndex = i;
|
146 | const left = param.get("left");
|
147 | const right = param.get("right");
|
148 | const defNode = buildDefaultParam({
|
149 | VARIABLE_NAME: left.node,
|
150 | DEFAULT_VALUE: right.node,
|
151 | ARGUMENT_KEY: _core.types.numericLiteral(i)
|
152 | });
|
153 | body.push(defNode);
|
154 | } else if (firstOptionalIndex !== null) {
|
155 | const defNode = buildSafeArgumentsAccess([param.node, _core.types.numericLiteral(i)]);
|
156 | body.push(defNode);
|
157 | } else if (param.isObjectPattern() || param.isArrayPattern()) {
|
158 | const uid = path.scope.generateUidIdentifier("ref");
|
159 |
|
160 | const defNode = _core.types.variableDeclaration("let", [_core.types.variableDeclarator(param.node, uid)]);
|
161 |
|
162 | body.push(defNode);
|
163 | param.replaceWith(_core.types.cloneNode(uid));
|
164 | }
|
165 |
|
166 | if (transformedRestNodes) {
|
167 | for (const transformedNode of transformedRestNodes) {
|
168 | body.push(transformedNode);
|
169 | }
|
170 | }
|
171 | }
|
172 |
|
173 | if (firstOptionalIndex !== null) {
|
174 | node.params = node.params.slice(0, firstOptionalIndex);
|
175 | }
|
176 |
|
177 | path.ensureBlock();
|
178 |
|
179 | if (state.needsOuterBinding || shadowedParams.size > 0) {
|
180 | body.push(buildScopeIIFE(shadowedParams, path.get("body").node));
|
181 | path.set("body", _core.types.blockStatement(body));
|
182 | const bodyPath = path.get("body.body");
|
183 | const arrowPath = bodyPath[bodyPath.length - 1].get("argument.callee");
|
184 | arrowPath.arrowFunctionToExpression();
|
185 | arrowPath.node.generator = path.node.generator;
|
186 | arrowPath.node.async = path.node.async;
|
187 | path.node.generator = false;
|
188 | } else {
|
189 | path.get("body").unshiftContainer("body", body);
|
190 | }
|
191 |
|
192 | return true;
|
193 | }
|
194 |
|
195 | function buildScopeIIFE(shadowedParams, body) {
|
196 | const args = [];
|
197 | const params = [];
|
198 |
|
199 | for (const name of shadowedParams) {
|
200 | args.push(_core.types.identifier(name));
|
201 | params.push(_core.types.identifier(name));
|
202 | }
|
203 |
|
204 | return _core.types.returnStatement(_core.types.callExpression(_core.types.arrowFunctionExpression(params, body), args));
|
205 | } |
\ | No newline at end of file |