@babel/traverse 7.4.4 → 7.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @babel/traverse might be problematic. Click here for more details.
- package/lib/path/context.js +1 -1
- package/lib/path/family.js +53 -1
- package/lib/path/inference/inferer-reference.js +1 -1
- package/lib/path/introspection.js +107 -44
- package/lib/path/modification.js +2 -2
- package/lib/path/replacement.js +8 -0
- package/lib/scope/index.js +1 -5
- package/package.json +7 -7
package/lib/path/context.js
CHANGED
@@ -53,7 +53,7 @@ function _call(fns) {
|
|
53
53
|
const ret = fn.call(this.state, this, this.state);
|
54
54
|
|
55
55
|
if (ret && typeof ret === "object" && typeof ret.then === "function") {
|
56
|
-
throw new Error(`You appear to be using a plugin with an async traversal visitor, ` + `which your current version of Babel does not support
|
56
|
+
throw new Error(`You appear to be using a plugin with an async traversal visitor, ` + `which your current version of Babel does not support. ` + `If you're using a published plugin, you may need to upgrade ` + `your @babel/core version.`);
|
57
57
|
}
|
58
58
|
|
59
59
|
if (ret) {
|
package/lib/path/family.js
CHANGED
@@ -47,6 +47,57 @@ function addCompletionRecords(path, paths) {
|
|
47
47
|
return paths;
|
48
48
|
}
|
49
49
|
|
50
|
+
function completionRecordForSwitch(cases, paths) {
|
51
|
+
let isLastCaseWithConsequent = true;
|
52
|
+
|
53
|
+
for (let i = cases.length - 1; i >= 0; i--) {
|
54
|
+
const switchCase = cases[i];
|
55
|
+
const consequent = switchCase.get("consequent");
|
56
|
+
let breakStatement;
|
57
|
+
|
58
|
+
findBreak: for (const statement of consequent) {
|
59
|
+
if (statement.isBlockStatement()) {
|
60
|
+
for (const statementInBlock of statement.get("body")) {
|
61
|
+
if (statementInBlock.isBreakStatement()) {
|
62
|
+
breakStatement = statementInBlock;
|
63
|
+
break findBreak;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
} else if (statement.isBreakStatement()) {
|
67
|
+
breakStatement = statement;
|
68
|
+
break;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
if (breakStatement) {
|
73
|
+
while (breakStatement.key === 0 && breakStatement.parentPath.isBlockStatement()) {
|
74
|
+
breakStatement = breakStatement.parentPath;
|
75
|
+
}
|
76
|
+
|
77
|
+
const prevSibling = breakStatement.getPrevSibling();
|
78
|
+
|
79
|
+
if (breakStatement.key > 0 && (prevSibling.isExpressionStatement() || prevSibling.isBlockStatement())) {
|
80
|
+
paths = addCompletionRecords(prevSibling, paths);
|
81
|
+
breakStatement.remove();
|
82
|
+
} else {
|
83
|
+
breakStatement.replaceWith(breakStatement.scope.buildUndefinedNode());
|
84
|
+
paths = addCompletionRecords(breakStatement, paths);
|
85
|
+
}
|
86
|
+
} else if (isLastCaseWithConsequent) {
|
87
|
+
const statementFinder = statement => !statement.isBlockStatement() || statement.get("body").some(statementFinder);
|
88
|
+
|
89
|
+
const hasConsequent = consequent.some(statementFinder);
|
90
|
+
|
91
|
+
if (hasConsequent) {
|
92
|
+
paths = addCompletionRecords(consequent[consequent.length - 1], paths);
|
93
|
+
isLastCaseWithConsequent = false;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
return paths;
|
99
|
+
}
|
100
|
+
|
50
101
|
function getCompletionRecords() {
|
51
102
|
let paths = [];
|
52
103
|
|
@@ -62,9 +113,10 @@ function getCompletionRecords() {
|
|
62
113
|
} else if (this.isTryStatement()) {
|
63
114
|
paths = addCompletionRecords(this.get("block"), paths);
|
64
115
|
paths = addCompletionRecords(this.get("handler"), paths);
|
65
|
-
paths = addCompletionRecords(this.get("finalizer"), paths);
|
66
116
|
} else if (this.isCatchClause()) {
|
67
117
|
paths = addCompletionRecords(this.get("body"), paths);
|
118
|
+
} else if (this.isSwitchStatement()) {
|
119
|
+
paths = completionRecordForSwitch(this.get("cases"), paths);
|
68
120
|
} else {
|
69
121
|
paths.push(this);
|
70
122
|
}
|
@@ -69,7 +69,7 @@ function getConstantViolationsBefore(binding, path, functions) {
|
|
69
69
|
|
70
70
|
const status = violation._guessExecutionStatusRelativeTo(path);
|
71
71
|
|
72
|
-
if (functions && status === "
|
72
|
+
if (functions && status === "unknown") functions.push(violation);
|
73
73
|
return status === "before";
|
74
74
|
});
|
75
75
|
}
|
@@ -172,81 +172,144 @@ function willIMaybeExecuteBefore(target) {
|
|
172
172
|
return this._guessExecutionStatusRelativeTo(target) !== "after";
|
173
173
|
}
|
174
174
|
|
175
|
-
function
|
176
|
-
|
177
|
-
|
175
|
+
function getOuterFunction(path) {
|
176
|
+
return (path.scope.getFunctionParent() || path.scope.getProgramParent()).path;
|
177
|
+
}
|
178
178
|
|
179
|
-
|
180
|
-
|
179
|
+
function isExecutionUncertain(type, key) {
|
180
|
+
switch (type) {
|
181
|
+
case "LogicalExpression":
|
182
|
+
return key === "right";
|
181
183
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
184
|
+
case "ConditionalExpression":
|
185
|
+
case "IfStatement":
|
186
|
+
return key === "consequent" || key === "alternate";
|
187
|
+
|
188
|
+
case "WhileStatement":
|
189
|
+
case "DoWhileStatement":
|
190
|
+
case "ForInStatement":
|
191
|
+
case "ForOfStatement":
|
192
|
+
return key === "body";
|
193
|
+
|
194
|
+
case "ForStatement":
|
195
|
+
return key === "body" || key === "update";
|
196
|
+
|
197
|
+
case "SwitchStatement":
|
198
|
+
return key === "cases";
|
199
|
+
|
200
|
+
case "TryStatement":
|
201
|
+
return key === "handler";
|
202
|
+
|
203
|
+
case "AssignmentPattern":
|
204
|
+
return key === "right";
|
205
|
+
|
206
|
+
case "OptionalMemberExpression":
|
207
|
+
return key === "property";
|
208
|
+
|
209
|
+
case "OptionalCallExpression":
|
210
|
+
return key === "arguments";
|
211
|
+
|
212
|
+
default:
|
213
|
+
return false;
|
214
|
+
}
|
215
|
+
}
|
216
|
+
|
217
|
+
function isExecutionUncertainInList(paths, maxIndex) {
|
218
|
+
for (let i = 0; i < maxIndex; i++) {
|
219
|
+
const path = paths[i];
|
220
|
+
|
221
|
+
if (isExecutionUncertain(path.parent.type, path.parentKey)) {
|
222
|
+
return true;
|
186
223
|
}
|
187
224
|
}
|
188
225
|
|
189
|
-
|
190
|
-
|
191
|
-
|
226
|
+
return false;
|
227
|
+
}
|
228
|
+
|
229
|
+
function _guessExecutionStatusRelativeTo(target) {
|
230
|
+
const funcParent = {
|
231
|
+
this: getOuterFunction(this),
|
232
|
+
target: getOuterFunction(target)
|
233
|
+
};
|
234
|
+
|
235
|
+
if (funcParent.target.node !== funcParent.this.node) {
|
236
|
+
return this._guessExecutionStatusRelativeToDifferentFunctions(funcParent.target);
|
237
|
+
}
|
238
|
+
|
239
|
+
const paths = {
|
240
|
+
target: target.getAncestry(),
|
241
|
+
this: this.getAncestry()
|
242
|
+
};
|
243
|
+
if (paths.target.indexOf(this) >= 0) return "after";
|
244
|
+
if (paths.this.indexOf(target) >= 0) return "before";
|
192
245
|
let commonPath;
|
193
|
-
|
194
|
-
|
246
|
+
const commonIndex = {
|
247
|
+
target: 0,
|
248
|
+
this: 0
|
249
|
+
};
|
195
250
|
|
196
|
-
|
197
|
-
const
|
198
|
-
|
251
|
+
while (!commonPath && commonIndex.this < paths.this.length) {
|
252
|
+
const path = paths.this[commonIndex.this];
|
253
|
+
commonIndex.target = paths.target.indexOf(path);
|
199
254
|
|
200
|
-
if (
|
201
|
-
commonPath =
|
202
|
-
|
255
|
+
if (commonIndex.target >= 0) {
|
256
|
+
commonPath = path;
|
257
|
+
} else {
|
258
|
+
commonIndex.this++;
|
203
259
|
}
|
204
260
|
}
|
205
261
|
|
206
262
|
if (!commonPath) {
|
207
|
-
|
263
|
+
throw new Error("Internal Babel error - The two compared nodes" + " don't appear to belong to the same program.");
|
208
264
|
}
|
209
265
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
if (!targetRelationship || !selfRelationship) {
|
214
|
-
return "before";
|
266
|
+
if (isExecutionUncertainInList(paths.this, commonIndex.this - 1) || isExecutionUncertainInList(paths.target, commonIndex.target - 1)) {
|
267
|
+
return "unknown";
|
215
268
|
}
|
216
269
|
|
217
|
-
|
218
|
-
|
270
|
+
const divergence = {
|
271
|
+
this: paths.this[commonIndex.this - 1],
|
272
|
+
target: paths.target[commonIndex.target - 1]
|
273
|
+
};
|
274
|
+
|
275
|
+
if (divergence.target.listKey && divergence.this.listKey && divergence.target.container === divergence.this.container) {
|
276
|
+
return divergence.target.key > divergence.this.key ? "before" : "after";
|
219
277
|
}
|
220
278
|
|
221
279
|
const keys = t().VISITOR_KEYS[commonPath.type];
|
222
|
-
const
|
223
|
-
|
224
|
-
|
280
|
+
const keyPosition = {
|
281
|
+
this: keys.indexOf(divergence.this.parentKey),
|
282
|
+
target: keys.indexOf(divergence.target.parentKey)
|
283
|
+
};
|
284
|
+
return keyPosition.target > keyPosition.this ? "before" : "after";
|
225
285
|
}
|
226
286
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
287
|
+
const executionOrderCheckedNodes = new WeakSet();
|
288
|
+
|
289
|
+
function _guessExecutionStatusRelativeToDifferentFunctions(target) {
|
290
|
+
if (!target.isFunctionDeclaration()) return "unknown";
|
291
|
+
const binding = target.scope.getBinding(target.node.id.name);
|
231
292
|
if (!binding.references) return "before";
|
232
293
|
const referencePaths = binding.referencePaths;
|
294
|
+
let allStatus;
|
233
295
|
|
234
296
|
for (const path of referencePaths) {
|
297
|
+
const childOfFunction = !!path.find(path => path.node === target.node);
|
298
|
+
if (childOfFunction) continue;
|
299
|
+
|
235
300
|
if (path.key !== "callee" || !path.parentPath.isCallExpression()) {
|
236
|
-
return;
|
301
|
+
return "unknown";
|
237
302
|
}
|
238
|
-
}
|
239
303
|
|
240
|
-
|
241
|
-
|
242
|
-
for (const path of referencePaths) {
|
243
|
-
const childOfFunction = !!path.find(path => path.node === targetFuncPath.node);
|
244
|
-
if (childOfFunction) continue;
|
304
|
+
if (executionOrderCheckedNodes.has(path.node)) continue;
|
305
|
+
executionOrderCheckedNodes.add(path.node);
|
245
306
|
|
246
307
|
const status = this._guessExecutionStatusRelativeTo(path);
|
247
308
|
|
248
|
-
|
249
|
-
|
309
|
+
executionOrderCheckedNodes.delete(path.node);
|
310
|
+
|
311
|
+
if (allStatus && allStatus !== status) {
|
312
|
+
return "unknown";
|
250
313
|
} else {
|
251
314
|
allStatus = status;
|
252
315
|
}
|
package/lib/path/modification.js
CHANGED
@@ -44,7 +44,7 @@ function insertBefore(nodes) {
|
|
44
44
|
|
45
45
|
if (parentPath.isExpressionStatement() || parentPath.isLabeledStatement() || parentPath.isExportNamedDeclaration() || parentPath.isExportDefaultDeclaration() && this.isDeclaration()) {
|
46
46
|
return parentPath.insertBefore(nodes);
|
47
|
-
} else if (this.isNodeType("Expression") && this.
|
47
|
+
} else if (this.isNodeType("Expression") && !this.isJSXElement() || parentPath.isForStatement() && this.key === "init") {
|
48
48
|
if (this.node) nodes.push(this.node);
|
49
49
|
return this.replaceExpressionWithStatements(nodes);
|
50
50
|
} else if (Array.isArray(this.container)) {
|
@@ -196,7 +196,7 @@ function unshiftContainer(listKey, nodes) {
|
|
196
196
|
key: 0
|
197
197
|
});
|
198
198
|
|
199
|
-
return path.
|
199
|
+
return path._containerInsertBefore(nodes);
|
200
200
|
}
|
201
201
|
|
202
202
|
function pushContainer(listKey, nodes) {
|
package/lib/path/replacement.js
CHANGED
@@ -206,6 +206,8 @@ function replaceExpressionWithStatements(nodes) {
|
|
206
206
|
return this.replaceWith(toSequenceExpression)[0].get("expressions");
|
207
207
|
}
|
208
208
|
|
209
|
+
const functionParent = this.getFunctionParent();
|
210
|
+
const isParentAsync = functionParent && functionParent.is("async");
|
209
211
|
const container = t().arrowFunctionExpression([], t().blockStatement(nodes));
|
210
212
|
this.replaceWith(t().callExpression(container, []));
|
211
213
|
this.traverse(hoistVariablesVisitor);
|
@@ -235,6 +237,12 @@ function replaceExpressionWithStatements(nodes) {
|
|
235
237
|
|
236
238
|
const callee = this.get("callee");
|
237
239
|
callee.arrowFunctionToExpression();
|
240
|
+
|
241
|
+
if (isParentAsync && _index.default.hasType(this.get("callee.body").node, "AwaitExpression", t().FUNCTION_TYPES)) {
|
242
|
+
callee.set("async", true);
|
243
|
+
this.replaceWith(t().awaitExpression(this.node));
|
244
|
+
}
|
245
|
+
|
238
246
|
return callee.get("body.body");
|
239
247
|
}
|
240
248
|
|
package/lib/scope/index.js
CHANGED
@@ -460,11 +460,7 @@ class Scope {
|
|
460
460
|
}
|
461
461
|
|
462
462
|
buildUndefinedNode() {
|
463
|
-
|
464
|
-
return t().unaryExpression("void", t().numericLiteral(0), true);
|
465
|
-
} else {
|
466
|
-
return t().identifier("undefined");
|
467
|
-
}
|
463
|
+
return t().unaryExpression("void", t().numericLiteral(0), true);
|
468
464
|
}
|
469
465
|
|
470
466
|
registerConstantViolation(path) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@babel/traverse",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.6.0",
|
4
4
|
"description": "The Babel Traverse module maintains the overall tree state, and is responsible for replacing, removing, and adding nodes",
|
5
5
|
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
6
6
|
"homepage": "https://babeljs.io/",
|
@@ -11,18 +11,18 @@
|
|
11
11
|
"repository": "https://github.com/babel/babel/tree/master/packages/babel-traverse",
|
12
12
|
"main": "lib/index.js",
|
13
13
|
"dependencies": {
|
14
|
-
"@babel/code-frame": "^7.
|
15
|
-
"@babel/generator": "^7.
|
14
|
+
"@babel/code-frame": "^7.5.5",
|
15
|
+
"@babel/generator": "^7.6.0",
|
16
16
|
"@babel/helper-function-name": "^7.1.0",
|
17
17
|
"@babel/helper-split-export-declaration": "^7.4.4",
|
18
|
-
"@babel/parser": "^7.
|
19
|
-
"@babel/types": "^7.
|
18
|
+
"@babel/parser": "^7.6.0",
|
19
|
+
"@babel/types": "^7.6.0",
|
20
20
|
"debug": "^4.1.0",
|
21
21
|
"globals": "^11.1.0",
|
22
|
-
"lodash": "^4.17.
|
22
|
+
"lodash": "^4.17.13"
|
23
23
|
},
|
24
24
|
"devDependencies": {
|
25
25
|
"@babel/helper-plugin-test-runner": "^7.0.0"
|
26
26
|
},
|
27
|
-
"gitHead": "
|
27
|
+
"gitHead": "cbd5a26e57758e3f748174ff84aa570e8780e85d"
|
28
28
|
}
|