1- use hir:: { HasSource , HirDisplay , InFile , Module , TypeInfo } ;
1+ use hir:: { HasSource , HirDisplay , Module , TypeInfo } ;
22use ide_db:: { base_db:: FileId , helpers:: SnippetCap } ;
33use rustc_hash:: { FxHashMap , FxHashSet } ;
44use stdx:: to_lower_snake_case;
@@ -106,31 +106,28 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
106106
107107fn gen_method ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
108108 let call: ast:: MethodCallExpr = ctx. find_node_at_offset ( ) ?;
109- let fn_name: ast:: NameRef = ast:: NameRef :: cast (
110- call. syntax ( ) . children ( ) . find ( |child| child. kind ( ) == SyntaxKind :: NAME_REF ) ?,
111- ) ?;
112- let ty = ctx. sema . type_of_expr ( & call. receiver ( ) ?) ?. original ( ) . strip_references ( ) . as_adt ( ) ?;
109+ let fn_name = call. name_ref ( ) ?;
110+ let adt = ctx. sema . type_of_expr ( & call. receiver ( ) ?) ?. original ( ) . strip_references ( ) . as_adt ( ) ?;
113111
114- let current_module =
115- ctx. sema . scope ( ctx. find_node_at_offset :: < ast:: MethodCallExpr > ( ) ?. syntax ( ) ) . module ( ) ?;
116- let target_module = ty. module ( ctx. sema . db ) ;
112+ let current_module = ctx. sema . scope ( call. syntax ( ) ) . module ( ) ?;
113+ let target_module = adt. module ( ctx. sema . db ) ;
117114
118115 if current_module. krate ( ) != target_module. krate ( ) {
119116 return None ;
120117 }
121118
122- let ( impl_ , file ) = match ty {
123- hir :: Adt :: Struct ( strukt ) => get_impl ( strukt . source ( ctx. sema . db ) ? . syntax ( ) , & fn_name , ctx ) ,
124- hir :: Adt :: Enum ( en ) => get_impl ( en . source ( ctx . sema . db ) ? . syntax ( ) , & fn_name , ctx ) ,
125- hir :: Adt :: Union ( union ) => get_impl ( union . source ( ctx. sema . db ) ? . syntax ( ) , & fn_name , ctx ) ,
126- } ?;
119+ let range = adt . source ( ctx . sema . db ) ? . syntax ( ) . original_file_range ( ctx . sema . db ) ;
120+ let file = ctx. sema . parse ( range . file_id ) ;
121+ let adt_source =
122+ ctx. sema . find_node_at_offset_with_macros ( file . syntax ( ) , range . range . start ( ) ) ? ;
123+ let impl_ = find_struct_impl ( ctx , & adt_source , fn_name . text ( ) . as_str ( ) ) ?;
127124
128125 let function_builder = FunctionBuilder :: from_method_call (
129126 ctx,
130127 & call,
131128 & fn_name,
132129 & impl_,
133- file ,
130+ range . file_id ,
134131 target_module,
135132 current_module,
136133 ) ?;
@@ -145,7 +142,7 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
145142 builder. edit_file ( function_template. file ) ;
146143 let mut new_fn = function_template. to_string ( ctx. config . snippet_cap ) ;
147144 if impl_. is_none ( ) {
148- new_fn = format ! ( "\n impl {} {{\n {}\n }}" , ty . name( ctx. sema. db) , new_fn, ) ;
145+ new_fn = format ! ( "\n impl {} {{\n {}\n }}" , adt . name( ctx. sema. db) , new_fn, ) ;
149146 }
150147 match ctx. config . snippet_cap {
151148 Some ( cap) => builder. insert_snippet ( cap, function_template. insert_offset , new_fn) ,
@@ -155,18 +152,6 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
155152 )
156153}
157154
158- fn get_impl (
159- adt : InFile < & SyntaxNode > ,
160- fn_name : & ast:: NameRef ,
161- ctx : & AssistContext ,
162- ) -> Option < ( Option < ast:: Impl > , FileId ) > {
163- let file = adt. file_id . original_file ( ctx. sema . db ) ;
164- let adt = adt. value ;
165- let adt = ast:: Adt :: cast ( adt. clone ( ) ) ?;
166- let r = find_struct_impl ( ctx, & adt, fn_name. text ( ) . as_str ( ) ) ?;
167- Some ( ( r, file) )
168- }
169-
170155struct FunctionTemplate {
171156 insert_offset : TextSize ,
172157 leading_ws : String ,
0 commit comments