@@ -6,7 +6,7 @@ use syntax::{
6
6
ast:: {
7
7
self ,
8
8
edit:: { AstNodeEdit , IndentLevel } ,
9
- make, ArgListOwner , AstNode , ModuleItemOwner ,
9
+ make, ArgListOwner , AstNode , CallExpr , ModuleItemOwner ,
10
10
} ,
11
11
SyntaxKind , SyntaxNode , TextRange , TextSize ,
12
12
} ;
@@ -85,10 +85,10 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
85
85
None => None ,
86
86
} ;
87
87
88
- let ( function_builder , inserting_offset , file ) =
89
- FunctionBuilder :: from_call ( ctx, & call, & path, target_module) ?;
88
+ let ( target , file , insert_offset ) = get_fn_target ( ctx , & target_module , call . clone ( ) ) ? ;
89
+ let function_builder = FunctionBuilder :: from_call ( ctx, & call, & path, target_module, target ) ?;
90
90
let target = call. syntax ( ) . text_range ( ) ;
91
- add_func_to_accumulator ( acc, ctx, target, function_builder, inserting_offset , file, None )
91
+ add_func_to_accumulator ( acc, ctx, target, function_builder, insert_offset , file, None )
92
92
}
93
93
94
94
fn gen_method ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
@@ -109,24 +109,26 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
109
109
ctx. sema . find_node_at_offset_with_macros ( file. syntax ( ) , range. range . start ( ) ) ?;
110
110
let impl_ = find_struct_impl ( ctx, & adt_source, fn_name. text ( ) . as_str ( ) ) ?;
111
111
112
- let ( function_builder, inserting_offset, file) = FunctionBuilder :: from_method_call (
112
+ let ( target, insert_offset) = get_method_target ( ctx, & target_module, & impl_) ?;
113
+ let function_builder =
114
+ FunctionBuilder :: from_method_call ( ctx, & call, & fn_name, target_module, target) ?;
115
+ let text_range = call. syntax ( ) . text_range ( ) ;
116
+ let adt_name = if impl_. is_none ( ) { Some ( adt. name ( ctx. sema . db ) ) } else { None } ;
117
+ add_func_to_accumulator (
118
+ acc,
113
119
ctx,
114
- & call ,
115
- & fn_name ,
116
- & impl_ ,
120
+ text_range ,
121
+ function_builder ,
122
+ insert_offset ,
117
123
range. file_id ,
118
- target_module,
119
- current_module,
120
- ) ?;
121
- let target = call. syntax ( ) . text_range ( ) ;
122
- let adt_name = if impl_. is_none ( ) { Some ( adt. name ( ctx. sema . db ) ) } else { None } ;
123
- add_func_to_accumulator ( acc, ctx, target, function_builder, inserting_offset, file, adt_name)
124
+ adt_name,
125
+ )
124
126
}
125
127
126
128
fn add_func_to_accumulator (
127
129
acc : & mut Assists ,
128
130
ctx : & AssistContext ,
129
- target : TextRange ,
131
+ text_range : TextRange ,
130
132
function_builder : FunctionBuilder ,
131
133
insert_offset : TextSize ,
132
134
file : FileId ,
@@ -135,7 +137,7 @@ fn add_func_to_accumulator(
135
137
acc. add (
136
138
AssistId ( "generate_function" , AssistKind :: Generate ) ,
137
139
format ! ( "Generate `{}` method" , function_builder. fn_name) ,
138
- target ,
140
+ text_range ,
139
141
|builder| {
140
142
let function_template = function_builder. render ( ) ;
141
143
let mut func = function_template. to_string ( ctx. config . snippet_cap ) ;
@@ -194,7 +196,6 @@ struct FunctionBuilder {
194
196
params : ast:: ParamList ,
195
197
ret_type : Option < ast:: RetType > ,
196
198
should_focus_return_type : bool ,
197
- file : FileId ,
198
199
needs_pub : bool ,
199
200
is_async : bool ,
200
201
}
@@ -207,17 +208,8 @@ impl FunctionBuilder {
207
208
call : & ast:: CallExpr ,
208
209
path : & ast:: Path ,
209
210
target_module : Option < hir:: Module > ,
210
- ) -> Option < ( Self , TextSize , FileId ) > {
211
- let mut file = ctx. frange . file_id ;
212
- let target = match & target_module {
213
- Some ( target_module) => {
214
- let module_source = target_module. definition_source ( ctx. db ( ) ) ;
215
- let ( in_file, target) = next_space_for_fn_in_module ( ctx. sema . db , & module_source) ?;
216
- file = in_file;
217
- target
218
- }
219
- None => next_space_for_fn_after_call_site ( FuncExpr :: Func ( call. clone ( ) ) ) ?,
220
- } ;
211
+ target : GeneratedFunctionTarget ,
212
+ ) -> Option < Self > {
221
213
let needs_pub = target_module. is_some ( ) ;
222
214
let target_module = target_module. or_else ( || current_module ( target. syntax ( ) , ctx) ) ?;
223
215
let fn_name = fn_name ( path) ?;
@@ -229,51 +221,27 @@ impl FunctionBuilder {
229
221
let ( ret_type, should_focus_return_type) =
230
222
make_return_type ( ctx, & ast:: Expr :: CallExpr ( call. clone ( ) ) , target_module) ;
231
223
232
- let insert_offset = match & target {
233
- GeneratedFunctionTarget :: BehindItem ( it) => it. text_range ( ) . end ( ) ,
234
- GeneratedFunctionTarget :: InEmptyItemList ( it) => {
235
- it. text_range ( ) . start ( ) + TextSize :: of ( '{' )
236
- }
237
- } ;
238
-
239
- Some ( (
240
- Self {
241
- target,
242
- fn_name,
243
- type_params,
244
- params,
245
- ret_type,
246
- should_focus_return_type,
247
- file,
248
- needs_pub,
249
- is_async,
250
- } ,
251
- insert_offset,
252
- file,
253
- ) )
224
+ Some ( Self {
225
+ target,
226
+ fn_name,
227
+ type_params,
228
+ params,
229
+ ret_type,
230
+ should_focus_return_type,
231
+ needs_pub,
232
+ is_async,
233
+ } )
254
234
}
255
235
256
236
fn from_method_call (
257
237
ctx : & AssistContext ,
258
238
call : & ast:: MethodCallExpr ,
259
239
name : & ast:: NameRef ,
260
- impl_ : & Option < ast:: Impl > ,
261
- file : FileId ,
262
240
target_module : Module ,
263
- current_module : Module ,
264
- ) -> Option < ( Self , TextSize , FileId ) > {
265
- let target = match impl_ {
266
- Some ( impl_) => next_space_for_fn_in_impl ( & impl_) ?,
267
- None => {
268
- next_space_for_fn_in_module (
269
- ctx. sema . db ,
270
- & target_module. definition_source ( ctx. sema . db ) ,
271
- ) ?
272
- . 1
273
- }
274
- } ;
275
- let needs_pub = !module_is_descendant ( & current_module, & target_module, ctx) ;
276
-
241
+ target : GeneratedFunctionTarget ,
242
+ ) -> Option < Self > {
243
+ let needs_pub =
244
+ !module_is_descendant ( & current_module ( call. syntax ( ) , ctx) ?, & target_module, ctx) ;
277
245
let fn_name = make:: name ( & name. text ( ) ) ;
278
246
let ( type_params, params) = fn_args ( ctx, target_module, FuncExpr :: Method ( call. clone ( ) ) ) ?;
279
247
@@ -283,28 +251,16 @@ impl FunctionBuilder {
283
251
let ( ret_type, should_focus_return_type) =
284
252
make_return_type ( ctx, & ast:: Expr :: MethodCallExpr ( call. clone ( ) ) , target_module) ;
285
253
286
- let insert_offset = match & target {
287
- GeneratedFunctionTarget :: BehindItem ( it) => it. text_range ( ) . end ( ) ,
288
- GeneratedFunctionTarget :: InEmptyItemList ( it) => {
289
- it. text_range ( ) . start ( ) + TextSize :: of ( '{' )
290
- }
291
- } ;
292
-
293
- Some ( (
294
- Self {
295
- target,
296
- fn_name,
297
- type_params,
298
- params,
299
- ret_type,
300
- should_focus_return_type,
301
- file,
302
- needs_pub,
303
- is_async,
304
- } ,
305
- insert_offset,
306
- file,
307
- ) )
254
+ Some ( Self {
255
+ target,
256
+ fn_name,
257
+ type_params,
258
+ params,
259
+ ret_type,
260
+ should_focus_return_type,
261
+ needs_pub,
262
+ is_async,
263
+ } )
308
264
}
309
265
310
266
fn render ( self ) -> FunctionTemplate {
@@ -382,6 +338,47 @@ fn make_return_type(
382
338
( ret_type, should_focus_return_type)
383
339
}
384
340
341
+ fn get_fn_target (
342
+ ctx : & AssistContext ,
343
+ target_module : & Option < Module > ,
344
+ call : CallExpr ,
345
+ ) -> Option < ( GeneratedFunctionTarget , FileId , TextSize ) > {
346
+ let mut file = ctx. frange . file_id ;
347
+ let target = match target_module {
348
+ Some ( target_module) => {
349
+ let module_source = target_module. definition_source ( ctx. db ( ) ) ;
350
+ let ( in_file, target) = next_space_for_fn_in_module ( ctx. sema . db , & module_source) ?;
351
+ file = in_file;
352
+ target
353
+ }
354
+ None => next_space_for_fn_after_call_site ( FuncExpr :: Func ( call. clone ( ) ) ) ?,
355
+ } ;
356
+ Some ( ( target. clone ( ) , file, get_insert_offset ( & target) ) )
357
+ }
358
+
359
+ fn get_method_target (
360
+ ctx : & AssistContext ,
361
+ target_module : & Module ,
362
+ impl_ : & Option < ast:: Impl > ,
363
+ ) -> Option < ( GeneratedFunctionTarget , TextSize ) > {
364
+ let target = match impl_ {
365
+ Some ( impl_) => next_space_for_fn_in_impl ( & impl_) ?,
366
+ None => {
367
+ next_space_for_fn_in_module ( ctx. sema . db , & target_module. definition_source ( ctx. sema . db ) ) ?
368
+ . 1
369
+ }
370
+ } ;
371
+ Some ( ( target. clone ( ) , get_insert_offset ( & target) ) )
372
+ }
373
+
374
+ fn get_insert_offset ( target : & GeneratedFunctionTarget ) -> TextSize {
375
+ match & target {
376
+ GeneratedFunctionTarget :: BehindItem ( it) => it. text_range ( ) . end ( ) ,
377
+ GeneratedFunctionTarget :: InEmptyItemList ( it) => it. text_range ( ) . start ( ) + TextSize :: of ( '{' ) ,
378
+ }
379
+ }
380
+
381
+ #[ derive( Clone ) ]
385
382
enum GeneratedFunctionTarget {
386
383
BehindItem ( SyntaxNode ) ,
387
384
InEmptyItemList ( SyntaxNode ) ,
0 commit comments