From 93c9f068704197791ee0e92c8863ba03673021f0 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:53:22 -0500 Subject: [PATCH] fix: Properly handle removals in `SyntaxEditor` --- crates/syntax/src/syntax_editor/edit_algo.rs | 24 +++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/crates/syntax/src/syntax_editor/edit_algo.rs b/crates/syntax/src/syntax_editor/edit_algo.rs index d6d903715d..fa51fb6eef 100644 --- a/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/crates/syntax/src/syntax_editor/edit_algo.rs @@ -102,6 +102,7 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { let mut changed_ancestors: VecDeque = VecDeque::new(); let mut dependent_changes = vec![]; let mut independent_changes = vec![]; + let mut outdated_changes = vec![]; for (change_index, change) in changes.iter().enumerate() { // Check if this change is dependent on another change (i.e. it's contained within another range) @@ -116,10 +117,14 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { // FIXME: Resolve changes that depend on a range of elements let ancestor = &changed_ancestors[index]; - dependent_changes.push(DependentChange { - parent: ancestor.change_index as u32, - child: change_index as u32, - }); + if let Change::Replace(_, None) = changes[ancestor.change_index] { + outdated_changes.push(change_index as u32); + } else { + dependent_changes.push(DependentChange { + parent: ancestor.change_index as u32, + child: change_index as u32, + }); + } } else { // This change is independent of any other change @@ -195,8 +200,9 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { Change::Replace(target, Some(new_target)) => { (to_owning_node(target), to_owning_node(new_target)) } - // Silently drop outdated change - Change::Replace(_, None) => continue, + Change::Replace(_, None) => { + unreachable!("deletions should not generate dependent changes") + } Change::ReplaceAll(_, _) | Change::ReplaceWithMany(_, _) => { unimplemented!("cannot resolve changes that depend on replacing many elements") } @@ -234,6 +240,12 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { } } + // We reverse here since we pushed to this in ascending order, + // and we want to remove elements in descending order + for idx in outdated_changes.into_iter().rev() { + changes.remove(idx as usize); + } + // Apply changes let mut root = tree_mutator.mutable_clone;