1
1
use hir:: { self , HasCrate , HirDisplay } ;
2
- use stdx:: format_to;
3
2
use syntax:: ast:: { self , make, AstNode , HasName , HasVisibility } ;
4
3
5
4
use crate :: {
6
- utils:: { find_impl_block_end , find_struct_impl, generate_impl_text , render_snippet, Cursor } ,
5
+ utils:: { find_struct_impl, render_snippet, Cursor } ,
7
6
AssistContext , AssistId , AssistKind , Assists , GroupLabel ,
8
7
} ;
9
8
@@ -31,9 +30,9 @@ use crate::{
31
30
// ```
32
31
pub ( crate ) fn generate_delegate ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
33
32
let strukt = ctx. find_node_at_offset :: < ast:: Struct > ( ) ?;
34
- let field = ctx . find_node_at_offset :: < ast :: RecordField > ( ) ?;
33
+ let strukt_name = strukt . name ( ) ?;
35
34
36
- let field_name = field . name ( ) ?;
35
+ let field = ctx . find_node_at_offset :: < ast :: RecordField > ( ) ?;
37
36
let field_ty = field. ty ( ) ?;
38
37
39
38
let sema_field_ty = ctx. sema . resolve_type ( & field_ty) ?;
@@ -61,23 +60,6 @@ pub(crate) fn generate_delegate(acc: &mut Assists, ctx: &AssistContext) -> Optio
61
60
format ! ( "Generate a delegate method for '{}'" , method. name( ctx. db( ) ) ) ,
62
61
target,
63
62
|builder| {
64
- let mut buf = String :: with_capacity ( 512 ) ;
65
-
66
- let vis = strukt. visibility ( ) . map_or ( String :: new ( ) , |v| format ! ( "{} " , v) ) ;
67
- let return_type = method. ret_type ( ctx. db ( ) ) ;
68
- let return_type = if return_type. is_unit ( ) || return_type. is_unknown ( ) {
69
- String :: new ( )
70
- } else {
71
- let module = match ctx. sema . scope ( strukt. syntax ( ) ) . module ( ) {
72
- Some ( m) => m,
73
- None => return ,
74
- } ;
75
- match return_type. display_source_code ( ctx. db ( ) , module. into ( ) ) {
76
- Ok ( rt) => format ! ( "-> {}" , rt) ,
77
- Err ( _) => return ,
78
- }
79
- } ;
80
-
81
63
// make function
82
64
let vis = strukt. visibility ( ) ;
83
65
let name = make:: name ( & method. name ( ctx. db ( ) ) . to_string ( ) ) ;
@@ -89,21 +71,28 @@ pub(crate) fn generate_delegate(acc: &mut Assists, ctx: &AssistContext) -> Optio
89
71
let is_async = false ;
90
72
let f = make:: fn_ ( vis, name, type_params, params, body, ret_type, is_async) ;
91
73
92
- let start_offset = impl_def
93
- . and_then ( |impl_def| find_impl_block_end ( impl_def, & mut buf) )
94
- . unwrap_or_else ( || {
95
- buf = generate_impl_text ( & ast:: Adt :: Struct ( strukt. clone ( ) ) , & buf) ;
96
- strukt. syntax ( ) . text_range ( ) . end ( )
97
- } ) ;
98
-
99
- let cap = ctx. config . snippet_cap . unwrap ( ) ; // FIXME.
100
74
let cursor = Cursor :: Before ( f. syntax ( ) ) ;
75
+ let cap = ctx. config . snippet_cap . unwrap ( ) ; // FIXME.
101
76
102
- builder. insert_snippet (
103
- cap,
104
- start_offset,
105
- format ! ( "\n \n {}" , render_snippet( cap, f. syntax( ) , cursor) ) ,
106
- ) ;
77
+ match impl_def {
78
+ Some ( impl_def) => {
79
+ let impl_def = impl_def. clone_for_update ( ) ;
80
+ let old_range = impl_def. syntax ( ) . text_range ( ) ;
81
+ let assoc_items = impl_def. get_or_create_assoc_item_list ( ) ;
82
+ assoc_items. add_item ( f. clone ( ) . into ( ) ) ;
83
+ let snippet = render_snippet ( cap, impl_def. syntax ( ) , cursor) ;
84
+ builder. replace_snippet ( cap, old_range, snippet) ;
85
+ }
86
+ None => {
87
+ let name = & strukt_name. to_string ( ) ;
88
+ let impl_def = make:: impl_ ( make:: ext:: ident_path ( name) ) ;
89
+ let assoc_items = impl_def. get_or_create_assoc_item_list ( ) ;
90
+ assoc_items. add_item ( f. clone ( ) . into ( ) ) ;
91
+ let start_offset = strukt. syntax ( ) . text_range ( ) . end ( ) ;
92
+ let snippet = render_snippet ( cap, impl_def. syntax ( ) , cursor) ;
93
+ builder. insert_snippet ( cap, start_offset, snippet) ;
94
+ }
95
+ }
107
96
} ,
108
97
) ?;
109
98
}
@@ -132,11 +121,13 @@ impl Age {
132
121
struct Person {
133
122
ag$0e: Age,
134
123
}
124
+
125
+ impl Person {}
135
126
"# ,
136
127
r#"
137
128
struct Age(u8);
138
129
impl Age {
139
- fn age(&self) -> u8 {
130
+ $0fn age(&self) -> u8 {
140
131
self.0
141
132
}
142
133
}
0 commit comments