@@ -4,12 +4,12 @@ use ide_db::{
44} ;
55use syntax:: {
66 ast:: { self , AstNode , HasName , HasVisibility , StructKind , edit_in_place:: Indent , make} ,
7- ted ,
7+ syntax_editor :: Position ,
88} ;
99
1010use crate :: {
1111 AssistContext , AssistId , Assists ,
12- utils:: { find_struct_impl, generate_impl } ,
12+ utils:: { find_struct_impl, generate_impl_with_item } ,
1313} ;
1414
1515// Assist: generate_new
@@ -149,7 +149,53 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
149149 . clone_for_update ( ) ;
150150 fn_. indent ( 1 . into ( ) ) ;
151151
152- if let Some ( cap) = ctx. config . snippet_cap {
152+ let mut editor = builder. make_editor ( strukt. syntax ( ) ) ;
153+
154+ // Get the node for set annotation
155+ let contain_fn = if let Some ( impl_def) = impl_def {
156+ fn_. indent ( impl_def. indent_level ( ) ) ;
157+
158+ if let Some ( l_curly) = impl_def. assoc_item_list ( ) . and_then ( |list| list. l_curly_token ( ) )
159+ {
160+ editor. insert_all (
161+ Position :: after ( l_curly) ,
162+ vec ! [
163+ make:: tokens:: whitespace( & format!( "\n {}" , impl_def. indent_level( ) + 1 ) )
164+ . into( ) ,
165+ fn_. syntax( ) . clone( ) . into( ) ,
166+ make:: tokens:: whitespace( "\n " ) . into( ) ,
167+ ] ,
168+ ) ;
169+ fn_. syntax ( ) . clone ( )
170+ } else {
171+ let items = vec ! [ either:: Either :: Right ( ast:: AssocItem :: Fn ( fn_) ) ] ;
172+ let list = make:: assoc_item_list ( Some ( items) ) ;
173+ editor. insert ( Position :: after ( impl_def. syntax ( ) ) , list. syntax ( ) ) ;
174+ list. syntax ( ) . clone ( )
175+ }
176+ } else {
177+ // Generate a new impl to add the method to
178+ let indent_level = strukt. indent_level ( ) ;
179+ let body = vec ! [ either:: Either :: Right ( ast:: AssocItem :: Fn ( fn_) ) ] ;
180+ let list = make:: assoc_item_list ( Some ( body) ) ;
181+ let impl_def = generate_impl_with_item ( & ast:: Adt :: Struct ( strukt. clone ( ) ) , Some ( list) ) ;
182+
183+ impl_def. indent ( strukt. indent_level ( ) ) ;
184+
185+ // Insert it after the adt
186+ editor. insert_all (
187+ Position :: after ( strukt. syntax ( ) ) ,
188+ vec ! [
189+ make:: tokens:: whitespace( & format!( "\n \n {indent_level}" ) ) . into( ) ,
190+ impl_def. syntax( ) . clone( ) . into( ) ,
191+ ] ,
192+ ) ;
193+ impl_def. syntax ( ) . clone ( )
194+ } ;
195+
196+ if let Some ( fn_) = contain_fn. descendants ( ) . find_map ( ast:: Fn :: cast)
197+ && let Some ( cap) = ctx. config . snippet_cap
198+ {
153199 match strukt. kind ( ) {
154200 StructKind :: Tuple ( _) => {
155201 let struct_args = fn_
@@ -168,8 +214,8 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
168214 for ( struct_arg, fn_param) in struct_args. zip ( fn_params. params ( ) ) {
169215 if let Some ( fn_pat) = fn_param. pat ( ) {
170216 let fn_pat = fn_pat. syntax ( ) . clone ( ) ;
171- builder
172- . add_placeholder_snippet_group ( cap , vec ! [ struct_arg, fn_pat] ) ;
217+ let placeholder = builder. make_placeholder_snippet ( cap ) ;
218+ editor . add_annotation_all ( vec ! [ struct_arg, fn_pat] , placeholder )
173219 }
174220 }
175221 }
@@ -179,36 +225,12 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
179225
180226 // Add a tabstop before the name
181227 if let Some ( name) = fn_. name ( ) {
182- builder. add_tabstop_before ( cap, name) ;
228+ let tabstop_before = builder. make_tabstop_before ( cap) ;
229+ editor. add_annotation ( name. syntax ( ) , tabstop_before) ;
183230 }
184231 }
185232
186- // Get the mutable version of the impl to modify
187- let impl_def = if let Some ( impl_def) = impl_def {
188- fn_. indent ( impl_def. indent_level ( ) ) ;
189- builder. make_mut ( impl_def)
190- } else {
191- // Generate a new impl to add the method to
192- let impl_def = generate_impl ( & ast:: Adt :: Struct ( strukt. clone ( ) ) ) ;
193- let indent_level = strukt. indent_level ( ) ;
194- fn_. indent ( indent_level) ;
195-
196- // Insert it after the adt
197- let strukt = builder. make_mut ( strukt. clone ( ) ) ;
198-
199- ted:: insert_all_raw (
200- ted:: Position :: after ( strukt. syntax ( ) ) ,
201- vec ! [
202- make:: tokens:: whitespace( & format!( "\n \n {indent_level}" ) ) . into( ) ,
203- impl_def. syntax( ) . clone( ) . into( ) ,
204- ] ,
205- ) ;
206-
207- impl_def
208- } ;
209-
210- // Add the `new` method at the start of the impl
211- impl_def. get_or_create_assoc_item_list ( ) . add_item_at_start ( fn_. into ( ) ) ;
233+ builder. add_file_edits ( ctx. vfs_file_id ( ) , editor) ;
212234 } )
213235}
214236
0 commit comments