Skip to content

Commit

Permalink
fix: avoid popContext on unvisited node paths (babel#16305)
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung authored and liuxingbaoyu committed Mar 5, 2024
1 parent 8c3b483 commit 9c214e7
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
@@ -0,0 +1,5 @@
async () => do {
await 0
while (0) {}
0
}
@@ -0,0 +1,5 @@
async () => await async function () {
await 0;
while (0) {}
return 0;
}();
11 changes: 7 additions & 4 deletions packages/babel-traverse/src/context.ts
Expand Up @@ -118,9 +118,12 @@ export default class TraversalContext<S = unknown> {

const visited = new WeakSet();
let stop = false;
let visitIndex = 0;

// visit the queue
for (const path of queue) {
for (; visitIndex < queue.length; ) {
const path = queue[visitIndex];
visitIndex++;
path.resync();

if (
Expand Down Expand Up @@ -154,9 +157,9 @@ export default class TraversalContext<S = unknown> {
}
}

// clear queue
for (const path of queue) {
path.popContext();
// pop contexts
for (let i = 0; i < visitIndex; i++) {
queue[i].popContext();
}

// clear queue
Expand Down
38 changes: 38 additions & 0 deletions packages/babel-traverse/test/traverse.js
Expand Up @@ -314,6 +314,44 @@ describe("traverse", function () {
["EXIT", "./Bar"],
]);
});
it("should preserve the context for those nodes that are not visited in sub-traversal", () => {
const code = `{ var first; function second() {} }`;
const ast = parse(code);
let contextLevel;
traverse(
ast,
{
enter(path) {
if (path.isFunctionDeclaration()) {
path.parentPath.traverse(
{
enter(path) {
if (path.isFunctionDeclaration()) {
path.parentPath.traverse(
{
enter(path) {
if (path.isVariableDeclaration()) path.stop();
},
},
{ level: 3 },
);
// the function declaration path should have state.level as 2
// as it is defined within level 2 traversal and the node is
// not visited in the next sub-traversal
contextLevel = path.state.level;
}
},
},
{ level: 2 },
);
}
},
},
undefined,
{ level: 1 },
);
expect(contextLevel).toBe(2);
});
});
describe("path.stop()", () => {
it("should stop the traversal when a grand child is stopped", () => {
Expand Down

0 comments on commit 9c214e7

Please sign in to comment.