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;
@@ -8,7 +8,7 @@ use syntax::{
88 edit:: { AstNodeEdit , IndentLevel } ,
99 make, ArgListOwner , AstNode , ModuleItemOwner ,
1010 } ,
11- SyntaxKind , SyntaxNode , TextSize ,
11+ SyntaxKind , SyntaxNode , TextRange , TextSize ,
1212} ;
1313
1414use crate :: {
@@ -87,21 +87,7 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
8787
8888 let function_builder = FunctionBuilder :: from_call ( ctx, & call, & path, target_module) ?;
8989 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 )
10591}
10692
10793fn gen_method ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
@@ -132,50 +118,46 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
132118 current_module,
133119 ) ?;
134120 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+ }
135124
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 < ( ) > {
136132 acc. add (
137133 AssistId ( "generate_function" , AssistKind :: Generate ) ,
138134 format ! ( "Generate `{}` method" , function_builder. fn_name) ,
139135 target,
140136 |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) ;
146141 }
142+ builder. edit_file ( file) ;
147143 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 ) ,
150146 }
151147 } ,
152148 )
153149}
154150
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-
167151fn current_module ( current_node : & SyntaxNode , ctx : & AssistContext ) -> Option < Module > {
168152 ctx. sema . scope ( current_node) . module ( )
169153}
170154
171155struct FunctionTemplate {
172- insert_offset : TextSize ,
173156 leading_ws : String ,
174157 fn_def : ast:: Fn ,
175158 ret_type : Option < ast:: RetType > ,
176159 should_focus_return_type : bool ,
177160 trailing_ws : String ,
178- file : FileId ,
179161 tail_expr : ast:: Expr ,
180162}
181163
@@ -300,7 +282,7 @@ impl FunctionBuilder {
300282 } )
301283 }
302284
303- fn render ( self ) -> FunctionTemplate {
285+ fn render ( self ) -> ( FunctionTemplate , TextSize , FileId ) {
304286 let placeholder_expr = make:: ext:: expr_todo ( ) ;
305287 let fn_body = make:: block_expr ( vec ! [ ] , Some ( placeholder_expr) ) ;
306288 let visibility = if self . needs_pub { Some ( make:: visibility_pub_crate ( ) ) } else { None } ;
@@ -333,17 +315,19 @@ impl FunctionBuilder {
333315 }
334316 } ;
335317
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+ } ,
337328 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+ )
347331 }
348332}
349333
0 commit comments