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.rs60
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);
}