Skip to content

feat(ast_visit): add walk_children_* methods #12643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

overlookmotel
Copy link
Member

@overlookmotel overlookmotel commented Jul 30, 2025

Implementation of first suggested solution from #12641.

Split out walking children of AST nodes into separate walk_children_* functions. e.g.:

pub fn walk_block_statement<'a, V: Visit<'a>>(visitor: &mut V, it: &BlockStatement<'a>) {
    let kind = AstKind::BlockStatement(visitor.alloc(it));
    visitor.enter_node(kind);
    walk_children_block_statement(visitor, it);
    visitor.leave_node(kind);
}

pub fn walk_children_block_statement<'a, V: Visit<'a>>(visitor: &mut V, it: &BlockStatement<'a>) {
    visitor.enter_scope(ScopeFlags::empty(), &it.scope_id);
    visitor.visit_span(&it.span);
    visitor.visit_statements(&it.body);
    visitor.leave_scope();
}

Enter/leave scope

enter_scope and leave_scope calls are in walk_children_*, not in walk_*. So if you need some code to run after enter_scope, you'd still need to copy the code from walk_children_* into your Visit::visit_* impl.

Reason is that some AST types enter the scope late, or exit it early. e.g.:

pub struct TSConditionalType<'a> {
pub span: Span,
/// The type before `extends` in the test expression.
pub check_type: TSType<'a>,
/// The type `check_type` is being tested against.
#[scope(enter_before)]
pub extends_type: TSType<'a>,
/// The type evaluated to if the test is true.
pub true_type: TSType<'a>,
/// The type evaluated to if the test is false.
#[scope(exit_before)]
pub false_type: TSType<'a>,
pub scope_id: Cell<Option<ScopeId>>,
}

Therefore it's not possible to have enter_scope + leave_scope calls in walk_* functions for all types. I think it'd be confusing if they were in some walk_* functions, but not in others, so have opted not to have them in any walk_* functions for consistency.

Most AST types don't have scopes, so hopefully the walk_children_* functions will still be useful in majority of cases.

Structs only

Only structs have walk_children_* functions, because once changes to AstKind are complete (#11490), no enums will have an AstKind. So walk_* and walk_children_* functions would be equivalent for all enums.

@github-actions github-actions bot added A-ast-tools Area - AST tools C-enhancement Category - New feature or request labels Jul 30, 2025
Copy link
Member Author


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link

codspeed-hq bot commented Jul 30, 2025

CodSpeed Instrumentation Performance Report

Merging #12643 will not alter performance

Comparing 07-30-feat_ast_visit_add_walk_children__methods (b6dc7f9) with main (763a618)

Summary

✅ 34 untouched benchmarks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ast-tools Area - AST tools C-enhancement Category - New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant