mirror of https://github.com/astral-sh/ruff
[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:
parent
9d8e35b165
commit
6370aea644
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue