Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/syntax_editor/edit_algo.rs')
| -rw-r--r-- | crates/syntax/src/syntax_editor/edit_algo.rs | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/crates/syntax/src/syntax_editor/edit_algo.rs b/crates/syntax/src/syntax_editor/edit_algo.rs index e697d97061..27ea03ec09 100644 --- a/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/crates/syntax/src/syntax_editor/edit_algo.rs @@ -35,7 +35,10 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { // - changed nodes become part of the changed node set (useful for the formatter to only change those parts) // - Propagate annotations - let SyntaxEditor { root, mut changes, mappings, annotations } = editor; + let SyntaxEditor { root, changes, annotations, make } = editor; + let mut changes = changes.into_inner(); + let annotations = annotations.into_inner(); + let mappings = make.take(); let mut node_depths = FxHashMap::<SyntaxNode, usize>::default(); let mut get_node_depth = |node: SyntaxNode| { @@ -192,11 +195,8 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { } }; } - Change::Replace(SyntaxElement::Node(target), Some(SyntaxElement::Node(new_target))) => { + Change::Replace(SyntaxElement::Node(target), Some(SyntaxElement::Node(_))) => { *target = tree_mutator.make_syntax_mut(target); - if new_target.ancestors().any(|node| node == tree_mutator.immutable) { - *new_target = new_target.clone_for_update(); - } } Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => { *target = tree_mutator.make_element_mut(target); @@ -210,6 +210,56 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { } match &mut changes[index as usize] { + Change::Insert(_, SyntaxElement::Node(node)) + | Change::Replace(_, Some(SyntaxElement::Node(node))) => { + if node.parent().is_some() { + *node = node.clone_subtree().clone_for_update(); + } else if !node.is_mutable() { + *node = node.clone_for_update(); + } + } + Change::Insert(_, SyntaxElement::Token(token)) + | Change::Replace(_, Some(SyntaxElement::Token(token))) => { + if let Some(parent) = token.parent() { + let idx = token.index(); + let new_parent = parent.clone_subtree().clone_for_update(); + *token = new_parent + .children_with_tokens() + .nth(idx) + .and_then(SyntaxElement::into_token) + .unwrap(); + } + } + Change::InsertAll(_, elements) + | Change::ReplaceWithMany(_, elements) + | Change::ReplaceAll(_, elements) => { + for element in elements { + match element { + SyntaxElement::Node(node) => { + if node.parent().is_some() { + *node = node.clone_subtree().clone_for_update(); + } else if !node.is_mutable() { + *node = node.clone_for_update(); + } + } + SyntaxElement::Token(token) => { + if let Some(parent) = token.parent() { + let idx = token.index(); + let new_parent = parent.clone_subtree().clone_for_update(); + *token = new_parent + .children_with_tokens() + .nth(idx) + .and_then(SyntaxElement::into_token) + .unwrap(); + } + } + } + } + } + _ => {} + } + + match &mut changes[index as usize] { Change::Insert(_, element) | Change::Replace(_, Some(element)) => { deduplicate_node(element); } |