@@ -85,9 +85,10 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
8585 None => None ,
8686 } ;
8787
88- let function_builder = FunctionBuilder :: from_call ( ctx, & call, & path, target_module) ?;
88+ let ( function_builder, inserting_offset, file) =
89+ FunctionBuilder :: from_call ( ctx, & call, & path, target_module) ?;
8990 let target = call. syntax ( ) . text_range ( ) ;
90- add_func_to_accumulator ( acc, ctx, target, function_builder, None )
91+ add_func_to_accumulator ( acc, ctx, target, function_builder, inserting_offset , file , None )
9192}
9293
9394fn gen_method ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
@@ -108,7 +109,7 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
108109 ctx. sema . find_node_at_offset_with_macros ( file. syntax ( ) , range. range . start ( ) ) ?;
109110 let impl_ = find_struct_impl ( ctx, & adt_source, fn_name. text ( ) . as_str ( ) ) ?;
110111
111- let function_builder = FunctionBuilder :: from_method_call (
112+ let ( function_builder, inserting_offset , file ) = FunctionBuilder :: from_method_call (
112113 ctx,
113114 & call,
114115 & fn_name,
@@ -119,22 +120,24 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
119120 ) ?;
120121 let target = call. syntax ( ) . text_range ( ) ;
121122 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+ add_func_to_accumulator ( acc, ctx, target, function_builder, inserting_offset , file , adt_name)
123124}
124125
125126fn add_func_to_accumulator (
126127 acc : & mut Assists ,
127128 ctx : & AssistContext ,
128129 target : TextRange ,
129130 function_builder : FunctionBuilder ,
131+ insert_offset : TextSize ,
132+ file : FileId ,
130133 adt_name : Option < hir:: Name > ,
131134) -> Option < ( ) > {
132135 acc. add (
133136 AssistId ( "generate_function" , AssistKind :: Generate ) ,
134137 format ! ( "Generate `{}` method" , function_builder. fn_name) ,
135138 target,
136139 |builder| {
137- let ( function_template, insert_offset , file ) = function_builder. render ( ) ;
140+ let function_template = function_builder. render ( ) ;
138141 let mut func = function_template. to_string ( ctx. config . snippet_cap ) ;
139142 if let Some ( name) = adt_name {
140143 func = format ! ( "\n impl {} {{\n {}\n }}" , name, func) ;
@@ -204,7 +207,7 @@ impl FunctionBuilder {
204207 call : & ast:: CallExpr ,
205208 path : & ast:: Path ,
206209 target_module : Option < hir:: Module > ,
207- ) -> Option < Self > {
210+ ) -> Option < ( Self , TextSize , FileId ) > {
208211 let mut file = ctx. frange . file_id ;
209212 let target = match & target_module {
210213 Some ( target_module) => {
@@ -226,17 +229,28 @@ impl FunctionBuilder {
226229 let ( ret_type, should_focus_return_type) =
227230 make_return_type ( ctx, & ast:: Expr :: CallExpr ( call. clone ( ) ) , target_module) ;
228231
229- Some ( Self {
230- target,
231- fn_name,
232- type_params,
233- params,
234- ret_type,
235- should_focus_return_type,
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,
236252 file,
237- needs_pub,
238- is_async,
239- } )
253+ ) )
240254 }
241255
242256 fn from_method_call (
@@ -247,7 +261,7 @@ impl FunctionBuilder {
247261 file : FileId ,
248262 target_module : Module ,
249263 current_module : Module ,
250- ) -> Option < Self > {
264+ ) -> Option < ( Self , TextSize , FileId ) > {
251265 let target = match impl_ {
252266 Some ( impl_) => next_space_for_fn_in_impl ( & impl_) ?,
253267 None => {
@@ -269,20 +283,31 @@ impl FunctionBuilder {
269283 let ( ret_type, should_focus_return_type) =
270284 make_return_type ( ctx, & ast:: Expr :: MethodCallExpr ( call. clone ( ) ) , target_module) ;
271285
272- Some ( Self {
273- target,
274- fn_name,
275- type_params,
276- params,
277- ret_type,
278- should_focus_return_type,
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,
279306 file,
280- needs_pub,
281- is_async,
282- } )
307+ ) )
283308 }
284309
285- fn render ( self ) -> ( FunctionTemplate , TextSize , FileId ) {
310+ fn render ( self ) -> FunctionTemplate {
286311 let placeholder_expr = make:: ext:: expr_todo ( ) ;
287312 let fn_body = make:: block_expr ( vec ! [ ] , Some ( placeholder_expr) ) ;
288313 let visibility = if self . needs_pub { Some ( make:: visibility_pub_crate ( ) ) } else { None } ;
@@ -298,36 +323,30 @@ impl FunctionBuilder {
298323 let leading_ws;
299324 let trailing_ws;
300325
301- let insert_offset = match self . target {
326+ match self . target {
302327 GeneratedFunctionTarget :: BehindItem ( it) => {
303328 let indent = IndentLevel :: from_node ( & it) ;
304329 leading_ws = format ! ( "\n \n {}" , indent) ;
305330 fn_def = fn_def. indent ( indent) ;
306331 trailing_ws = String :: new ( ) ;
307- it. text_range ( ) . end ( )
308332 }
309333 GeneratedFunctionTarget :: InEmptyItemList ( it) => {
310334 let indent = IndentLevel :: from_node ( & it) ;
311335 leading_ws = format ! ( "\n {}" , indent + 1 ) ;
312336 fn_def = fn_def. indent ( indent + 1 ) ;
313337 trailing_ws = format ! ( "\n {}" , indent) ;
314- it. text_range ( ) . start ( ) + TextSize :: of ( '{' )
315338 }
316339 } ;
317340
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- } ,
328- insert_offset,
329- self . file ,
330- )
341+ FunctionTemplate {
342+ leading_ws,
343+ ret_type : fn_def. ret_type ( ) ,
344+ // PANIC: we guarantee we always create a function body with a tail expr
345+ tail_expr : fn_def. body ( ) . unwrap ( ) . tail_expr ( ) . unwrap ( ) ,
346+ should_focus_return_type : self . should_focus_return_type ,
347+ fn_def,
348+ trailing_ws,
349+ }
331350 }
332351}
333352
0 commit comments