1 | "use strict";
|
---|
2 |
|
---|
3 | Object.defineProperty(exports, "__esModule", {
|
---|
4 | value: true
|
---|
5 | });
|
---|
6 | exports._replaceWith = _replaceWith;
|
---|
7 | exports.replaceExpressionWithStatements = replaceExpressionWithStatements;
|
---|
8 | exports.replaceInline = replaceInline;
|
---|
9 | exports.replaceWith = replaceWith;
|
---|
10 | exports.replaceWithMultiple = replaceWithMultiple;
|
---|
11 | exports.replaceWithSourceString = replaceWithSourceString;
|
---|
12 | var _codeFrame = require("@babel/code-frame");
|
---|
13 | var _index = require("../index.js");
|
---|
14 | var _index2 = require("./index.js");
|
---|
15 | var _cache = require("../cache.js");
|
---|
16 | var _modification = require("./modification.js");
|
---|
17 | var _parser = require("@babel/parser");
|
---|
18 | var _t = require("@babel/types");
|
---|
19 | const {
|
---|
20 | FUNCTION_TYPES,
|
---|
21 | arrowFunctionExpression,
|
---|
22 | assignmentExpression,
|
---|
23 | awaitExpression,
|
---|
24 | blockStatement,
|
---|
25 | buildUndefinedNode,
|
---|
26 | callExpression,
|
---|
27 | cloneNode,
|
---|
28 | conditionalExpression,
|
---|
29 | expressionStatement,
|
---|
30 | getBindingIdentifiers,
|
---|
31 | identifier,
|
---|
32 | inheritLeadingComments,
|
---|
33 | inheritTrailingComments,
|
---|
34 | inheritsComments,
|
---|
35 | isBlockStatement,
|
---|
36 | isEmptyStatement,
|
---|
37 | isExpression,
|
---|
38 | isExpressionStatement,
|
---|
39 | isIfStatement,
|
---|
40 | isProgram,
|
---|
41 | isStatement,
|
---|
42 | isVariableDeclaration,
|
---|
43 | removeComments,
|
---|
44 | returnStatement,
|
---|
45 | sequenceExpression,
|
---|
46 | validate,
|
---|
47 | yieldExpression
|
---|
48 | } = _t;
|
---|
49 | function replaceWithMultiple(nodes) {
|
---|
50 | var _getCachedPaths;
|
---|
51 | this.resync();
|
---|
52 | nodes = _modification._verifyNodeList.call(this, nodes);
|
---|
53 | inheritLeadingComments(nodes[0], this.node);
|
---|
54 | inheritTrailingComments(nodes[nodes.length - 1], this.node);
|
---|
55 | (_getCachedPaths = (0, _cache.getCachedPaths)(this.hub, this.parent)) == null || _getCachedPaths.delete(this.node);
|
---|
56 | this.node = this.container[this.key] = null;
|
---|
57 | const paths = this.insertAfter(nodes);
|
---|
58 | if (this.node) {
|
---|
59 | this.requeue();
|
---|
60 | } else {
|
---|
61 | this.remove();
|
---|
62 | }
|
---|
63 | return paths;
|
---|
64 | }
|
---|
65 | function replaceWithSourceString(replacement) {
|
---|
66 | this.resync();
|
---|
67 | let ast;
|
---|
68 | try {
|
---|
69 | replacement = `(${replacement})`;
|
---|
70 | ast = (0, _parser.parse)(replacement);
|
---|
71 | } catch (err) {
|
---|
72 | const loc = err.loc;
|
---|
73 | if (loc) {
|
---|
74 | err.message += " - make sure this is an expression.\n" + (0, _codeFrame.codeFrameColumns)(replacement, {
|
---|
75 | start: {
|
---|
76 | line: loc.line,
|
---|
77 | column: loc.column + 1
|
---|
78 | }
|
---|
79 | });
|
---|
80 | err.code = "BABEL_REPLACE_SOURCE_ERROR";
|
---|
81 | }
|
---|
82 | throw err;
|
---|
83 | }
|
---|
84 | const expressionAST = ast.program.body[0].expression;
|
---|
85 | _index.default.removeProperties(expressionAST);
|
---|
86 | return this.replaceWith(expressionAST);
|
---|
87 | }
|
---|
88 | function replaceWith(replacementPath) {
|
---|
89 | this.resync();
|
---|
90 | if (this.removed) {
|
---|
91 | throw new Error("You can't replace this node, we've already removed it");
|
---|
92 | }
|
---|
93 | let replacement = replacementPath instanceof _index2.default ? replacementPath.node : replacementPath;
|
---|
94 | if (!replacement) {
|
---|
95 | throw new Error("You passed `path.replaceWith()` a falsy node, use `path.remove()` instead");
|
---|
96 | }
|
---|
97 | if (this.node === replacement) {
|
---|
98 | return [this];
|
---|
99 | }
|
---|
100 | if (this.isProgram() && !isProgram(replacement)) {
|
---|
101 | throw new Error("You can only replace a Program root node with another Program node");
|
---|
102 | }
|
---|
103 | if (Array.isArray(replacement)) {
|
---|
104 | throw new Error("Don't use `path.replaceWith()` with an array of nodes, use `path.replaceWithMultiple()`");
|
---|
105 | }
|
---|
106 | if (typeof replacement === "string") {
|
---|
107 | throw new Error("Don't use `path.replaceWith()` with a source string, use `path.replaceWithSourceString()`");
|
---|
108 | }
|
---|
109 | let nodePath = "";
|
---|
110 | if (this.isNodeType("Statement") && isExpression(replacement)) {
|
---|
111 | if (!this.canHaveVariableDeclarationOrExpression() && !this.canSwapBetweenExpressionAndStatement(replacement) && !this.parentPath.isExportDefaultDeclaration()) {
|
---|
112 | replacement = expressionStatement(replacement);
|
---|
113 | nodePath = "expression";
|
---|
114 | }
|
---|
115 | }
|
---|
116 | if (this.isNodeType("Expression") && isStatement(replacement)) {
|
---|
117 | if (!this.canHaveVariableDeclarationOrExpression() && !this.canSwapBetweenExpressionAndStatement(replacement)) {
|
---|
118 | return this.replaceExpressionWithStatements([replacement]);
|
---|
119 | }
|
---|
120 | }
|
---|
121 | const oldNode = this.node;
|
---|
122 | if (oldNode) {
|
---|
123 | inheritsComments(replacement, oldNode);
|
---|
124 | removeComments(oldNode);
|
---|
125 | }
|
---|
126 | _replaceWith.call(this, replacement);
|
---|
127 | this.type = replacement.type;
|
---|
128 | this.setScope();
|
---|
129 | this.requeue();
|
---|
130 | return [nodePath ? this.get(nodePath) : this];
|
---|
131 | }
|
---|
132 | function _replaceWith(node) {
|
---|
133 | var _getCachedPaths2;
|
---|
134 | if (!this.container) {
|
---|
135 | throw new ReferenceError("Container is falsy");
|
---|
136 | }
|
---|
137 | if (this.inList) {
|
---|
138 | validate(this.parent, this.key, [node]);
|
---|
139 | } else {
|
---|
140 | validate(this.parent, this.key, node);
|
---|
141 | }
|
---|
142 | this.debug(`Replace with ${node == null ? void 0 : node.type}`);
|
---|
143 | (_getCachedPaths2 = (0, _cache.getCachedPaths)(this.hub, this.parent)) == null || _getCachedPaths2.set(node, this).delete(this.node);
|
---|
144 | this.node = this.container[this.key] = node;
|
---|
145 | }
|
---|
146 | function replaceExpressionWithStatements(nodes) {
|
---|
147 | this.resync();
|
---|
148 | const declars = [];
|
---|
149 | const nodesAsSingleExpression = gatherSequenceExpressions(nodes, declars);
|
---|
150 | if (nodesAsSingleExpression) {
|
---|
151 | for (const id of declars) this.scope.push({
|
---|
152 | id
|
---|
153 | });
|
---|
154 | return this.replaceWith(nodesAsSingleExpression)[0].get("expressions");
|
---|
155 | }
|
---|
156 | const functionParent = this.getFunctionParent();
|
---|
157 | const isParentAsync = functionParent == null ? void 0 : functionParent.is("async");
|
---|
158 | const isParentGenerator = functionParent == null ? void 0 : functionParent.is("generator");
|
---|
159 | const container = arrowFunctionExpression([], blockStatement(nodes));
|
---|
160 | this.replaceWith(callExpression(container, []));
|
---|
161 | const callee = this.get("callee");
|
---|
162 | callee.get("body").scope.hoistVariables(id => this.scope.push({
|
---|
163 | id
|
---|
164 | }));
|
---|
165 | const completionRecords = callee.getCompletionRecords();
|
---|
166 | for (const path of completionRecords) {
|
---|
167 | if (!path.isExpressionStatement()) continue;
|
---|
168 | const loop = path.findParent(path => path.isLoop());
|
---|
169 | if (loop) {
|
---|
170 | let uid = loop.getData("expressionReplacementReturnUid");
|
---|
171 | if (!uid) {
|
---|
172 | uid = callee.scope.generateDeclaredUidIdentifier("ret");
|
---|
173 | callee.get("body").pushContainer("body", returnStatement(cloneNode(uid)));
|
---|
174 | loop.setData("expressionReplacementReturnUid", uid);
|
---|
175 | } else {
|
---|
176 | uid = identifier(uid.name);
|
---|
177 | }
|
---|
178 | path.get("expression").replaceWith(assignmentExpression("=", cloneNode(uid), path.node.expression));
|
---|
179 | } else {
|
---|
180 | path.replaceWith(returnStatement(path.node.expression));
|
---|
181 | }
|
---|
182 | }
|
---|
183 | callee.arrowFunctionToExpression();
|
---|
184 | const newCallee = callee;
|
---|
185 | const needToAwaitFunction = isParentAsync && _index.default.hasType(this.get("callee.body").node, "AwaitExpression", FUNCTION_TYPES);
|
---|
186 | const needToYieldFunction = isParentGenerator && _index.default.hasType(this.get("callee.body").node, "YieldExpression", FUNCTION_TYPES);
|
---|
187 | if (needToAwaitFunction) {
|
---|
188 | newCallee.set("async", true);
|
---|
189 | if (!needToYieldFunction) {
|
---|
190 | this.replaceWith(awaitExpression(this.node));
|
---|
191 | }
|
---|
192 | }
|
---|
193 | if (needToYieldFunction) {
|
---|
194 | newCallee.set("generator", true);
|
---|
195 | this.replaceWith(yieldExpression(this.node, true));
|
---|
196 | }
|
---|
197 | return newCallee.get("body.body");
|
---|
198 | }
|
---|
199 | function gatherSequenceExpressions(nodes, declars) {
|
---|
200 | const exprs = [];
|
---|
201 | let ensureLastUndefined = true;
|
---|
202 | for (const node of nodes) {
|
---|
203 | if (!isEmptyStatement(node)) {
|
---|
204 | ensureLastUndefined = false;
|
---|
205 | }
|
---|
206 | if (isExpression(node)) {
|
---|
207 | exprs.push(node);
|
---|
208 | } else if (isExpressionStatement(node)) {
|
---|
209 | exprs.push(node.expression);
|
---|
210 | } else if (isVariableDeclaration(node)) {
|
---|
211 | if (node.kind !== "var") return;
|
---|
212 | for (const declar of node.declarations) {
|
---|
213 | const bindings = getBindingIdentifiers(declar);
|
---|
214 | for (const key of Object.keys(bindings)) {
|
---|
215 | declars.push(cloneNode(bindings[key]));
|
---|
216 | }
|
---|
217 | if (declar.init) {
|
---|
218 | exprs.push(assignmentExpression("=", declar.id, declar.init));
|
---|
219 | }
|
---|
220 | }
|
---|
221 | ensureLastUndefined = true;
|
---|
222 | } else if (isIfStatement(node)) {
|
---|
223 | const consequent = node.consequent ? gatherSequenceExpressions([node.consequent], declars) : buildUndefinedNode();
|
---|
224 | const alternate = node.alternate ? gatherSequenceExpressions([node.alternate], declars) : buildUndefinedNode();
|
---|
225 | if (!consequent || !alternate) return;
|
---|
226 | exprs.push(conditionalExpression(node.test, consequent, alternate));
|
---|
227 | } else if (isBlockStatement(node)) {
|
---|
228 | const body = gatherSequenceExpressions(node.body, declars);
|
---|
229 | if (!body) return;
|
---|
230 | exprs.push(body);
|
---|
231 | } else if (isEmptyStatement(node)) {
|
---|
232 | if (nodes.indexOf(node) === 0) {
|
---|
233 | ensureLastUndefined = true;
|
---|
234 | }
|
---|
235 | } else {
|
---|
236 | return;
|
---|
237 | }
|
---|
238 | }
|
---|
239 | if (ensureLastUndefined) exprs.push(buildUndefinedNode());
|
---|
240 | if (exprs.length === 1) {
|
---|
241 | return exprs[0];
|
---|
242 | } else {
|
---|
243 | return sequenceExpression(exprs);
|
---|
244 | }
|
---|
245 | }
|
---|
246 | function replaceInline(nodes) {
|
---|
247 | this.resync();
|
---|
248 | if (Array.isArray(nodes)) {
|
---|
249 | if (Array.isArray(this.container)) {
|
---|
250 | nodes = _modification._verifyNodeList.call(this, nodes);
|
---|
251 | const paths = _modification._containerInsertAfter.call(this, nodes);
|
---|
252 | this.remove();
|
---|
253 | return paths;
|
---|
254 | } else {
|
---|
255 | return this.replaceWithMultiple(nodes);
|
---|
256 | }
|
---|
257 | } else {
|
---|
258 | return this.replaceWith(nodes);
|
---|
259 | }
|
---|
260 | }
|
---|
261 |
|
---|
262 | //# sourceMappingURL=replacement.js.map
|
---|