@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.

@@ -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.` + `If you're using a published plugin, you may need to upgrade ` + `your @babel/core version.`);
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) {
@@ -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 === "function") functions.push(violation);
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 _guessExecutionStatusRelativeTo(target) {
176
- const targetFuncParent = target.scope.getFunctionParent() || target.scope.getProgramParent();
177
- const selfFuncParent = this.scope.getFunctionParent() || target.scope.getProgramParent();
175
+ function getOuterFunction(path) {
176
+ return (path.scope.getFunctionParent() || path.scope.getProgramParent()).path;
177
+ }
178
178
 
179
- if (targetFuncParent.node !== selfFuncParent.node) {
180
- const status = this._guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent);
179
+ function isExecutionUncertain(type, key) {
180
+ switch (type) {
181
+ case "LogicalExpression":
182
+ return key === "right";
181
183
 
182
- if (status) {
183
- return status;
184
- } else {
185
- target = targetFuncParent.path;
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
- const targetPaths = target.getAncestry();
190
- if (targetPaths.indexOf(this) >= 0) return "after";
191
- const selfPaths = this.getAncestry();
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
- let targetIndex;
194
- let selfIndex;
246
+ const commonIndex = {
247
+ target: 0,
248
+ this: 0
249
+ };
195
250
 
196
- for (selfIndex = 0; selfIndex < selfPaths.length; selfIndex++) {
197
- const selfPath = selfPaths[selfIndex];
198
- targetIndex = targetPaths.indexOf(selfPath);
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 (targetIndex >= 0) {
201
- commonPath = selfPath;
202
- break;
255
+ if (commonIndex.target >= 0) {
256
+ commonPath = path;
257
+ } else {
258
+ commonIndex.this++;
203
259
  }
204
260
  }
205
261
 
206
262
  if (!commonPath) {
207
- return "before";
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
- const targetRelationship = targetPaths[targetIndex - 1];
211
- const selfRelationship = selfPaths[selfIndex - 1];
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
- if (targetRelationship.listKey && targetRelationship.container === selfRelationship.container) {
218
- return targetRelationship.key > selfRelationship.key ? "before" : "after";
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 targetKeyPosition = keys.indexOf(targetRelationship.key);
223
- const selfKeyPosition = keys.indexOf(selfRelationship.key);
224
- return targetKeyPosition > selfKeyPosition ? "before" : "after";
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
- function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent) {
228
- const targetFuncPath = targetFuncParent.path;
229
- if (!targetFuncPath.isFunctionDeclaration()) return;
230
- const binding = targetFuncPath.scope.getBinding(targetFuncPath.node.id.name);
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
- let allStatus;
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
- if (allStatus) {
249
- if (allStatus !== status) return;
309
+ executionOrderCheckedNodes.delete(path.node);
310
+
311
+ if (allStatus && allStatus !== status) {
312
+ return "unknown";
250
313
  } else {
251
314
  allStatus = status;
252
315
  }
@@ -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.listKey !== "params" && this.listKey !== "arguments" || parentPath.isForStatement() && this.key === "init") {
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.insertBefore(nodes);
199
+ return path._containerInsertBefore(nodes);
200
200
  }
201
201
 
202
202
  function pushContainer(listKey, nodes) {
@@ -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
 
@@ -460,11 +460,7 @@ class Scope {
460
460
  }
461
461
 
462
462
  buildUndefinedNode() {
463
- if (this.hasBinding("undefined")) {
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.4.4",
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.0.0",
15
- "@babel/generator": "^7.4.4",
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.4.4",
19
- "@babel/types": "^7.4.4",
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.11"
22
+ "lodash": "^4.17.13"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@babel/helper-plugin-test-runner": "^7.0.0"
26
26
  },
27
- "gitHead": "2c88694388831b1e5b88e4bbed6781eb2be1edba"
27
+ "gitHead": "cbd5a26e57758e3f748174ff84aa570e8780e85d"
28
28
  }