Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit f74ef3a

Browse files
committed
properly sort changes by depth to sort between nodes that have the same start range
1 parent f08299f commit f74ef3a

File tree

1 file changed

+19
-4
lines changed
  • src/tools/rust-analyzer/crates/syntax/src/syntax_editor

1 file changed

+19
-4
lines changed

src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{collections::VecDeque, ops::RangeInclusive};
1+
use std::{cmp::Ordering, collections::VecDeque, ops::RangeInclusive};
22

33
use rowan::TextRange;
44
use rustc_hash::FxHashMap;
@@ -30,14 +30,29 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
3030

3131
let SyntaxEditor { root, mut changes, mappings, annotations } = editor;
3232

33-
// Sort changes by range then change kind, so that we can:
33+
let mut node_depths = FxHashMap::<SyntaxNode, usize>::default();
34+
let mut get_node_depth = |node: SyntaxNode| {
35+
*node_depths.entry(node).or_insert_with_key(|node| node.ancestors().count())
36+
};
37+
38+
// Sort changes by range, then depth, then change kind, so that we can:
3439
// - ensure that parent edits are ordered before child edits
3540
// - ensure that inserts will be guaranteed to be inserted at the right range
3641
// - easily check for disjoint replace ranges
3742
changes.sort_by(|a, b| {
3843
a.target_range()
3944
.start()
4045
.cmp(&b.target_range().start())
46+
.then_with(|| {
47+
let a_target = a.target_parent();
48+
let b_target = b.target_parent();
49+
50+
if a_target == b_target {
51+
return Ordering::Equal;
52+
}
53+
54+
get_node_depth(a_target).cmp(&get_node_depth(b_target))
55+
})
4156
.then(a.change_kind().cmp(&b.change_kind()))
4257
});
4358

@@ -49,8 +64,8 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
4964
l.change_kind() == ChangeKind::Replace && r.change_kind() == ChangeKind::Replace
5065
})
5166
.all(|(l, r)| {
52-
(l.target_parent() != r.target_parent()
53-
|| l.target_range().intersect(r.target_range()).is_none())
67+
get_node_depth(l.target_parent()) != get_node_depth(r.target_parent())
68+
|| l.target_range().intersect(r.target_range()).is_none()
5469
});
5570

5671
if stdx::never!(

0 commit comments

Comments
 (0)