Skip to content

feat(node): Add AST traversal utilities and expose Node API#1224

Open
marlon-costa-dc wants to merge 1 commit intomozilla:masterfrom
marlon-costa-dc:feature/node-api-extensions
Open

feat(node): Add AST traversal utilities and expose Node API#1224
marlon-costa-dc wants to merge 1 commit intomozilla:masterfrom
marlon-costa-dc:feature/node-api-extensions

Conversation

@marlon-costa-dc
Copy link
Contributor

Summary

Adds utility methods for AST traversal to the Node struct and Search trait:

  • has_ancestor(pred) — Check if any ancestor node matches a predicate (non-recursive, explicit stack)
  • traverse_children(token_list) — Navigate multi-level child paths for finding deeply nested nodes
  • all_occurrences(pred) — Find all descendant nodes matching a predicate (depth-first, extends Search trait)
  • asttools module — Reusable AST traversal utilities (exported as pub mod)
  • pub visibility — Expose Node methods (kind_id, parent, start_row, etc.) for downstream crate usage
  • CppCode getter fix — Fix let-chain pattern to use proper if let with &&

Motivation

These methods support more complex AST analysis patterns needed by downstream crates that use rust-code-analysis as a dependency:

  • Checking node context by examining ancestors (e.g., "is this node inside a class?")
  • Collecting all nodes of a certain type for batch processing
  • Navigating deeply nested AST structures (e.g., finding visibility modifiers through modifier lists)

Implementation Notes

  • has_ancestor uses a generic closure (Fn(&Node) -> bool) for flexible predicates
  • all_occurrences uses fn(u16) -> bool to match existing first_occurrence signature
  • All traversals are non-recursive (explicit stacks) to avoid stack overflow on deep ASTs
  • Single clean commit rebased on upstream/master

Replaces

Replaces #1213 (closed due to messy branch history). Clean single-commit version.

Test Plan

  • cargo check passes
  • All 252 existing tests pass (cargo test --workspace)

@marlon-costa-dc marlon-costa-dc force-pushed the feature/node-api-extensions branch from ceb99b0 to 167bcda Compare February 25, 2026 13:22
@Luni-4
Copy link
Collaborator

Luni-4 commented Feb 25, 2026

@marlon-costa-dc

This CI error should be fixed in another PR, so not blocking for these contributions

Comment on lines +441 to +464
if let Some(declarator) = node.child_by_field_name("declarator")
&& let Some(fd) = declarator.first_occurrence(|id| {
Cpp::FunctionDeclarator == id
|| Cpp::FunctionDeclarator2 == id
|| Cpp::FunctionDeclarator3 == id
}) && let Some(first) = fd.child(0)
{
match first.kind_id().into() {
Cpp::TypeIdentifier
| Cpp::Identifier
| Cpp::FieldIdentifier
| Cpp::DestructorName
| Cpp::OperatorName
| Cpp::QualifiedIdentifier
| Cpp::QualifiedIdentifier2
| Cpp::QualifiedIdentifier3
| Cpp::QualifiedIdentifier4
| Cpp::TemplateFunction
| Cpp::TemplateMethod => {
let code = &code[first.start_byte()..first.end_byte()];
return std::str::from_utf8(code).ok();
}
_ => {}
})
&& let Some(first) = fd.child(0)
{
match first.kind_id().into() {
Cpp::TypeIdentifier
| Cpp::Identifier
| Cpp::FieldIdentifier
| Cpp::DestructorName
| Cpp::OperatorName
| Cpp::QualifiedIdentifier
| Cpp::QualifiedIdentifier2
| Cpp::QualifiedIdentifier3
| Cpp::QualifiedIdentifier4
| Cpp::TemplateFunction
| Cpp::TemplateMethod => {
let code = &code[first.start_byte()..first.end_byte()];
return std::str::from_utf8(code).ok();
}
_ => {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can these changes be moved in another PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants