Skip to content

Commit d1e4891

Browse files
committed
Pick smaller node ancestors first when descending at offset
1 parent 538ac59 commit d1e4891

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

crates/hir/src/semantics.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,8 @@ impl<'db> SemanticsImpl<'db> {
562562

563563
// Note this return type is deliberate as [`find_nodes_at_offset_with_descend`] wants to stop
564564
// traversing the inner iterator when it finds a node.
565+
// The outer iterator is over the tokens descendants
566+
// The inner iterator is the ancestors of a descendant
565567
fn descend_node_at_offset(
566568
&self,
567569
node: &SyntaxNode,
@@ -570,8 +572,16 @@ impl<'db> SemanticsImpl<'db> {
570572
// Handle macro token cases
571573
node.token_at_offset(offset)
572574
.map(move |token| self.descend_into_macros(token))
573-
.map(|it| it.into_iter().map(move |it| self.token_ancestors_with_macros(it)))
574-
.flatten()
575+
.map(|descendants| {
576+
descendants.into_iter().map(move |it| self.token_ancestors_with_macros(it))
577+
})
578+
// re-order the tokens from token_at_offset by returning the ancestors with the smaller first nodes first
579+
// See algo::ancestors_at_offset, which uses the same approach
580+
.kmerge_by(|left, right| {
581+
left.clone()
582+
.map(|node| node.text_range().len())
583+
.lt(right.clone().map(|node| node.text_range().len()))
584+
})
575585
}
576586

577587
fn original_range(&self, node: &SyntaxNode) -> FileRange {
@@ -589,11 +599,14 @@ impl<'db> SemanticsImpl<'db> {
589599
fn token_ancestors_with_macros(
590600
&self,
591601
token: SyntaxToken,
592-
) -> impl Iterator<Item = SyntaxNode> + '_ {
602+
) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
593603
token.parent().into_iter().flat_map(move |parent| self.ancestors_with_macros(parent))
594604
}
595605

596-
fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
606+
fn ancestors_with_macros(
607+
&self,
608+
node: SyntaxNode,
609+
) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
597610
let node = self.find_file(node);
598611
node.ancestors_with_macros(self.db.upcast()).map(|it| it.value)
599612
}

crates/hir_expand/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ impl InFile<SyntaxNode> {
525525
pub fn ancestors_with_macros(
526526
self,
527527
db: &dyn db::AstDatabase,
528-
) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ {
528+
) -> impl Iterator<Item = InFile<SyntaxNode>> + Clone + '_ {
529529
iter::successors(Some(self), move |node| match node.value.parent() {
530530
Some(parent) => Some(node.with_value(parent)),
531531
None => {

0 commit comments

Comments
 (0)