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