@@ -2,7 +2,7 @@ use hir::{self, HasCrate, HasSource, HirDisplay};
2
2
use syntax:: ast:: { self , make, AstNode , HasGenericParams , HasName , HasVisibility } ;
3
3
4
4
use crate :: {
5
- utils:: { find_struct_impl, render_snippet, Cursor } ,
5
+ utils:: { convert_param_list_to_arg_list , find_struct_impl, render_snippet, Cursor } ,
6
6
AssistContext , AssistId , AssistKind , Assists , GroupLabel ,
7
7
} ;
8
8
use syntax:: ast:: edit:: AstNodeEdit ;
@@ -43,8 +43,6 @@ use syntax::ast::edit::AstNodeEdit;
43
43
// }
44
44
// ```
45
45
pub ( crate ) fn generate_delegate_methods ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
46
- let cap = ctx. config . snippet_cap ?;
47
-
48
46
let strukt = ctx. find_node_at_offset :: < ast:: Struct > ( ) ?;
49
47
let strukt_name = strukt. name ( ) ?;
50
48
@@ -57,8 +55,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
57
55
None => {
58
56
let field = ctx. find_node_at_offset :: < ast:: TupleField > ( ) ?;
59
57
let field_list = ctx. find_node_at_offset :: < ast:: TupleFieldList > ( ) ?;
60
- let field_list_index =
61
- field_list. syntax ( ) . children ( ) . into_iter ( ) . position ( |s| & s == field. syntax ( ) ) ?;
58
+ let field_list_index = field_list. fields ( ) . position ( |it| it == field) ?;
62
59
let field_ty = field. ty ( ) ?;
63
60
( format ! ( "{}" , field_list_index) , field_ty)
64
61
}
@@ -73,16 +70,14 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
73
70
methods. push ( f)
74
71
}
75
72
}
76
- Some ( ( ) )
73
+ Option :: < ( ) > :: None
77
74
} ) ;
78
75
79
76
let target = field_ty. syntax ( ) . text_range ( ) ;
80
77
for method in methods {
81
- let impl_def = find_struct_impl (
82
- ctx,
83
- & ast:: Adt :: Struct ( strukt. clone ( ) ) ,
84
- & method. name ( ctx. db ( ) ) . to_string ( ) ,
85
- ) ?;
78
+ let adt = ast:: Adt :: Struct ( strukt. clone ( ) ) ;
79
+ let name = method. name ( ctx. db ( ) ) . to_string ( ) ;
80
+ let impl_def = find_struct_impl ( ctx, & adt, & name) . flatten ( ) ;
86
81
acc. add_group (
87
82
& GroupLabel ( "Generate delegate methods…" . to_owned ( ) ) ,
88
83
AssistId ( "generate_delegate_methods" , AssistKind :: Generate ) ,
@@ -99,15 +94,22 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
99
94
let name = make:: name ( & method. name ( ctx. db ( ) ) . to_string ( ) ) ;
100
95
let params =
101
96
method_source. param_list ( ) . unwrap_or_else ( || make:: param_list ( None , [ ] ) ) ;
97
+ let type_params = method_source. generic_param_list ( ) ;
98
+ let arg_list = match method_source. param_list ( ) {
99
+ Some ( list) => convert_param_list_to_arg_list ( list) ,
100
+ None => make:: arg_list ( [ ] ) ,
101
+ } ;
102
102
let tail_expr = make:: expr_method_call (
103
103
make:: ext:: field_from_idents ( [ "self" , & field_name] ) . unwrap ( ) , // This unwrap is ok because we have at least 1 arg in the list
104
104
make:: name_ref ( & method_name. to_string ( ) ) ,
105
- make :: arg_list ( [ ] ) ,
105
+ arg_list,
106
106
) ;
107
- let type_params = method_source. generic_param_list ( ) ;
108
107
let body = make:: block_expr ( [ ] , Some ( tail_expr) ) ;
109
108
let ret_type = method. ret_type ( ctx. db ( ) ) ;
110
109
let ret_type = if ret_type. is_unknown ( ) {
110
+ // FIXME: we currently can't resolve certain generics, and
111
+ // are returning placeholders instead. We should fix our
112
+ // type resolution here, so we return fewer placeholders.
111
113
Some ( make:: ret_type ( make:: ty_placeholder ( ) ) )
112
114
} else {
113
115
let ret_type = & ret_type. display ( ctx. db ( ) ) . to_string ( ) ;
@@ -133,8 +135,15 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
133
135
assoc_items. add_item ( f. clone ( ) . into ( ) ) ;
134
136
135
137
// Update the impl block.
136
- let snippet = render_snippet ( cap, impl_def. syntax ( ) , cursor) ;
137
- builder. replace_snippet ( cap, old_range, snippet) ;
138
+ match ctx. config . snippet_cap {
139
+ Some ( cap) => {
140
+ let snippet = render_snippet ( cap, impl_def. syntax ( ) , cursor) ;
141
+ builder. replace_snippet ( cap, old_range, snippet) ;
142
+ }
143
+ None => {
144
+ builder. replace ( old_range, impl_def. syntax ( ) . to_string ( ) ) ;
145
+ }
146
+ }
138
147
}
139
148
None => {
140
149
// Attach the function to the impl block
@@ -147,10 +156,19 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
147
156
assoc_items. add_item ( f. clone ( ) . into ( ) ) ;
148
157
149
158
// Insert the impl block.
150
- let offset = strukt. syntax ( ) . text_range ( ) . end ( ) ;
151
- let snippet = render_snippet ( cap, impl_def. syntax ( ) , cursor) ;
152
- let snippet = format ! ( "\n \n {}" , snippet) ;
153
- builder. insert_snippet ( cap, offset, snippet) ;
159
+ match ctx. config . snippet_cap {
160
+ Some ( cap) => {
161
+ let offset = strukt. syntax ( ) . text_range ( ) . end ( ) ;
162
+ let snippet = render_snippet ( cap, impl_def. syntax ( ) , cursor) ;
163
+ let snippet = format ! ( "\n \n {}" , snippet) ;
164
+ builder. insert_snippet ( cap, offset, snippet) ;
165
+ }
166
+ None => {
167
+ let offset = strukt. syntax ( ) . text_range ( ) . end ( ) ;
168
+ let snippet = format ! ( "\n \n {}" , impl_def. syntax( ) . to_string( ) ) ;
169
+ builder. insert ( offset, snippet) ;
170
+ }
171
+ }
154
172
}
155
173
}
156
174
} ,
@@ -297,7 +315,7 @@ struct Person<T> {
297
315
298
316
impl<T> Person<T> {
299
317
$0pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> _ {
300
- self.age.age()
318
+ self.age.age(ty, arg )
301
319
}
302
320
}"# ,
303
321
) ;
0 commit comments