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;
@@ -8,7 +8,7 @@ use syntax::{
8
8
edit:: { AstNodeEdit , IndentLevel } ,
9
9
make, ArgListOwner , AstNode , ModuleItemOwner ,
10
10
} ,
11
- SyntaxKind , SyntaxNode , TextSize ,
11
+ SyntaxKind , SyntaxNode , TextRange , TextSize ,
12
12
} ;
13
13
14
14
use crate :: {
@@ -87,21 +87,7 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
87
87
88
88
let function_builder = FunctionBuilder :: from_call ( ctx, & call, & path, target_module) ?;
89
89
let target = call. syntax ( ) . text_range ( ) ;
90
-
91
- acc. add (
92
- AssistId ( "generate_function" , AssistKind :: Generate ) ,
93
- format ! ( "Generate `{}` function" , function_builder. fn_name) ,
94
- target,
95
- |builder| {
96
- let function_template = function_builder. render ( ) ;
97
- builder. edit_file ( function_template. file ) ;
98
- let new_fn = function_template. to_string ( ctx. config . snippet_cap ) ;
99
- match ctx. config . snippet_cap {
100
- Some ( cap) => builder. insert_snippet ( cap, function_template. insert_offset , new_fn) ,
101
- None => builder. insert ( function_template. insert_offset , new_fn) ,
102
- }
103
- } ,
104
- )
90
+ add_func_to_accumulator ( acc, ctx, target, function_builder, None )
105
91
}
106
92
107
93
fn gen_method ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
@@ -132,50 +118,46 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
132
118
current_module,
133
119
) ?;
134
120
let target = call. syntax ( ) . text_range ( ) ;
121
+ let adt_name = if impl_. is_none ( ) { Some ( adt. name ( ctx. sema . db ) ) } else { None } ;
122
+ add_func_to_accumulator ( acc, ctx, target, function_builder, adt_name)
123
+ }
135
124
125
+ fn add_func_to_accumulator (
126
+ acc : & mut Assists ,
127
+ ctx : & AssistContext ,
128
+ target : TextRange ,
129
+ function_builder : FunctionBuilder ,
130
+ adt_name : Option < hir:: Name > ,
131
+ ) -> Option < ( ) > {
136
132
acc. add (
137
133
AssistId ( "generate_function" , AssistKind :: Generate ) ,
138
134
format ! ( "Generate `{}` method" , function_builder. fn_name) ,
139
135
target,
140
136
|builder| {
141
- let function_template = function_builder. render ( ) ;
142
- builder. edit_file ( function_template. file ) ;
143
- let mut new_fn = function_template. to_string ( ctx. config . snippet_cap ) ;
144
- if impl_. is_none ( ) {
145
- new_fn = format ! ( "\n impl {} {{\n {}\n }}" , adt. name( ctx. sema. db) , new_fn, ) ;
137
+ let ( function_template, insert_offset, file) = function_builder. render ( ) ;
138
+ let mut func = function_template. to_string ( ctx. config . snippet_cap ) ;
139
+ if let Some ( name) = adt_name {
140
+ func = format ! ( "\n impl {} {{\n {}\n }}" , name, func) ;
146
141
}
142
+ builder. edit_file ( file) ;
147
143
match ctx. config . snippet_cap {
148
- Some ( cap) => builder. insert_snippet ( cap, function_template . insert_offset , new_fn ) ,
149
- None => builder. insert ( function_template . insert_offset , new_fn ) ,
144
+ Some ( cap) => builder. insert_snippet ( cap, insert_offset, func ) ,
145
+ None => builder. insert ( insert_offset, func ) ,
150
146
}
151
147
} ,
152
148
)
153
149
}
154
150
155
- fn get_impl (
156
- adt : InFile < & SyntaxNode > ,
157
- fn_name : & ast:: NameRef ,
158
- ctx : & AssistContext ,
159
- ) -> Option < ( Option < ast:: Impl > , FileId ) > {
160
- let file = adt. file_id . original_file ( ctx. sema . db ) ;
161
- let adt = adt. value ;
162
- let adt = ast:: Adt :: cast ( adt. clone ( ) ) ?;
163
- let r = find_struct_impl ( ctx, & adt, fn_name. text ( ) . as_str ( ) ) ?;
164
- Some ( ( r, file) )
165
- }
166
-
167
151
fn current_module ( current_node : & SyntaxNode , ctx : & AssistContext ) -> Option < Module > {
168
152
ctx. sema . scope ( current_node) . module ( )
169
153
}
170
154
171
155
struct FunctionTemplate {
172
- insert_offset : TextSize ,
173
156
leading_ws : String ,
174
157
fn_def : ast:: Fn ,
175
158
ret_type : Option < ast:: RetType > ,
176
159
should_focus_return_type : bool ,
177
160
trailing_ws : String ,
178
- file : FileId ,
179
161
tail_expr : ast:: Expr ,
180
162
}
181
163
@@ -300,7 +282,7 @@ impl FunctionBuilder {
300
282
} )
301
283
}
302
284
303
- fn render ( self ) -> FunctionTemplate {
285
+ fn render ( self ) -> ( FunctionTemplate , TextSize , FileId ) {
304
286
let placeholder_expr = make:: ext:: expr_todo ( ) ;
305
287
let fn_body = make:: block_expr ( vec ! [ ] , Some ( placeholder_expr) ) ;
306
288
let visibility = if self . needs_pub { Some ( make:: visibility_pub_crate ( ) ) } else { None } ;
@@ -333,17 +315,19 @@ impl FunctionBuilder {
333
315
}
334
316
} ;
335
317
336
- FunctionTemplate {
318
+ (
319
+ FunctionTemplate {
320
+ leading_ws,
321
+ ret_type : fn_def. ret_type ( ) ,
322
+ // PANIC: we guarantee we always create a function body with a tail expr
323
+ tail_expr : fn_def. body ( ) . unwrap ( ) . tail_expr ( ) . unwrap ( ) ,
324
+ should_focus_return_type : self . should_focus_return_type ,
325
+ fn_def,
326
+ trailing_ws,
327
+ } ,
337
328
insert_offset,
338
- leading_ws,
339
- ret_type : fn_def. ret_type ( ) ,
340
- // PANIC: we guarantee we always create a function body with a tail expr
341
- tail_expr : fn_def. body ( ) . unwrap ( ) . tail_expr ( ) . unwrap ( ) ,
342
- should_focus_return_type : self . should_focus_return_type ,
343
- fn_def,
344
- trailing_ws,
345
- file : self . file ,
346
- }
329
+ self . file ,
330
+ )
347
331
}
348
332
}
349
333
0 commit comments