[ty_test] Fix find_covering_node to correctly find minimal node

The previous implementation had a bug: it would overwrite `found` for
every matching node in source order, which could incorrectly select a
sibling node instead of the minimal covering node.

Now use the same approach as ty_ide's covering_node:
- Use leave_node() to detect when we've finished traversing a subtree
- Set a `found` flag when leaving the minimal node to prevent further
  updates
- This ensures we return the deepest (most specific) node that covers
  the offset, not just the last one visited in source order

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Douglas Creager 2025-10-08 12:53:06 -04:00
parent 9d8e35b165
commit 6370aea644
1 changed files with 17 additions and 5 deletions

View File

@ -20,27 +20,39 @@ use crate::db::Db;
fn find_covering_node<'a>(root: AnyNodeRef<'a>, offset: TextSize) -> Option<AnyNodeRef<'a>> {
struct Visitor<'a> {
offset: TextSize,
found: Option<AnyNodeRef<'a>>,
found: bool,
minimal_node: Option<AnyNodeRef<'a>>,
}
impl<'a> SourceOrderVisitor<'a> for Visitor<'a> {
fn enter_node(&mut self, node: AnyNodeRef<'a>) -> TraversalSignal {
if node.range().contains(self.offset) {
self.found = Some(node);
if !self.found && node.range().contains(self.offset) {
// This node contains the offset. Save it and traverse into children
// to find a more specific node.
self.minimal_node = Some(node);
TraversalSignal::Traverse
} else {
TraversalSignal::Skip
}
}
fn leave_node(&mut self, node: AnyNodeRef<'a>) {
// If we're leaving a node that we saved, and we haven't found a more
// specific child, then this is the minimal covering node.
if !self.found && self.minimal_node == Some(node) {
self.found = true;
}
}
}
let mut visitor = Visitor {
offset,
found: None,
found: false,
minimal_node: None,
};
root.visit_source_order(&mut visitor);
visitor.found
visitor.minimal_node
}
/// Get the inferred type at a given position in a file.