@@ -187,6 +187,7 @@ fn generate_module_def(
187187 parent_impl : & Option < ast:: Impl > ,
188188 Module { name, body_items, use_items } : & Module ,
189189) -> ast:: Module {
190+ let make = SyntaxFactory :: without_mappings ( ) ;
190191 let items: Vec < _ > = if let Some ( impl_) = parent_impl. as_ref ( )
191192 && let Some ( self_ty) = impl_. self_ty ( )
192193 {
@@ -196,9 +197,13 @@ fn generate_module_def(
196197 . filter_map ( ast:: AssocItem :: cast)
197198 . map ( |it| it. indent ( IndentLevel ( 1 ) ) )
198199 . collect_vec ( ) ;
199- let assoc_item_list = make:: assoc_item_list ( Some ( assoc_items) ) . clone_for_update ( ) ;
200- let impl_ = impl_. reset_indent ( ) ;
201- ted:: replace ( impl_. get_or_create_assoc_item_list ( ) . syntax ( ) , assoc_item_list. syntax ( ) ) ;
200+ let impl_reset = impl_. reset_indent ( ) ;
201+ let ( editor, impl_root) = SyntaxEditor :: with_ast_node ( & impl_reset) ;
202+ let assoc_item_list = editor. make ( ) . assoc_item_list ( assoc_items) ;
203+ if let Some ( existing_list) = impl_root. assoc_item_list ( ) {
204+ editor. replace ( existing_list. syntax ( ) , assoc_item_list. syntax ( ) ) ;
205+ }
206+ let impl_ = ast:: Impl :: cast ( editor. finish ( ) . new_root ( ) . clone ( ) ) . unwrap ( ) ;
202207 // Add the import for enum/struct corresponding to given impl block
203208 let use_impl = make_use_stmt_of_node_with_super ( self_ty. syntax ( ) ) ;
204209 once ( use_impl)
@@ -210,19 +215,19 @@ fn generate_module_def(
210215 } ;
211216
212217 let items = items. into_iter ( ) . map ( |it| it. reset_indent ( ) . indent ( IndentLevel ( 1 ) ) ) . collect_vec ( ) ;
213- let module_body = make:: item_list ( Some ( items) ) ;
214-
215- let module_name = make:: name ( name) ;
216- make:: mod_ ( module_name, Some ( module_body) )
218+ let module_body = make. item_list ( items) ;
219+ let module_name = make. name ( name) ;
220+ make. mod_ ( module_name, Some ( module_body) )
217221}
218222
219223fn make_use_stmt_of_node_with_super ( node_syntax : & SyntaxNode ) -> ast:: Item {
220- let super_path = make:: ext:: ident_path ( "super" ) ;
221- let node_path = make:: ext:: ident_path ( & node_syntax. to_string ( ) ) ;
222- let use_ = make:: use_ (
223- None ,
224+ let make = SyntaxFactory :: without_mappings ( ) ;
225+ let super_path = make. ident_path ( "super" ) ;
226+ let node_path = make. path_from_text ( & node_syntax. to_string ( ) ) ;
227+ let use_ = make. use_ (
228+ [ ] ,
224229 None ,
225- make:: use_tree ( make:: join_paths ( vec ! [ super_path, node_path] ) , None , None , false ) ,
230+ make. use_tree ( make. path_concat ( super_path, node_path) , None , None , false ) ,
226231 ) ;
227232
228233 ast:: Item :: from ( use_)
@@ -386,18 +391,32 @@ impl Module {
386391 if use_. syntax ( ) . parent ( ) . is_some_and ( |parent| parent == covering_node)
387392 && use_stmts_set. insert ( use_. syntax ( ) . text_range ( ) . start ( ) )
388393 {
389- let use_ = use_stmts_to_be_inserted
390- . entry ( use_. syntax ( ) . text_range ( ) . start ( ) )
391- . or_insert_with ( || use_. clone_subtree ( ) . clone_for_update ( ) ) ;
392- for seg in use_
394+ let key = use_. syntax ( ) . text_range ( ) . start ( ) ;
395+ let entry = use_stmts_to_be_inserted
396+ . entry ( key)
397+ . or_insert_with ( || {
398+ let ( _, root) = SyntaxEditor :: with_ast_node ( & use_) ;
399+ root
400+ } ) ;
401+ let make = SyntaxFactory :: without_mappings ( ) ;
402+ let ( editor, edit_root) = SyntaxEditor :: with_ast_node ( & * entry) ;
403+ let replacements: Vec < _ > = edit_root
393404 . syntax ( )
394405 . descendants ( )
395406 . filter_map ( ast:: NameRef :: cast)
396407 . filter ( |seg| seg. syntax ( ) . to_string ( ) == name_ref. to_string ( ) )
397- {
398- let new_ref = make:: path_from_text ( & format ! ( "{mod_name}::{seg}" ) )
399- . clone_for_update ( ) ;
400- ted:: replace ( seg. syntax ( ) . parent ( ) ?, new_ref. syntax ( ) ) ;
408+ . filter_map ( |seg| {
409+ Some ( (
410+ seg. syntax ( ) . parent ( ) ?,
411+ make. path_from_text ( & format ! ( "{mod_name}::{seg}" ) ) ,
412+ ) )
413+ } )
414+ . collect ( ) ;
415+ if !replacements. is_empty ( ) {
416+ for ( parent, new_ref) in & replacements {
417+ editor. replace ( parent, new_ref. syntax ( ) ) ;
418+ }
419+ * entry = ast:: Use :: cast ( editor. finish ( ) . new_root ( ) . clone ( ) ) . unwrap ( ) ;
401420 }
402421 }
403422 }
@@ -409,8 +428,13 @@ impl Module {
409428 }
410429
411430 fn change_visibility ( & mut self , record_fields : Vec < SyntaxNode > ) {
431+ for item in & mut self . body_items {
432+ let ( _, root) = SyntaxEditor :: with_ast_node ( & item. reset_indent ( ) ) ;
433+ * item = root;
434+ }
435+
412436 let ( mut replacements, record_field_parents, impls) =
413- get_replacements_for_visibility_change ( & mut self . body_items , false ) ;
437+ get_replacements_for_visibility_change ( & mut self . body_items ) ;
414438
415439 let mut impl_items = impls
416440 . into_iter ( )
@@ -419,7 +443,7 @@ impl Module {
419443 . collect_vec ( ) ;
420444
421445 let ( mut impl_item_replacements, _, _) =
422- get_replacements_for_visibility_change ( & mut impl_items, true ) ;
446+ get_replacements_for_visibility_change ( & mut impl_items) ;
423447
424448 replacements. append ( & mut impl_item_replacements) ;
425449
@@ -433,17 +457,40 @@ impl Module {
433457 }
434458 }
435459
436- for ( vis, syntax) in replacements {
437- let item = syntax. children_with_tokens ( ) . find ( |node_or_token| {
438- match node_or_token. kind ( ) {
439- // We're skipping comments, doc comments, and attribute macros that may precede the keyword
440- // that the visibility should be placed before.
441- SyntaxKind :: COMMENT | SyntaxKind :: ATTR | SyntaxKind :: WHITESPACE => false ,
442- _ => true ,
443- }
444- } ) ;
460+ let make = SyntaxFactory :: without_mappings ( ) ;
461+ for body_item in & mut self . body_items {
462+ let insert_targets: Vec < _ > = replacements
463+ . iter ( )
464+ . filter ( |( vis, syntax) | {
465+ vis. is_none ( )
466+ && ( syntax == body_item. syntax ( )
467+ || syntax. ancestors ( ) . any ( |a| & a == body_item. syntax ( ) ) )
468+ } )
469+ . filter_map ( |( _, syntax) | {
470+ syntax. children_with_tokens ( ) . find ( |nt| {
471+ !matches ! (
472+ nt. kind( ) ,
473+ SyntaxKind :: COMMENT | SyntaxKind :: ATTR | SyntaxKind :: WHITESPACE
474+ )
475+ } )
476+ } )
477+ . collect ( ) ;
445478
446- add_change_vis ( vis, item) ;
479+ if insert_targets. is_empty ( ) {
480+ continue ;
481+ }
482+
483+ let ( editor, _) = SyntaxEditor :: new ( body_item. syntax ( ) . clone ( ) ) ;
484+ for target in insert_targets {
485+ editor. insert_all (
486+ Position :: before ( target) ,
487+ vec ! [
488+ make. visibility_pub_crate( ) . syntax( ) . clone( ) . into( ) ,
489+ make. whitespace( " " ) . into( ) ,
490+ ] ,
491+ ) ;
492+ }
493+ * body_item = ast:: Item :: cast ( editor. finish ( ) . new_root ( ) . clone ( ) ) . unwrap ( ) ;
447494 }
448495 }
449496
@@ -494,6 +541,7 @@ impl Module {
494541 curr_parent_module : & Option < ast:: Module > ,
495542 ctx : & AssistContext < ' _ , ' _ > ,
496543 ) -> Option < TextRange > {
544+ let make = SyntaxFactory :: without_mappings ( ) ;
497545 //We only need to find in the current file
498546 let selection_range = ctx. selection_trimmed ( ) ;
499547 let file_id = ctx. file_id ( ) ;
@@ -591,7 +639,7 @@ impl Module {
591639 if !first_path_in_use_tree_str. contains ( "super" )
592640 && !first_path_in_use_tree_str. contains ( "crate" )
593641 {
594- let super_path = make:: ext :: ident_path ( "super" ) ;
642+ let super_path = make. ident_path ( "super" ) ;
595643 use_tree_str. push ( super_path) ;
596644 }
597645 }
@@ -610,7 +658,7 @@ impl Module {
610658 && let Some ( first_path_in_use_tree) = use_tree_paths. first ( )
611659 && first_path_in_use_tree. to_string ( ) . contains ( "super" )
612660 {
613- use_tree_paths. insert ( 0 , make:: ext :: ident_path ( "super" ) ) ;
661+ use_tree_paths. insert ( 0 , make. ident_path ( "super" ) ) ;
614662 }
615663
616664 let is_item = matches ! (
@@ -625,12 +673,12 @@ impl Module {
625673 | Definition :: TypeAlias ( _)
626674 ) ;
627675
628- if ( def_out_sel || !is_item) && use_stmt_not_in_sel {
629- let use_ = make :: use_ (
630- None ,
631- None ,
632- make :: use_tree ( make :: join_paths ( use_tree_paths ) , None , None , false ) ,
633- ) ;
676+ if ( def_out_sel || !is_item)
677+ && use_stmt_not_in_sel
678+ && let Some ( joined ) =
679+ use_tree_paths . into_iter ( ) . reduce ( |acc , p| make . path_concat ( acc , p ) )
680+ {
681+ let use_ = make . use_ ( [ ] , None , make . use_tree ( joined , None , None , false ) ) ;
634682 self . use_items . insert ( 0 , ast:: Item :: from ( use_) ) ;
635683 }
636684 }
@@ -742,7 +790,6 @@ fn check_def_in_mod_and_out_sel(
742790
743791fn get_replacements_for_visibility_change (
744792 items : & mut [ ast:: Item ] ,
745- is_clone_for_updated : bool ,
746793) -> (
747794 Vec < ( Option < ast:: Visibility > , SyntaxNode ) > ,
748795 Vec < ( Option < ast:: Visibility > , SyntaxNode ) > ,
@@ -753,9 +800,6 @@ fn get_replacements_for_visibility_change(
753800 let mut impls = Vec :: new ( ) ;
754801
755802 for item in items {
756- if !is_clone_for_updated {
757- * item = item. clone_for_update ( ) ;
758- }
759803 //Use stmts are ignored
760804 macro_rules! push_to_replacement {
761805 ( $it: ident) => {
@@ -812,15 +856,6 @@ fn get_use_tree_paths_from_path(
812856 Some ( use_tree_str)
813857}
814858
815- fn add_change_vis ( vis : Option < ast:: Visibility > , node_or_token_opt : Option < syntax:: SyntaxElement > ) {
816- if vis. is_none ( )
817- && let Some ( node_or_token) = node_or_token_opt
818- {
819- let pub_crate_vis = make:: visibility_pub_crate ( ) . clone_for_update ( ) ;
820- ted:: insert ( ted:: Position :: before ( node_or_token) , pub_crate_vis. syntax ( ) ) ;
821- }
822- }
823-
824859fn indent_range_before_given_node ( node : & SyntaxNode ) -> Option < TextRange > {
825860 node. siblings_with_tokens ( syntax:: Direction :: Prev )
826861 . find ( |x| x. kind ( ) == WHITESPACE )
0 commit comments