@@ -3,11 +3,12 @@ use crate::{
33 AssistId ,
44} ;
55use ide_db:: helpers:: FamousDefs ;
6+ use itertools:: Itertools ;
7+ use stdx:: format_to;
68use syntax:: {
7- ast:: { self , Impl , NameOwner } ,
9+ ast:: { self , AttrsOwner , GenericParamsOwner , Impl , NameOwner , TypeBoundsOwner } ,
810 AstNode ,
911} ;
10- use crate :: utils:: generate_trait_impl_text;
1112
1213// Assist: generate_default_from_new
1314//
@@ -60,37 +61,66 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext)
6061 }
6162
6263 let insert_location = impl_. syntax ( ) . text_range ( ) ;
63- let code = match ast:: Struct :: cast ( impl_. self_ty ( ) . unwrap ( ) . syntax ( ) . clone ( ) ) {
64- None => {
65- default_fn_node_for_new ( impl_)
66- }
67- Some ( strukt) => {
68- generate_trait_impl_text ( & ast:: Adt :: Struct ( strukt) , "core:default:Default" , " fn default() -> Self {{
69- Self::new()
70- }}" )
71- }
72- } ;
64+
7365 acc. add (
7466 AssistId ( "generate_default_from_new" , crate :: AssistKind :: Generate ) ,
7567 "Generate a Default impl from a new fn" ,
7668 insert_location,
7769 move |builder| {
70+ let default_code = " fn default() -> Self {
71+ Self::new()
72+ }" ;
73+ let code = generate_trait_impl_text_from_impl ( & impl_, "Default" , default_code) ;
7874 builder. insert ( insert_location. end ( ) , code) ;
7975 } ,
8076 )
8177}
8278
83- fn default_fn_node_for_new ( impl_ : Impl ) -> String {
84- format ! (
85- "
79+ fn generate_trait_impl_text_from_impl ( impl_ : & ast:: Impl , trait_text : & str , code : & str ) -> String {
80+ let generic_params = impl_. generic_param_list ( ) ;
81+ let mut buf = String :: with_capacity ( code. len ( ) ) ;
82+ buf. push_str ( "\n \n " ) ;
83+ impl_
84+ . attrs ( )
85+ . filter ( |attr| attr. as_simple_call ( ) . map ( |( name, _arg) | name == "cfg" ) . unwrap_or ( false ) )
86+ . for_each ( |attr| buf. push_str ( format ! ( "{}\n " , attr. to_string( ) ) . as_str ( ) ) ) ;
87+ buf. push_str ( "impl" ) ;
88+
89+ if let Some ( generic_params) = & generic_params {
90+ let lifetimes = generic_params. lifetime_params ( ) . map ( |lt| format ! ( "{}" , lt. syntax( ) ) ) ;
91+ let type_params = generic_params. type_params ( ) . map ( |type_param| {
92+ let mut buf = String :: new ( ) ;
93+ if let Some ( it) = type_param. name ( ) {
94+ format_to ! ( buf, "{}" , it. syntax( ) ) ;
95+ }
96+ if let Some ( it) = type_param. colon_token ( ) {
97+ format_to ! ( buf, "{} " , it) ;
98+ }
99+ if let Some ( it) = type_param. type_bound_list ( ) {
100+ format_to ! ( buf, "{}" , it. syntax( ) ) ;
101+ }
102+ buf
103+ } ) ;
104+ let const_params = generic_params. const_params ( ) . map ( |t| t. syntax ( ) . to_string ( ) ) ;
105+ let generics = lifetimes. chain ( type_params) . chain ( const_params) . format ( ", " ) ;
106+ format_to ! ( buf, "<{}>" , generics) ;
107+ }
108+
109+ buf. push ( ' ' ) ;
110+ buf. push_str ( trait_text) ;
111+ buf. push_str ( " for " ) ;
112+ buf. push_str ( & impl_. self_ty ( ) . unwrap ( ) . syntax ( ) . text ( ) . to_string ( ) ) ;
113+
114+ match impl_. where_clause ( ) {
115+ Some ( where_clause) => {
116+ format_to ! ( buf, "\n {}\n {{\n {}\n }}" , where_clause, code) ;
117+ }
118+ None => {
119+ format_to ! ( buf, " {{\n {}\n }}" , code) ;
120+ }
121+ }
86122
87- impl Default for {} {{
88- fn default() -> Self {{
89- Self::new()
90- }}
91- }}" ,
92- impl_. self_ty( ) . unwrap( ) . syntax( ) . text( )
93- )
123+ buf
94124}
95125
96126fn is_default_implemented ( ctx : & AssistContext , impl_ : & Impl ) -> bool {
@@ -185,7 +215,7 @@ impl Default for Test {
185215 }
186216
187217 #[ test]
188- fn generate_default3 ( ) {
218+ fn new_function_with_generic ( ) {
189219 check_pass (
190220 r#"
191221pub struct Foo<T> {
@@ -194,7 +224,7 @@ pub struct Foo<T> {
194224
195225impl<T> Foo<T> {
196226 pub fn ne$0w() -> Self {
197- todo !()
227+ unimplemented !()
198228 }
199229}
200230"# ,
@@ -205,7 +235,7 @@ pub struct Foo<T> {
205235
206236impl<T> Foo<T> {
207237 pub fn new() -> Self {
208- todo !()
238+ unimplemented !()
209239 }
210240}
211241
@@ -218,6 +248,200 @@ impl<T> Default for Foo<T> {
218248 ) ;
219249 }
220250
251+ #[ test]
252+ fn new_function_with_generics ( ) {
253+ check_pass (
254+ r#"
255+ pub struct Foo<T, B> {
256+ _tars: *mut T,
257+ _bar: *mut B,
258+ }
259+
260+ impl<T, B> Foo<T, B> {
261+ pub fn ne$0w() -> Self {
262+ unimplemented!()
263+ }
264+ }
265+ "# ,
266+ r#"
267+ pub struct Foo<T, B> {
268+ _tars: *mut T,
269+ _bar: *mut B,
270+ }
271+
272+ impl<T, B> Foo<T, B> {
273+ pub fn new() -> Self {
274+ unimplemented!()
275+ }
276+ }
277+
278+ impl<T, B> Default for Foo<T, B> {
279+ fn default() -> Self {
280+ Self::new()
281+ }
282+ }
283+ "# ,
284+ ) ;
285+ }
286+
287+ #[ test]
288+ fn new_function_with_generic_and_bound ( ) {
289+ check_pass (
290+ r#"
291+ pub struct Foo<T> {
292+ t: T,
293+ }
294+
295+ impl<T: From<i32>> Foo<T> {
296+ pub fn ne$0w() -> Self {
297+ Foo { t: 0.into() }
298+ }
299+ }
300+ "# ,
301+ r#"
302+ pub struct Foo<T> {
303+ t: T,
304+ }
305+
306+ impl<T: From<i32>> Foo<T> {
307+ pub fn new() -> Self {
308+ Foo { t: 0.into() }
309+ }
310+ }
311+
312+ impl<T: From<i32>> Default for Foo<T> {
313+ fn default() -> Self {
314+ Self::new()
315+ }
316+ }
317+ "# ,
318+ ) ;
319+ }
320+
321+ #[ test]
322+ fn new_function_with_generics_and_bounds ( ) {
323+ check_pass (
324+ r#"
325+ pub struct Foo<T, B> {
326+ _tars: T,
327+ _bar: B,
328+ }
329+
330+ impl<T: From<i32>, B: From<i64>> Foo<T, B> {
331+ pub fn ne$0w() -> Self {
332+ unimplemented!()
333+ }
334+ }
335+ "# ,
336+ r#"
337+ pub struct Foo<T, B> {
338+ _tars: T,
339+ _bar: B,
340+ }
341+
342+ impl<T: From<i32>, B: From<i64>> Foo<T, B> {
343+ pub fn new() -> Self {
344+ unimplemented!()
345+ }
346+ }
347+
348+ impl<T: From<i32>, B: From<i64>> Default for Foo<T, B> {
349+ fn default() -> Self {
350+ Self::new()
351+ }
352+ }
353+ "# ,
354+ ) ;
355+ }
356+
357+ #[ test]
358+ fn new_function_with_generic_and_where ( ) {
359+ check_pass (
360+ r#"
361+ pub struct Foo<T> {
362+ t: T,
363+ }
364+
365+ impl<T: From<i32>> Foo<T>
366+ where
367+ Option<T>: Debug
368+ {
369+ pub fn ne$0w() -> Self {
370+ Foo { t: 0.into() }
371+ }
372+ }
373+ "# ,
374+ r#"
375+ pub struct Foo<T> {
376+ t: T,
377+ }
378+
379+ impl<T: From<i32>> Foo<T>
380+ where
381+ Option<T>: Debug
382+ {
383+ pub fn new() -> Self {
384+ Foo { t: 0.into() }
385+ }
386+ }
387+
388+ impl<T: From<i32>> Default for Foo<T>
389+ where
390+ Option<T>: Debug
391+ {
392+ fn default() -> Self {
393+ Self::new()
394+ }
395+ }
396+ "# ,
397+ ) ;
398+ }
399+
400+ #[ test]
401+ fn new_function_with_generics_and_wheres ( ) {
402+ check_pass (
403+ r#"
404+ pub struct Foo<T, B> {
405+ _tars: T,
406+ _bar: B,
407+ }
408+
409+ impl<T: From<i32>, B: From<i64>> Foo<T, B>
410+ where
411+ Option<T>: Debug, Option<B>: Debug,
412+ {
413+ pub fn ne$0w() -> Self {
414+ unimplemented!()
415+ }
416+ }
417+ "# ,
418+ r#"
419+ pub struct Foo<T, B> {
420+ _tars: T,
421+ _bar: B,
422+ }
423+
424+ impl<T: From<i32>, B: From<i64>> Foo<T, B>
425+ where
426+ Option<T>: Debug, Option<B>: Debug,
427+ {
428+ pub fn new() -> Self {
429+ unimplemented!()
430+ }
431+ }
432+
433+ impl<T: From<i32>, B: From<i64>> Default for Foo<T, B>
434+ where
435+ Option<T>: Debug, Option<B>: Debug,
436+ {
437+ fn default() -> Self {
438+ Self::new()
439+ }
440+ }
441+ "# ,
442+ ) ;
443+ }
444+
221445 #[ test]
222446 fn new_function_with_parameters ( ) {
223447 cov_mark:: check!( new_function_with_parameters) ;
0 commit comments