@@ -4,13 +4,13 @@ use ra_syntax::{
44 ast:: {
55 self ,
66 edit:: { AstNodeEdit , IndentLevel } ,
7- ArgListOwner , AstNode , ModuleItemOwner ,
7+ make , ArgListOwner , AstNode , ModuleItemOwner ,
88 } ,
99 SyntaxKind , SyntaxNode , TextSize ,
1010} ;
1111use rustc_hash:: { FxHashMap , FxHashSet } ;
1212
13- use crate :: { utils:: render_snippet, AssistContext , AssistId , Assists } ;
13+ use crate :: { assist_config :: SnippetCap , utils:: render_snippet, AssistContext , AssistId , Assists } ;
1414
1515// Assist: add_function
1616//
@@ -61,27 +61,33 @@ pub(crate) fn add_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
6161 acc. add ( AssistId ( "add_function" ) , "Add function" , target, |builder| {
6262 let function_template = function_builder. render ( ) ;
6363 builder. set_file ( function_template. file ) ;
64+ let new_fn = function_template. to_string ( ctx. config . snippet_cap ) ;
6465 match ctx. config . snippet_cap {
65- Some ( cap) => {
66- let snippet = render_snippet (
67- function_template. fn_def . syntax ( ) ,
68- function_template. placeholder_expr . syntax ( ) ,
69- ) ;
70- builder. insert_snippet ( cap, function_template. insert_offset , snippet)
71- }
72- None => builder
73- . insert ( function_template. insert_offset , function_template. fn_def . to_string ( ) ) ,
66+ Some ( cap) => builder. insert_snippet ( cap, function_template. insert_offset , new_fn) ,
67+ None => builder. insert ( function_template. insert_offset , new_fn) ,
7468 }
7569 } )
7670}
7771
7872struct FunctionTemplate {
7973 insert_offset : TextSize ,
80- fn_def : ast:: SourceFile ,
8174 placeholder_expr : ast:: MacroCall ,
75+ leading_ws : String ,
76+ fn_def : ast:: FnDef ,
77+ trailing_ws : String ,
8278 file : FileId ,
8379}
8480
81+ impl FunctionTemplate {
82+ fn to_string ( & self , cap : Option < SnippetCap > ) -> String {
83+ let f = match cap {
84+ Some ( cap) => render_snippet ( cap, self . fn_def . syntax ( ) , self . placeholder_expr . syntax ( ) ) ,
85+ None => self . fn_def . to_string ( ) ,
86+ } ;
87+ format ! ( "{}{}{}" , self . leading_ws, f, self . trailing_ws)
88+ }
89+ }
90+
8591struct FunctionBuilder {
8692 target : GeneratedFunctionTarget ,
8793 fn_name : ast:: Name ,
@@ -119,33 +125,41 @@ impl FunctionBuilder {
119125 }
120126
121127 fn render ( self ) -> FunctionTemplate {
122- let placeholder_expr = ast:: make:: expr_todo ( ) ;
123- let fn_body = ast:: make:: block_expr ( vec ! [ ] , Some ( placeholder_expr) ) ;
124- let mut fn_def = ast:: make:: fn_def ( self . fn_name , self . type_params , self . params , fn_body) ;
125- if self . needs_pub {
126- fn_def = ast:: make:: add_pub_crate_modifier ( fn_def) ;
127- }
128-
129- let ( fn_def, insert_offset) = match self . target {
128+ let placeholder_expr = make:: expr_todo ( ) ;
129+ let fn_body = make:: block_expr ( vec ! [ ] , Some ( placeholder_expr) ) ;
130+ let visibility = if self . needs_pub { Some ( make:: visibility_pub_crate ( ) ) } else { None } ;
131+ let mut fn_def =
132+ make:: fn_def ( visibility, self . fn_name , self . type_params , self . params , fn_body) ;
133+ let leading_ws;
134+ let trailing_ws;
135+
136+ let insert_offset = match self . target {
130137 GeneratedFunctionTarget :: BehindItem ( it) => {
131- let with_leading_blank_line = ast:: make:: add_leading_newlines ( 2 , fn_def) ;
132- let indented = with_leading_blank_line. indent ( IndentLevel :: from_node ( & it) ) ;
133- ( indented, it. text_range ( ) . end ( ) )
138+ let indent = IndentLevel :: from_node ( & it) ;
139+ leading_ws = format ! ( "\n \n {}" , indent) ;
140+ fn_def = fn_def. indent ( indent) ;
141+ trailing_ws = String :: new ( ) ;
142+ it. text_range ( ) . end ( )
134143 }
135144 GeneratedFunctionTarget :: InEmptyItemList ( it) => {
136- let indent_once = IndentLevel ( 1 ) ;
137145 let indent = IndentLevel :: from_node ( it. syntax ( ) ) ;
138- let fn_def = ast:: make:: add_leading_newlines ( 1 , fn_def) ;
139- let fn_def = fn_def. indent ( indent_once) ;
140- let fn_def = ast:: make:: add_trailing_newlines ( 1 , fn_def) ;
141- let fn_def = fn_def. indent ( indent) ;
142- ( fn_def, it. syntax ( ) . text_range ( ) . start ( ) + TextSize :: of ( '{' ) )
146+ leading_ws = format ! ( "\n {}" , indent + 1 ) ;
147+ fn_def = fn_def. indent ( indent + 1 ) ;
148+ trailing_ws = format ! ( "\n {}" , indent) ;
149+ it. syntax ( ) . text_range ( ) . start ( ) + TextSize :: of ( '{' )
143150 }
144151 } ;
145152
146153 let placeholder_expr =
147154 fn_def. syntax ( ) . descendants ( ) . find_map ( ast:: MacroCall :: cast) . unwrap ( ) ;
148- FunctionTemplate { insert_offset, placeholder_expr, fn_def, file : self . file }
155+ FunctionTemplate {
156+ insert_offset,
157+ placeholder_expr,
158+ leading_ws,
159+ fn_def,
160+ trailing_ws,
161+ file : self . file ,
162+ }
149163 }
150164}
151165
@@ -165,7 +179,7 @@ impl GeneratedFunctionTarget {
165179
166180fn fn_name ( call : & ast:: Path ) -> Option < ast:: Name > {
167181 let name = call. segment ( ) ?. syntax ( ) . to_string ( ) ;
168- Some ( ast :: make:: name ( & name) )
182+ Some ( make:: name ( & name) )
169183}
170184
171185/// Computes the type variables and arguments required for the generated function
@@ -187,8 +201,8 @@ fn fn_args(
187201 } ) ;
188202 }
189203 deduplicate_arg_names ( & mut arg_names) ;
190- let params = arg_names. into_iter ( ) . zip ( arg_types) . map ( |( name, ty) | ast :: make:: param ( name, ty) ) ;
191- Some ( ( None , ast :: make:: param_list ( params) ) )
204+ let params = arg_names. into_iter ( ) . zip ( arg_types) . map ( |( name, ty) | make:: param ( name, ty) ) ;
205+ Some ( ( None , make:: param_list ( params) ) )
192206}
193207
194208/// Makes duplicate argument names unique by appending incrementing numbers.
0 commit comments