[traverse] Allow skipping nodes inserted with .replaceWith() (#9777)
* Avoid regression
This commit is contained in:
parent
b5b8055cc0
commit
43b623c1f1
@ -67,7 +67,12 @@ export function visit(): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.call("enter") || this.shouldSkip) {
|
// Note: We need to check "this.shouldSkip" twice because
|
||||||
|
// the visitor can set it to true. Usually .shouldSkip is false
|
||||||
|
// before calling the enter visitor, but it can be true in case of
|
||||||
|
// a requeued node (e.g. by .replaceWith()) that is then marked
|
||||||
|
// with .skip().
|
||||||
|
if (this.shouldSkip || this.call("enter") || this.shouldSkip) {
|
||||||
this.debug("Skip...");
|
this.debug("Skip...");
|
||||||
return this.shouldStop;
|
return this.shouldStop;
|
||||||
}
|
}
|
||||||
@ -233,6 +238,14 @@ export function setKey(key) {
|
|||||||
export function requeue(pathToQueue = this) {
|
export function requeue(pathToQueue = this) {
|
||||||
if (pathToQueue.removed) return;
|
if (pathToQueue.removed) return;
|
||||||
|
|
||||||
|
// TODO: Uncomment in Babel 8. If a path is skipped, and then replaced with a
|
||||||
|
// new one, the new one shouldn't probably be skipped.
|
||||||
|
// Note that this currently causes an infinite loop because of
|
||||||
|
// packages/babel-plugin-transform-block-scoping/src/tdz.js#L52-L59
|
||||||
|
// (b5b8055cc00756f94bf71deb45f288738520ee3c)
|
||||||
|
//
|
||||||
|
// pathToQueue.shouldSkip = false;
|
||||||
|
|
||||||
// TODO(loganfsmyth): This should be switched back to queue in parent contexts
|
// TODO(loganfsmyth): This should be switched back to queue in parent contexts
|
||||||
// automatically once #2892 and #4135 have been resolved. See #4140.
|
// automatically once #2892 and #4135 have been resolved. See #4140.
|
||||||
// let contexts = this._getQueueContexts();
|
// let contexts = this._getQueueContexts();
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import cloneDeep from "lodash/cloneDeep";
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
import traverse from "../lib";
|
import traverse from "../lib";
|
||||||
import { parse } from "@babel/parser";
|
import { parse } from "@babel/parser";
|
||||||
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
describe("traverse", function() {
|
describe("traverse", function() {
|
||||||
const code = `
|
const code = `
|
||||||
@ -174,4 +175,45 @@ describe("traverse", function() {
|
|||||||
expect(p).not.toBe(scopes[i]);
|
expect(p).not.toBe(scopes[i]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("path.skip()", function() {
|
||||||
|
it("replaced paths can be skipped", function() {
|
||||||
|
const ast = parse("id");
|
||||||
|
|
||||||
|
let skipped;
|
||||||
|
traverse(ast, {
|
||||||
|
noScope: true,
|
||||||
|
Identifier(path) {
|
||||||
|
path.replaceWith(t.numericLiteral(0));
|
||||||
|
path.skip();
|
||||||
|
skipped = true;
|
||||||
|
},
|
||||||
|
NumericLiteral() {
|
||||||
|
skipped = false;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(skipped).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Skipped: see the comment in the `NodePath.requque` method.
|
||||||
|
it.skip("skipped and requeued paths should be visited", function() {
|
||||||
|
const ast = parse("id");
|
||||||
|
|
||||||
|
let visited = false;
|
||||||
|
traverse(ast, {
|
||||||
|
noScope: true,
|
||||||
|
Identifier(path) {
|
||||||
|
path.replaceWith(t.numericLiteral(0));
|
||||||
|
path.skip();
|
||||||
|
path.requeue();
|
||||||
|
},
|
||||||
|
NumericLiteral() {
|
||||||
|
visited = true;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(visited).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user