1
- use hir:: { HasSource , HirDisplay , InFile , Module , TypeInfo } ;
1
+ use hir:: { HasSource , HirDisplay , Module , TypeInfo } ;
2
2
use ide_db:: { base_db:: FileId , helpers:: SnippetCap } ;
3
3
use rustc_hash:: { FxHashMap , FxHashSet } ;
4
4
use stdx:: to_lower_snake_case;
@@ -106,31 +106,28 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
106
106
107
107
fn gen_method ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
108
108
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 ( ) ?;
113
111
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 ) ;
117
114
118
115
if current_module. krate ( ) != target_module. krate ( ) {
119
116
return None ;
120
117
}
121
118
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 ( ) ) ?;
127
124
128
125
let function_builder = FunctionBuilder :: from_method_call (
129
126
ctx,
130
127
& call,
131
128
& fn_name,
132
129
& impl_,
133
- file ,
130
+ range . file_id ,
134
131
target_module,
135
132
current_module,
136
133
) ?;
@@ -145,7 +142,7 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
145
142
builder. edit_file ( function_template. file ) ;
146
143
let mut new_fn = function_template. to_string ( ctx. config . snippet_cap ) ;
147
144
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, ) ;
149
146
}
150
147
match ctx. config . snippet_cap {
151
148
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<()> {
155
152
)
156
153
}
157
154
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
-
170
155
struct FunctionTemplate {
171
156
insert_offset : TextSize ,
172
157
leading_ws : String ,
0 commit comments