@@ -19,7 +19,7 @@ use syntax::{
19
19
AstNode , Edition , NodeOrToken , SyntaxElement , SyntaxKind , SyntaxNode , T ,
20
20
algo:: find_node_at_range,
21
21
ast:: {
22
- self , HasArgList , HasGenericParams , HasName , HasVisibility ,
22
+ self , HasArgList , HasAttrs , HasGenericParams , HasName , HasVisibility ,
23
23
edit:: { AstNodeEdit , IndentLevel } ,
24
24
make,
25
25
syntax_factory:: SyntaxFactory ,
@@ -38,7 +38,7 @@ use crate::{AssistContext, Assists};
38
38
// ```
39
39
// ->
40
40
// ```
41
- // struct FooStruct{ bar: u32, baz: u32 }
41
+ // struct FooStruct { bar: u32, baz: u32 }
42
42
//
43
43
// fn foo(FooStruct { bar, baz, .. }: FooStruct) { ... }
44
44
// ```
@@ -158,7 +158,6 @@ pub(crate) fn extract_struct_from_function_signature(
158
158
let field_list = if let Some ( ( target_scope, source_scope) ) =
159
159
ctx. sema . scope ( func. syntax ( ) ) . zip ( ctx. sema . scope ( param_list. syntax ( ) ) )
160
160
{
161
- let field_list = field_list. reset_indent ( ) ;
162
161
let field_list =
163
162
PathTransform :: generic_transformation ( & target_scope, & source_scope)
164
163
. apply ( field_list. syntax ( ) ) ;
@@ -171,9 +170,9 @@ pub(crate) fn extract_struct_from_function_signature(
171
170
} else {
172
171
field_list
173
172
} ;
174
- field_list. fields ( ) . filter_map ( |f|f. ty ( ) ) . try_for_each ( |t|generate_new_lifetimes ( & mut editor , & t, & mut generics) ) ;
173
+ field_list. fields ( ) . filter_map ( |f|f. ty ( ) ) . try_for_each ( |t|generate_new_lifetimes ( builder , & t, & mut generics, ctx . vfs_file_id ( ) ) ) ;
175
174
tracing:: info!( "extract_struct_from_function_signature: collecting fields" ) ;
176
- let def = create_struct_def ( & make , name. clone ( ) , & func, & used_param_list, & field_list, generics) ;
175
+ let def = create_struct_def ( builder , name. clone ( ) , & func, & used_param_list, & field_list, generics, ctx . vfs_file_id ( ) ) ;
177
176
tracing:: info!( "extract_struct_from_function_signature: creating struct" ) ;
178
177
let def = def. indent ( indent) ;
179
178
editor. insert_all (
@@ -272,49 +271,47 @@ fn pat_to_name(pat: ast::Pat) -> Option<ast::Name> {
272
271
}
273
272
}
274
273
fn create_struct_def (
275
- editor : & SyntaxFactory ,
274
+ builder : & mut SourceChangeBuilder ,
276
275
name : ast:: Name ,
277
276
func : & ast:: Fn ,
278
277
param_ast : & [ ast:: Param ] ,
279
278
field_list : & ast:: RecordFieldList ,
280
279
generics : Option < ast:: GenericParamList > ,
280
+ _file_id : FileId ,
281
281
) -> ast:: Struct {
282
282
let fn_vis = func. visibility ( ) ;
283
283
284
284
// if we do not expleictly copy over comments/attribures they just get lost
285
285
// TODO: what about comments/attributes in between parameters
286
- // param_ast.iter().zip(field_list.fields()).for_each(|(param, field)| {
287
- // editor.attr_inner(meta)
288
- // let elements = take_all_comments(param.clone());
289
- // editor.insert_all(Position::first_child_of(field.syntax()), elements);
290
- // editor.insert_all(
291
- // Position::first_child_of(field.syntax()),
292
- // param
293
- // .attrs()
294
- // .flat_map(|it| [it.syntax().clone().into(), make::tokens::single_newline().into()])
295
- // .collect(),
296
- // );
297
- // });
286
+ param_ast. iter ( ) . zip ( field_list. fields ( ) ) . for_each ( |( param, field) | {
287
+ let mut editor = builder. make_editor ( field. syntax ( ) ) ;
288
+ let elements = take_all_comments ( param. clone ( ) ) ;
289
+ editor. insert_all ( Position :: first_child_of ( field. syntax ( ) ) , elements) ;
290
+ editor. insert_all (
291
+ Position :: first_child_of ( field. syntax ( ) ) ,
292
+ param
293
+ . attrs ( )
294
+ . flat_map ( |it| [ it. syntax ( ) . clone ( ) . into ( ) , make:: tokens:: single_newline ( ) . into ( ) ] )
295
+ . collect ( ) ,
296
+ ) ;
297
+ // this panics
298
+ // builder.add_file_edits(file_id, editor);
299
+ } ) ;
298
300
let field_list = field_list. indent ( IndentLevel :: single ( ) ) ;
299
301
300
302
make:: struct_ ( fn_vis, name, generics, field_list. into ( ) ) . clone_for_update ( )
301
303
}
302
- // Note: this also detaches whitespace after comments,
303
- // since `SyntaxNode::splice_children` (and by extension `ted::insert_all_raw`)
304
- // detaches nodes. If we only took the comments, we'd leave behind the old whitespace.
305
304
fn take_all_comments ( node : impl ast:: AstNode ) -> Vec < SyntaxElement > {
306
305
let mut remove_next_ws = false ;
307
306
node. syntax ( )
308
307
. children_with_tokens ( )
309
308
. filter_map ( move |child| match child. kind ( ) {
310
309
SyntaxKind :: COMMENT => {
311
310
remove_next_ws = true ;
312
- child. detach ( ) ;
313
311
Some ( child)
314
312
}
315
313
SyntaxKind :: WHITESPACE if remove_next_ws => {
316
314
remove_next_ws = false ;
317
- child. detach ( ) ;
318
315
Some ( make:: tokens:: single_newline ( ) . into ( ) )
319
316
}
320
317
_ => {
@@ -367,30 +364,38 @@ fn contains_impl_trait(ty: &ast::Type) -> bool {
367
364
ty. syntax ( ) . descendants ( ) . any ( |ty| ty. kind ( ) == ast:: ImplTraitType :: kind ( ) )
368
365
}
369
366
fn generate_new_lifetimes (
370
- editor : & mut SyntaxEditor ,
367
+ builder : & mut SourceChangeBuilder ,
371
368
ty : & ast:: Type ,
372
369
existing_type_param_list : & mut Option < ast:: GenericParamList > ,
370
+ _file_id : FileId ,
373
371
) -> Option < ( ) > {
374
372
for token in ty. syntax ( ) . descendants ( ) {
375
373
// we do not have to worry about for<'a> because we are only looking at '_ or &Type
376
374
// if you have an unbound lifetime thats on you
377
375
if let Some ( lt) = ast:: Lifetime :: cast ( token. clone ( ) )
378
376
&& lt. text ( ) == "'_"
379
377
{
378
+ let mut editor = builder. make_editor ( lt. syntax ( ) ) ;
380
379
let new_lt = generate_unique_lifetime_param_name ( existing_type_param_list) ?;
380
+ editor. replace ( lt. syntax ( ) , new_lt. syntax ( ) ) ;
381
381
existing_type_param_list
382
382
. get_or_insert ( make:: generic_param_list ( std:: iter:: empty ( ) ) . clone_for_update ( ) )
383
+ // TODO: used TED
383
384
. add_generic_param ( make:: lifetime_param ( new_lt. clone ( ) ) . clone_for_update ( ) . into ( ) ) ;
384
-
385
- // editor.replace(lt.syntax(), new_lt.clone_for_update().syntax() );
385
+ // this panics
386
+ // builder.add_file_edits(file_id, editor );
386
387
} else if let Some ( r) = ast:: RefType :: cast ( token. clone ( ) )
387
388
&& r. lifetime ( ) . is_none ( )
388
389
{
390
+ let mut editor = builder. make_editor ( r. syntax ( ) ) ;
389
391
let new_lt = generate_unique_lifetime_param_name ( existing_type_param_list) ?;
392
+ editor. insert ( Position :: after ( r. amp_token ( ) ?) , new_lt. syntax ( ) ) ;
390
393
existing_type_param_list
391
394
. get_or_insert ( make:: generic_param_list ( std:: iter:: empty ( ) ) . clone_for_update ( ) )
395
+ // TODO: used TED
392
396
. add_generic_param ( make:: lifetime_param ( new_lt. clone ( ) ) . clone_for_update ( ) . into ( ) ) ;
393
- // editor.insert(Position::after(r.amp_token()?), new_lt.clone_for_update().syntax());
397
+ // this panics
398
+ // builder.add_file_edits(file_id, editor);
394
399
}
395
400
// TODO: nominal types that have only lifetimes
396
401
// struct Bar<'a, 'b> { f: &'a &'b i32 }
@@ -488,7 +493,7 @@ fn process_references(
488
493
ctx. sema . db ,
489
494
* function_module_def,
490
495
ctx. config . insert_use . prefix_kind ,
491
- ctx. config . import_path_config ( ) ,
496
+ ctx. config . find_path_confg ( ctx . sema . is_nightly ( module . krate ( ) ) ) ,
492
497
) ;
493
498
if let Some ( mut mod_path) = mod_path {
494
499
mod_path. pop_segment ( ) ;
@@ -532,7 +537,6 @@ fn apply_references(
532
537
name : ast:: Name ,
533
538
file_id : impl Into < FileId > ,
534
539
) -> Option < ( ) > {
535
- let make = SyntaxFactory :: with_mappings ( ) ;
536
540
let mut editor = builder. make_editor ( call. syntax ( ) ) ;
537
541
if let Some ( ( scope, path) ) = import {
538
542
let scope = builder. make_import_scope_mut ( scope) ;
@@ -642,7 +646,7 @@ fn one($0x: u8, y: u32) {}
642
646
fn foo($0bar: i32$0, baz: i32) {}
643
647
"# ,
644
648
r#"
645
- struct FooStruct{ bar: i32 }
649
+ struct FooStruct { bar: i32 }
646
650
647
651
fn foo(FooStruct { bar, .. }: FooStruct, baz: i32) {}
648
652
"# ,
@@ -656,7 +660,7 @@ fn foo(FooStruct { bar, .. }: FooStruct, baz: i32) {}
656
660
fn foo($0bar: i32, baz: i32$0) {}
657
661
"# ,
658
662
r#"
659
- struct FooStruct{ bar: i32, baz: i32 }
663
+ struct FooStruct { bar: i32, baz: i32 }
660
664
661
665
fn foo(FooStruct { bar, baz, .. }: FooStruct) {}
662
666
"# ,
@@ -674,7 +678,7 @@ fn main() {
674
678
}
675
679
"# ,
676
680
r#"
677
- struct FooStruct{ bar: i32, baz: i32 }
681
+ struct FooStruct { bar: i32, baz: i32 }
678
682
679
683
fn foo(FooStruct { bar, baz, .. }: FooStruct) {}
680
684
@@ -705,15 +709,15 @@ mod b {
705
709
"# ,
706
710
r#"
707
711
mod a {
708
- pub struct FooStruct{ pub bar: i32 }
712
+ pub struct FooStruct { pub bar: i32 }
709
713
710
714
pub fn foo(FooStruct { bar, .. }: FooStruct, baz: i32) {
711
715
foo(FooStruct { bar: 1 }, 2)
712
716
}
713
717
}
714
718
715
719
mod b {
716
- use crate::a::{foo, FooStruct };
720
+ use crate::a::{FooStruct, foo };
717
721
718
722
fn main() {
719
723
foo(FooStruct { bar: 1 }, 2)
@@ -734,7 +738,7 @@ mod b {
734
738
}
735
739
"# ,
736
740
r#"
737
- struct FooStruct{ bar: i32 }
741
+ struct FooStruct { bar: i32 }
738
742
739
743
fn foo(FooStruct { bar, .. }: FooStruct, baz: i32) {}
740
744
@@ -753,7 +757,7 @@ mod b {
753
757
fn foo<'a, A>($0bar: &'a A$0, baz: i32) {}
754
758
"# ,
755
759
r#"
756
- struct FooStruct<'a, A>{ bar: &'a A }
760
+ struct FooStruct<'a, A> { bar: &'a A }
757
761
758
762
fn foo<'a, A>(FooStruct { bar, .. }: FooStruct<'a, A>, baz: i32) {}
759
763
"# ,
@@ -769,7 +773,7 @@ fn foo<'a, A>($0bar: &'a A$0, baz: i32) {
769
773
}
770
774
"# ,
771
775
r#"
772
- struct FooStruct<'a, A>{ bar: &'a A }
776
+ struct FooStruct<'a, A> { bar: &'a A }
773
777
774
778
fn foo<'a, A>(FooStruct { bar, .. }: FooStruct<'a, A>, baz: i32) {
775
779
foo(FooStruct { bar: 1 }, 2)
@@ -786,7 +790,7 @@ fn foo<'a, A>(FooStruct { bar, .. }: FooStruct<'a, A>, baz: i32) {
786
790
fn foo($0bar: &'_ i32$0, baz: i32) {}
787
791
"# ,
788
792
r#"
789
- struct FooStruct<'a>{ bar: &'a i32 }
793
+ struct FooStruct<'a> { bar: &'a i32 }
790
794
791
795
fn foo(FooStruct { bar, .. }: FooStruct<'_>, baz: i32) {}
792
796
"# ,
@@ -801,7 +805,7 @@ fn foo(FooStruct { bar, .. }: FooStruct<'_>, baz: i32) {}
801
805
fn foo($0bar: &i32$0, baz: i32) {}
802
806
"# ,
803
807
r#"
804
- struct FooStruct<'a>{ bar: &'a i32 }
808
+ struct FooStruct<'a> { bar: &'a i32 }
805
809
806
810
fn foo(FooStruct { bar, .. }: FooStruct<'_>, baz: i32) {}
807
811
"# ,
@@ -815,7 +819,7 @@ fn foo(FooStruct { bar, .. }: FooStruct<'_>, baz: i32) {}
815
819
fn foo<'a>($0bar: &'_ &'a i32$0, baz: i32) {}
816
820
"# ,
817
821
r#"
818
- struct FooStruct<'a, 'b>{ bar: &'b &'a i32 }
822
+ struct FooStruct<'a, 'b> { bar: &'b &'a i32 }
819
823
820
824
fn foo<'a>(FooStruct { bar, .. }: FooStruct<'a, '_>, baz: i32) {}
821
825
"# ,
@@ -833,7 +837,7 @@ fn foo<'a>($0bar: &'_ &'a i32$0, baz: i32) {
833
837
}
834
838
"# ,
835
839
r#"
836
- struct FooStruct<'a, 'b>{ bar: &'b &'a i32 }
840
+ struct FooStruct<'a, 'b> { bar: &'b &'a i32 }
837
841
838
842
fn foo<'a>(FooStruct { bar, .. }: FooStruct<'a, '_>, baz: i32) {
839
843
foo(FooStruct { bar: bar }, baz)
@@ -864,7 +868,7 @@ fn bar() {
864
868
"# ,
865
869
r#"
866
870
struct Foo
867
- struct FooStruct{ j: i32, i: i32 }
871
+ struct FooStruct { j: i32, i: i32 }
868
872
869
873
impl Foo {
870
874
fn foo(&self, FooStruct { j, i, .. }: FooStruct, z:i32) { }
@@ -895,7 +899,7 @@ fn bar() {
895
899
"# ,
896
900
r#"
897
901
struct Foo
898
- struct FooStruct{ j: i32, i: i32 }
902
+ struct FooStruct { j: i32, i: i32 }
899
903
900
904
impl Foo {
901
905
fn foo(&self, FooStruct { j, i, .. }: FooStruct, z:i32) { }
@@ -922,7 +926,7 @@ fn foo(
922
926
) { }
923
927
"# ,
924
928
r#"
925
- struct FooStruct{ #[foo]
929
+ struct FooStruct { #[foo]
926
930
// gag
927
931
f: i32 }
928
932
0 commit comments