about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs48
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs14
2 files changed, 52 insertions, 10 deletions
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
index 7e5d0f27e0a..992a847663a 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
@@ -327,7 +327,7 @@ mod tests {
 
     use crate::{
         ast::{self, make, syntax_factory::SyntaxFactory},
-        AstNode,
+        AstNode, SyntaxKind,
     };
 
     use super::*;
@@ -540,4 +540,50 @@ mod tests {
             }"#]];
         expect.assert_eq(&edit.new_root.to_string());
     }
+
+    #[test]
+    fn test_replace_token_in_parent() {
+        let parent_fn = make::fn_(
+            None,
+            make::name("it"),
+            None,
+            None,
+            make::param_list(None, []),
+            make::block_expr([], Some(make::expr_unit())),
+            Some(make::ret_type(make::ty_unit())),
+            false,
+            false,
+            false,
+            false,
+        );
+
+        let mut editor = SyntaxEditor::new(parent_fn.syntax().clone());
+
+        if let Some(ret_ty) = parent_fn.ret_type() {
+            editor.delete(ret_ty.syntax().clone());
+
+            if let Some(SyntaxElement::Token(token)) = ret_ty.syntax().next_sibling_or_token() {
+                if token.kind().is_trivia() {
+                    editor.delete(token);
+                }
+            }
+        }
+
+        if let Some(tail) = parent_fn.body().unwrap().tail_expr() {
+            // FIXME: We do this because `xtask tidy` will not allow us to have trailing whitespace in the expect string.
+            if let Some(SyntaxElement::Token(token)) = tail.syntax().prev_sibling_or_token() {
+                if let SyntaxKind::WHITESPACE = token.kind() {
+                    editor.delete(token);
+                }
+            }
+            editor.delete(tail.syntax().clone());
+        }
+
+        let edit = editor.finish();
+
+        let expect = expect![[r#"
+fn it() {
+}"#]];
+        expect.assert_eq(&edit.new_root.to_string());
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
index 44a1fae23be..71b69dbec1d 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
@@ -128,13 +128,14 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
 
         // Add to changed ancestors, if applicable
         match change {
-            Change::Insert(_, _) | Change::InsertAll(_, _) => {}
-            Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => {
+            Change::Replace(SyntaxElement::Node(target), _)
+            | Change::ReplaceWithMany(SyntaxElement::Node(target), _) => {
                 changed_ancestors.push_back(ChangedAncestor::single(target, change_index))
             }
             Change::ReplaceAll(range, _) => {
                 changed_ancestors.push_back(ChangedAncestor::multiple(range, change_index))
             }
+            _ => (),
         }
     }
 
@@ -304,13 +305,8 @@ enum ChangedAncestorKind {
 }
 
 impl ChangedAncestor {
-    fn single(element: &SyntaxElement, change_index: usize) -> Self {
-        let kind = match element {
-            SyntaxElement::Node(node) => ChangedAncestorKind::Single { node: node.clone() },
-            SyntaxElement::Token(token) => {
-                ChangedAncestorKind::Single { node: token.parent().unwrap() }
-            }
-        };
+    fn single(node: &SyntaxNode, change_index: usize) -> Self {
+        let kind = ChangedAncestorKind::Single { node: node.clone() };
 
         Self { kind, change_index }
     }