1 use ide_db::helpers::FamousDefs;
2 use itertools::Itertools;
5 ast::{self, HasGenericParams, HasName, HasTypeBounds, Impl},
10 assist_context::{AssistContext, Assists},
14 // Assist: generate_default_from_new
16 // Generates default implementation from new method.
19 // struct Example { _inner: () }
22 // pub fn n$0ew() -> Self {
23 // Self { _inner: () }
29 // struct Example { _inner: () }
32 // pub fn new() -> Self {
33 // Self { _inner: () }
37 // impl Default for Example {
38 // fn default() -> Self {
43 pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
44 let fn_node = ctx.find_node_at_offset::<ast::Fn>()?;
45 let fn_name = fn_node.name()?;
47 if fn_name.text() != "new" {
48 cov_mark::hit!(other_function_than_new);
52 if fn_node.param_list()?.params().next().is_some() {
53 cov_mark::hit!(new_function_with_parameters);
57 let impl_ = fn_node.syntax().ancestors().into_iter().find_map(ast::Impl::cast)?;
58 if is_default_implemented(ctx, &impl_) {
59 cov_mark::hit!(default_block_is_already_present);
60 cov_mark::hit!(struct_in_module_with_default);
64 let insert_location = impl_.syntax().text_range();
67 AssistId("generate_default_from_new", crate::AssistKind::Generate),
68 "Generate a Default impl from a new fn",
71 let default_code = " fn default() -> Self {
74 let code = generate_trait_impl_text_from_impl(&impl_, "Default", default_code);
75 builder.insert(insert_location.end(), code);
80 fn generate_trait_impl_text_from_impl(impl_: &ast::Impl, trait_text: &str, code: &str) -> String {
81 let generic_params = impl_.generic_param_list();
82 let mut buf = String::with_capacity(code.len());
86 if let Some(generic_params) = &generic_params {
87 let lifetimes = generic_params.lifetime_params().map(|lt| format!("{}", lt.syntax()));
88 let type_params = generic_params.type_params().map(|type_param| {
89 let mut buf = String::new();
90 if let Some(it) = type_param.name() {
91 format_to!(buf, "{}", it.syntax());
93 if let Some(it) = type_param.colon_token() {
94 format_to!(buf, "{} ", it);
96 if let Some(it) = type_param.type_bound_list() {
97 format_to!(buf, "{}", it.syntax());
101 let const_params = generic_params.const_params().map(|t| t.syntax().to_string());
102 let generics = lifetimes.chain(type_params).chain(const_params).format(", ");
103 format_to!(buf, "<{}>", generics);
107 buf.push_str(trait_text);
108 buf.push_str(" for ");
109 buf.push_str(&impl_.self_ty().unwrap().syntax().text().to_string());
111 match impl_.where_clause() {
112 Some(where_clause) => {
113 format_to!(buf, "\n{}\n{{\n{}\n}}", where_clause, code);
116 format_to!(buf, " {{\n{}\n}}", code);
123 fn is_default_implemented(ctx: &AssistContext, impl_: &Impl) -> bool {
124 let db = ctx.sema.db;
125 let impl_ = ctx.sema.to_def(impl_);
126 let impl_def = match impl_ {
127 Some(value) => value,
128 None => return false,
131 let ty = impl_def.self_ty(db);
132 let krate = impl_def.module(db).krate();
133 let default = FamousDefs(&ctx.sema, Some(krate)).core_default_Default();
134 let default_trait = match default {
135 Some(value) => value,
136 None => return false,
139 ty.impls_trait(db, default_trait, &[])
144 use crate::tests::{check_assist, check_assist_not_applicable};
149 fn generate_default() {
151 generate_default_from_new,
153 //- minicore: default
154 struct Example { _inner: () }
157 pub fn ne$0w() -> Self {
165 struct Example { _inner: () }
168 pub fn new() -> Self {
173 impl Default for Example {
174 fn default() -> Self {
185 fn generate_default2() {
187 generate_default_from_new,
189 //- minicore: default
190 struct Test { value: u32 }
193 pub fn ne$0w() -> Self {
199 struct Test { value: u32 }
202 pub fn new() -> Self {
207 impl Default for Test {
208 fn default() -> Self {
217 fn new_function_with_generic() {
219 generate_default_from_new,
221 //- minicore: default
227 pub fn ne$0w() -> Self {
238 pub fn new() -> Self {
243 impl<T> Default for Foo<T> {
244 fn default() -> Self {
253 fn new_function_with_generics() {
255 generate_default_from_new,
257 //- minicore: default
258 pub struct Foo<T, B> {
263 impl<T, B> Foo<T, B> {
264 pub fn ne$0w() -> Self {
270 pub struct Foo<T, B> {
275 impl<T, B> Foo<T, B> {
276 pub fn new() -> Self {
281 impl<T, B> Default for Foo<T, B> {
282 fn default() -> Self {
291 fn new_function_with_generic_and_bound() {
293 generate_default_from_new,
295 //- minicore: default
300 impl<T: From<i32>> Foo<T> {
301 pub fn ne$0w() -> Self {
311 impl<T: From<i32>> Foo<T> {
312 pub fn new() -> Self {
317 impl<T: From<i32>> Default for Foo<T> {
318 fn default() -> Self {
327 fn new_function_with_generics_and_bounds() {
329 generate_default_from_new,
331 //- minicore: default
332 pub struct Foo<T, B> {
337 impl<T: From<i32>, B: From<i64>> Foo<T, B> {
338 pub fn ne$0w() -> Self {
344 pub struct Foo<T, B> {
349 impl<T: From<i32>, B: From<i64>> Foo<T, B> {
350 pub fn new() -> Self {
355 impl<T: From<i32>, B: From<i64>> Default for Foo<T, B> {
356 fn default() -> Self {
365 fn new_function_with_generic_and_where() {
367 generate_default_from_new,
369 //- minicore: default
374 impl<T: From<i32>> Foo<T>
378 pub fn ne$0w() -> Self {
388 impl<T: From<i32>> Foo<T>
392 pub fn new() -> Self {
397 impl<T: From<i32>> Default for Foo<T>
401 fn default() -> Self {
410 fn new_function_with_generics_and_wheres() {
412 generate_default_from_new,
414 //- minicore: default
415 pub struct Foo<T, B> {
420 impl<T: From<i32>, B: From<i64>> Foo<T, B>
422 Option<T>: Debug, Option<B>: Debug,
424 pub fn ne$0w() -> Self {
430 pub struct Foo<T, B> {
435 impl<T: From<i32>, B: From<i64>> Foo<T, B>
437 Option<T>: Debug, Option<B>: Debug,
439 pub fn new() -> Self {
444 impl<T: From<i32>, B: From<i64>> Default for Foo<T, B>
446 Option<T>: Debug, Option<B>: Debug,
448 fn default() -> Self {
457 fn new_function_with_parameters() {
458 cov_mark::check!(new_function_with_parameters);
459 check_assist_not_applicable(
460 generate_default_from_new,
462 //- minicore: default
463 struct Example { _inner: () }
466 pub fn $0new(value: ()) -> Self {
467 Self { _inner: value }
475 fn other_function_than_new() {
476 cov_mark::check!(other_function_than_new);
477 check_assist_not_applicable(
478 generate_default_from_new,
480 struct Example { _inner: () }
483 pub fn a$0dd() -> Self {
493 fn default_block_is_already_present() {
494 cov_mark::check!(default_block_is_already_present);
495 check_assist_not_applicable(
496 generate_default_from_new,
498 //- minicore: default
499 struct Example { _inner: () }
502 pub fn n$0ew() -> Self {
507 impl Default for Example {
508 fn default() -> Self {
517 fn standalone_new_function() {
518 check_assist_not_applicable(
519 generate_default_from_new,
529 fn multiple_struct_blocks() {
531 generate_default_from_new,
533 //- minicore: default
534 struct Example { _inner: () }
535 struct Test { value: u32 }
538 pub fn new$0() -> Self {
544 struct Example { _inner: () }
545 struct Test { value: u32 }
548 pub fn new() -> Self {
553 impl Default for Example {
554 fn default() -> Self {
563 fn when_struct_is_after_impl() {
565 generate_default_from_new,
567 //- minicore: default
569 pub fn $0new() -> Self {
574 struct Example { _inner: () }
578 pub fn new() -> Self {
583 impl Default for Example {
584 fn default() -> Self {
589 struct Example { _inner: () }
595 fn struct_in_module() {
597 generate_default_from_new,
599 //- minicore: default
601 struct Example { _inner: () }
604 pub fn n$0ew() -> Self {
612 struct Example { _inner: () }
615 pub fn new() -> Self {
620 impl Default for Example {
621 fn default() -> Self {
631 fn struct_in_module_with_default() {
632 cov_mark::check!(struct_in_module_with_default);
633 check_assist_not_applicable(
634 generate_default_from_new,
636 //- minicore: default
638 struct Example { _inner: () }
641 pub fn n$0ew() -> Self {
646 impl Default for Example {
647 fn default() -> Self {