@@ -2,7 +2,7 @@ use hir::{self, HasCrate, HasSource, HirDisplay};
22use syntax:: ast:: { self , make, AstNode , HasGenericParams , HasName , HasVisibility } ;
33
44use crate :: {
5- utils:: { find_struct_impl, render_snippet, Cursor } ,
5+ utils:: { convert_param_list_to_arg_list , find_struct_impl, render_snippet, Cursor } ,
66 AssistContext , AssistId , AssistKind , Assists , GroupLabel ,
77} ;
88use syntax:: ast:: edit:: AstNodeEdit ;
@@ -43,8 +43,6 @@ use syntax::ast::edit::AstNodeEdit;
4343// }
4444// ```
4545pub ( crate ) fn generate_delegate_methods ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
46- let cap = ctx. config . snippet_cap ?;
47-
4846 let strukt = ctx. find_node_at_offset :: < ast:: Struct > ( ) ?;
4947 let strukt_name = strukt. name ( ) ?;
5048
@@ -57,8 +55,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
5755 None => {
5856 let field = ctx. find_node_at_offset :: < ast:: TupleField > ( ) ?;
5957 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) ?;
6259 let field_ty = field. ty ( ) ?;
6360 ( format ! ( "{}" , field_list_index) , field_ty)
6461 }
@@ -73,16 +70,14 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
7370 methods. push ( f)
7471 }
7572 }
76- Some ( ( ) )
73+ Option :: < ( ) > :: None
7774 } ) ;
7875
7976 let target = field_ty. syntax ( ) . text_range ( ) ;
8077 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 ( ) ;
8681 acc. add_group (
8782 & GroupLabel ( "Generate delegate methods…" . to_owned ( ) ) ,
8883 AssistId ( "generate_delegate_methods" , AssistKind :: Generate ) ,
@@ -99,15 +94,22 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
9994 let name = make:: name ( & method. name ( ctx. db ( ) ) . to_string ( ) ) ;
10095 let params =
10196 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+ } ;
102102 let tail_expr = make:: expr_method_call (
103103 make:: ext:: field_from_idents ( [ "self" , & field_name] ) . unwrap ( ) , // This unwrap is ok because we have at least 1 arg in the list
104104 make:: name_ref ( & method_name. to_string ( ) ) ,
105- make :: arg_list ( [ ] ) ,
105+ arg_list,
106106 ) ;
107- let type_params = method_source. generic_param_list ( ) ;
108107 let body = make:: block_expr ( [ ] , Some ( tail_expr) ) ;
109108 let ret_type = method. ret_type ( ctx. db ( ) ) ;
110109 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.
111113 Some ( make:: ret_type ( make:: ty_placeholder ( ) ) )
112114 } else {
113115 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)
133135 assoc_items. add_item ( f. clone ( ) . into ( ) ) ;
134136
135137 // 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+ }
138147 }
139148 None => {
140149 // Attach the function to the impl block
@@ -147,10 +156,19 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
147156 assoc_items. add_item ( f. clone ( ) . into ( ) ) ;
148157
149158 // 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+ }
154172 }
155173 }
156174 } ,
@@ -297,7 +315,7 @@ struct Person<T> {
297315
298316impl<T> Person<T> {
299317 $0pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> _ {
300- self.age.age()
318+ self.age.age(ty, arg )
301319 }
302320}"# ,
303321 ) ;
0 commit comments