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 | } |
---|