Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
async () => do {
await 0
while (0) {}
0
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the main branch the contextLevel is 1, which is incorrect since Babel leaks the outer context to the inner sub-traversal.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

}
},
},
{ 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