@@ -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,28 @@ 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
394+ let entry = use_stmts_to_be_inserted
390395 . entry ( use_. syntax ( ) . text_range ( ) . start ( ) )
391- . or_insert_with ( || use_. clone_subtree ( ) . clone_for_update ( ) ) ;
392- for seg in use_
396+ . or_insert_with ( || use_. clone_subtree ( ) ) ;
397+ let make = SyntaxFactory :: without_mappings ( ) ;
398+ let replacements: Vec < _ > = entry
393399 . syntax ( )
394400 . descendants ( )
395401 . filter_map ( ast:: NameRef :: cast)
396402 . 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 ( ) ) ;
403+ . filter_map ( |seg| {
404+ Some ( (
405+ seg. syntax ( ) . parent ( ) ?,
406+ make. path_from_text ( & format ! ( "{mod_name}::{seg}" ) ) ,
407+ ) )
408+ } )
409+ . collect ( ) ;
410+ if !replacements. is_empty ( ) {
411+ let ( editor, _) = SyntaxEditor :: new ( entry. syntax ( ) . clone ( ) ) ;
412+ for ( parent, new_ref) in & replacements {
413+ editor. replace ( parent, new_ref. syntax ( ) ) ;
414+ }
415+ * entry = ast:: Use :: cast ( editor. finish ( ) . new_root ( ) . clone ( ) ) . unwrap ( ) ;
401416 }
402417 }
403418 }
@@ -409,8 +424,12 @@ impl Module {
409424 }
410425
411426 fn change_visibility ( & mut self , record_fields : Vec < SyntaxNode > ) {
427+ for item in & mut self . body_items {
428+ * item = ast:: Item :: cast ( item. reset_indent ( ) . syntax ( ) . clone_subtree ( ) ) . unwrap ( ) ;
429+ }
430+
412431 let ( mut replacements, record_field_parents, impls) =
413- get_replacements_for_visibility_change ( & mut self . body_items , false ) ;
432+ get_replacements_for_visibility_change ( & mut self . body_items ) ;
414433
415434 let mut impl_items = impls
416435 . into_iter ( )
@@ -419,7 +438,7 @@ impl Module {
419438 . collect_vec ( ) ;
420439
421440 let ( mut impl_item_replacements, _, _) =
422- get_replacements_for_visibility_change ( & mut impl_items, true ) ;
441+ get_replacements_for_visibility_change ( & mut impl_items) ;
423442
424443 replacements. append ( & mut impl_item_replacements) ;
425444
@@ -433,17 +452,40 @@ impl Module {
433452 }
434453 }
435454
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- } ) ;
455+ let make = SyntaxFactory :: without_mappings ( ) ;
456+ for body_item in & mut self . body_items {
457+ let insert_targets: Vec < _ > = replacements
458+ . iter ( )
459+ . filter ( |( vis, syntax) | {
460+ vis. is_none ( )
461+ && ( syntax == body_item. syntax ( )
462+ || syntax. ancestors ( ) . any ( |a| & a == body_item. syntax ( ) ) )
463+ } )
464+ . filter_map ( |( _, syntax) | {
465+ syntax. children_with_tokens ( ) . find ( |nt| {
466+ !matches ! (
467+ nt. kind( ) ,
468+ SyntaxKind :: COMMENT | SyntaxKind :: ATTR | SyntaxKind :: WHITESPACE
469+ )
470+ } )
471+ } )
472+ . collect ( ) ;
445473
446- add_change_vis ( vis, item) ;
474+ if insert_targets. is_empty ( ) {
475+ continue ;
476+ }
477+
478+ let ( editor, _) = SyntaxEditor :: new ( body_item. syntax ( ) . clone ( ) ) ;
479+ for target in insert_targets {
480+ editor. insert_all (
481+ Position :: before ( target) ,
482+ vec ! [
483+ make. visibility_pub_crate( ) . syntax( ) . clone( ) . into( ) ,
484+ make. whitespace( " " ) . into( ) ,
485+ ] ,
486+ ) ;
487+ }
488+ * body_item = ast:: Item :: cast ( editor. finish ( ) . new_root ( ) . clone ( ) ) . unwrap ( ) ;
447489 }
448490 }
449491
@@ -494,6 +536,7 @@ impl Module {
494536 curr_parent_module : & Option < ast:: Module > ,
495537 ctx : & AssistContext < ' _ , ' _ > ,
496538 ) -> Option < TextRange > {
539+ let make = SyntaxFactory :: without_mappings ( ) ;
497540 //We only need to find in the current file
498541 let selection_range = ctx. selection_trimmed ( ) ;
499542 let file_id = ctx. file_id ( ) ;
@@ -591,7 +634,7 @@ impl Module {
591634 if !first_path_in_use_tree_str. contains ( "super" )
592635 && !first_path_in_use_tree_str. contains ( "crate" )
593636 {
594- let super_path = make:: ext :: ident_path ( "super" ) ;
637+ let super_path = make. ident_path ( "super" ) ;
595638 use_tree_str. push ( super_path) ;
596639 }
597640 }
@@ -610,7 +653,7 @@ impl Module {
610653 && let Some ( first_path_in_use_tree) = use_tree_paths. first ( )
611654 && first_path_in_use_tree. to_string ( ) . contains ( "super" )
612655 {
613- use_tree_paths. insert ( 0 , make:: ext :: ident_path ( "super" ) ) ;
656+ use_tree_paths. insert ( 0 , make. ident_path ( "super" ) ) ;
614657 }
615658
616659 let is_item = matches ! (
@@ -625,12 +668,12 @@ impl Module {
625668 | Definition :: TypeAlias ( _)
626669 ) ;
627670
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- ) ;
671+ if ( def_out_sel || !is_item)
672+ && use_stmt_not_in_sel
673+ && let Some ( joined ) =
674+ use_tree_paths . into_iter ( ) . reduce ( |acc , p| make . path_concat ( acc , p ) )
675+ {
676+ let use_ = make . use_ ( [ ] , None , make . use_tree ( joined , None , None , false ) ) ;
634677 self . use_items . insert ( 0 , ast:: Item :: from ( use_) ) ;
635678 }
636679 }
@@ -742,7 +785,6 @@ fn check_def_in_mod_and_out_sel(
742785
743786fn get_replacements_for_visibility_change (
744787 items : & mut [ ast:: Item ] ,
745- is_clone_for_updated : bool ,
746788) -> (
747789 Vec < ( Option < ast:: Visibility > , SyntaxNode ) > ,
748790 Vec < ( Option < ast:: Visibility > , SyntaxNode ) > ,
@@ -753,9 +795,6 @@ fn get_replacements_for_visibility_change(
753795 let mut impls = Vec :: new ( ) ;
754796
755797 for item in items {
756- if !is_clone_for_updated {
757- * item = item. clone_for_update ( ) ;
758- }
759798 //Use stmts are ignored
760799 macro_rules! push_to_replacement {
761800 ( $it: ident) => {
@@ -812,15 +851,6 @@ fn get_use_tree_paths_from_path(
812851 Some ( use_tree_str)
813852}
814853
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-
824854fn indent_range_before_given_node ( node : & SyntaxNode ) -> Option < TextRange > {
825855 node. siblings_with_tokens ( syntax:: Direction :: Prev )
826856 . find ( |x| x. kind ( ) == WHITESPACE )
0 commit comments