UNPKG

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