Migrate `generate_trait_from_impl` assist to use `SyntaxEditor`
diff --git a/crates/ide-assists/src/handlers/generate_trait_from_impl.rs b/crates/ide-assists/src/handlers/generate_trait_from_impl.rs
index dc3dc73..56500cf 100644
--- a/crates/ide-assists/src/handlers/generate_trait_from_impl.rs
+++ b/crates/ide-assists/src/handlers/generate_trait_from_impl.rs
@@ -2,12 +2,8 @@
 use ide_db::assists::AssistId;
 use syntax::{
     AstNode, SyntaxKind, T,
-    ast::{
-        self, HasGenericParams, HasName, HasVisibility,
-        edit_in_place::{HasVisibilityEdit, Indent},
-        make,
-    },
-    ted::{self, Position},
+    ast::{self, HasGenericParams, HasName, HasVisibility, edit_in_place::Indent, make},
+    syntax_editor::{Position, SyntaxEditor},
 };
 
 // NOTES :
@@ -88,8 +84,8 @@
         return None;
     }
 
-    let assoc_items = impl_ast.assoc_item_list()?;
-    let first_element = assoc_items.assoc_items().next();
+    let impl_assoc_items = impl_ast.assoc_item_list()?;
+    let first_element = impl_assoc_items.assoc_items().next();
     first_element.as_ref()?;
 
     let impl_name = impl_ast.self_ty()?;
@@ -99,20 +95,16 @@
         "Generate trait from impl",
         impl_ast.syntax().text_range(),
         |builder| {
-            let impl_ast = builder.make_mut(impl_ast);
-            let trait_items = assoc_items.clone_for_update();
-            let impl_items = builder.make_mut(assoc_items);
-            let impl_name = builder.make_mut(impl_name);
+            let trait_items: ast::AssocItemList = {
+                let trait_items = impl_assoc_items.clone_subtree();
+                let mut trait_items_editor = SyntaxEditor::new(trait_items.syntax().clone());
 
-            trait_items.assoc_items().for_each(|item| {
-                strip_body(&item);
-                remove_items_visibility(&item);
-            });
-
-            impl_items.assoc_items().for_each(|item| {
-                remove_items_visibility(&item);
-            });
-
+                trait_items.assoc_items().for_each(|item| {
+                    strip_body(&mut trait_items_editor, &item);
+                    remove_items_visibility(&mut trait_items_editor, &item);
+                });
+                ast::AssocItemList::cast(trait_items_editor.finish().new_root().clone()).unwrap()
+            };
             let trait_ast = make::trait_(
                 false,
                 "NewTrait",
@@ -130,6 +122,7 @@
                 trait_name_ref.syntax().clone().into(),
                 make::tokens::single_space().into(),
                 make::token(T![for]).into(),
+                make::tokens::single_space().into(),
             ];
 
             if let Some(params) = impl_ast.generic_param_list() {
@@ -137,10 +130,15 @@
                 elements.insert(1, gen_args.syntax().clone().into());
             }
 
-            ted::insert_all(Position::before(impl_name.syntax()), elements);
+            let mut editor = builder.make_editor(impl_ast.syntax());
+            impl_assoc_items.assoc_items().for_each(|item| {
+                remove_items_visibility(&mut editor, &item);
+            });
+
+            editor.insert_all(Position::before(impl_name.syntax()), elements);
 
             // Insert trait before TraitImpl
-            ted::insert_all_raw(
+            editor.insert_all(
                 Position::before(impl_ast.syntax()),
                 vec![
                     trait_ast.syntax().clone().into(),
@@ -150,11 +148,12 @@
 
             // Link the trait name & trait ref names together as a placeholder snippet group
             if let Some(cap) = ctx.config.snippet_cap {
-                builder.add_placeholder_snippet_group(
-                    cap,
-                    vec![trait_name.syntax().clone(), trait_name_ref.syntax().clone()],
-                );
+                let placeholder = builder.make_placeholder_snippet(cap);
+                editor.add_annotation(trait_name.syntax(), placeholder);
+                editor.add_annotation(trait_name_ref.syntax(), placeholder);
             }
+
+            builder.add_file_edits(ctx.vfs_file_id(), editor);
         },
     );
 
@@ -162,19 +161,21 @@
 }
 
 /// `E0449` Trait items always share the visibility of their trait
-fn remove_items_visibility(item: &ast::AssocItem) {
+fn remove_items_visibility(editor: &mut SyntaxEditor, item: &ast::AssocItem) {
     if let Some(has_vis) = ast::AnyHasVisibility::cast(item.syntax().clone()) {
         if let Some(vis) = has_vis.visibility()
             && let Some(token) = vis.syntax().next_sibling_or_token()
             && token.kind() == SyntaxKind::WHITESPACE
         {
-            ted::remove(token);
+            editor.delete(token);
         }
-        has_vis.set_visibility(None);
+        if let Some(vis) = has_vis.visibility() {
+            editor.delete(vis.syntax());
+        }
     }
 }
 
-fn strip_body(item: &ast::AssocItem) {
+fn strip_body(editor: &mut SyntaxEditor, item: &ast::AssocItem) {
     if let ast::AssocItem::Fn(f) = item
         && let Some(body) = f.body()
     {
@@ -183,10 +184,10 @@
         if let Some(prev) = body.syntax().prev_sibling_or_token()
             && prev.kind() == SyntaxKind::WHITESPACE
         {
-            ted::remove(prev);
+            editor.delete(prev);
         }
 
-        ted::replace(body.syntax(), make::tokens::semicolon());
+        editor.replace(body.syntax(), make::tokens::semicolon());
     };
 }