1 use ide_db::famous_defs::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 toc_params = generic_params.type_or_const_params().map(|toc_param| match toc_param {
89 ast::TypeOrConstParam::Type(type_param) => {
90 let mut buf = String::new();
91 if let Some(it) = type_param.name() {
92 format_to!(buf, "{}", it.syntax());
94 if let Some(it) = type_param.colon_token() {
95 format_to!(buf, "{} ", it);
97 if let Some(it) = type_param.type_bound_list() {
98 format_to!(buf, "{}", it.syntax());
102 ast::TypeOrConstParam::Const(const_param) => const_param.syntax().to_string(),
104 let generics = lifetimes.chain(toc_params).format(", ");
105 format_to!(buf, "<{}>", generics);
109 buf.push_str(trait_text);
110 buf.push_str(" for ");
111 buf.push_str(&impl_.self_ty().unwrap().syntax().text().to_string());
113 match impl_.where_clause() {
114 Some(where_clause) => {
115 format_to!(buf, "\n{}\n{{\n{}\n}}", where_clause, code);
118 format_to!(buf, " {{\n{}\n}}", code);
125 fn is_default_implemented(ctx: &AssistContext<'_>, impl_: &Impl) -> bool {
126 let db = ctx.sema.db;
127 let impl_ = ctx.sema.to_def(impl_);
128 let impl_def = match impl_ {
129 Some(value) => value,
130 None => return false,
133 let ty = impl_def.self_ty(db);
134 let krate = impl_def.module(db).krate();
135 let default = FamousDefs(&ctx.sema, krate).core_default_Default();
136 let default_trait = match default {
137 Some(value) => value,
138 None => return false,
141 ty.impls_trait(db, default_trait, &[])
146 use crate::tests::{check_assist, check_assist_not_applicable};
151 fn generate_default() {
153 generate_default_from_new,
155 //- minicore: default
156 struct Example { _inner: () }
159 pub fn ne$0w() -> Self {
167 struct Example { _inner: () }
170 pub fn new() -> Self {
175 impl Default for Example {
176 fn default() -> Self {
187 fn generate_default2() {
189 generate_default_from_new,
191 //- minicore: default
192 struct Test { value: u32 }
195 pub fn ne$0w() -> Self {
201 struct Test { value: u32 }
204 pub fn new() -> Self {
209 impl Default for Test {
210 fn default() -> Self {
219 fn new_function_with_generic() {
221 generate_default_from_new,
223 //- minicore: default
229 pub fn ne$0w() -> Self {
240 pub fn new() -> Self {
245 impl<T> Default for Foo<T> {
246 fn default() -> Self {
255 fn new_function_with_generics() {
257 generate_default_from_new,
259 //- minicore: default
260 pub struct Foo<T, B> {
265 impl<T, B> Foo<T, B> {
266 pub fn ne$0w() -> Self {
272 pub struct Foo<T, B> {
277 impl<T, B> Foo<T, B> {
278 pub fn new() -> Self {
283 impl<T, B> Default for Foo<T, B> {
284 fn default() -> Self {
293 fn new_function_with_generic_and_bound() {
295 generate_default_from_new,
297 //- minicore: default
302 impl<T: From<i32>> Foo<T> {
303 pub fn ne$0w() -> Self {
313 impl<T: From<i32>> Foo<T> {
314 pub fn new() -> Self {
319 impl<T: From<i32>> Default for Foo<T> {
320 fn default() -> Self {
329 fn new_function_with_generics_and_bounds() {
331 generate_default_from_new,
333 //- minicore: default
334 pub struct Foo<T, B> {
339 impl<T: From<i32>, B: From<i64>> Foo<T, B> {
340 pub fn ne$0w() -> Self {
346 pub struct Foo<T, B> {
351 impl<T: From<i32>, B: From<i64>> Foo<T, B> {
352 pub fn new() -> Self {
357 impl<T: From<i32>, B: From<i64>> Default for Foo<T, B> {
358 fn default() -> Self {
367 fn new_function_with_generic_and_where() {
369 generate_default_from_new,
371 //- minicore: default
376 impl<T: From<i32>> Foo<T>
380 pub fn ne$0w() -> Self {
390 impl<T: From<i32>> Foo<T>
394 pub fn new() -> Self {
399 impl<T: From<i32>> Default for Foo<T>
403 fn default() -> Self {
412 fn new_function_with_generics_and_wheres() {
414 generate_default_from_new,
416 //- minicore: default
417 pub struct Foo<T, B> {
422 impl<T: From<i32>, B: From<i64>> Foo<T, B>
424 Option<T>: Debug, Option<B>: Debug,
426 pub fn ne$0w() -> Self {
432 pub struct Foo<T, B> {
437 impl<T: From<i32>, B: From<i64>> Foo<T, B>
439 Option<T>: Debug, Option<B>: Debug,
441 pub fn new() -> Self {
446 impl<T: From<i32>, B: From<i64>> Default for Foo<T, B>
448 Option<T>: Debug, Option<B>: Debug,
450 fn default() -> Self {
459 fn new_function_with_parameters() {
460 cov_mark::check!(new_function_with_parameters);
461 check_assist_not_applicable(
462 generate_default_from_new,
464 //- minicore: default
465 struct Example { _inner: () }
468 pub fn $0new(value: ()) -> Self {
469 Self { _inner: value }
477 fn other_function_than_new() {
478 cov_mark::check!(other_function_than_new);
479 check_assist_not_applicable(
480 generate_default_from_new,
482 struct Example { _inner: () }
485 pub fn a$0dd() -> Self {
495 fn default_block_is_already_present() {
496 cov_mark::check!(default_block_is_already_present);
497 check_assist_not_applicable(
498 generate_default_from_new,
500 //- minicore: default
501 struct Example { _inner: () }
504 pub fn n$0ew() -> Self {
509 impl Default for Example {
510 fn default() -> Self {
519 fn standalone_new_function() {
520 check_assist_not_applicable(
521 generate_default_from_new,
531 fn multiple_struct_blocks() {
533 generate_default_from_new,
535 //- minicore: default
536 struct Example { _inner: () }
537 struct Test { value: u32 }
540 pub fn new$0() -> Self {
546 struct Example { _inner: () }
547 struct Test { value: u32 }
550 pub fn new() -> Self {
555 impl Default for Example {
556 fn default() -> Self {
565 fn when_struct_is_after_impl() {
567 generate_default_from_new,
569 //- minicore: default
571 pub fn $0new() -> Self {
576 struct Example { _inner: () }
580 pub fn new() -> Self {
585 impl Default for Example {
586 fn default() -> Self {
591 struct Example { _inner: () }
597 fn struct_in_module() {
599 generate_default_from_new,
601 //- minicore: default
603 struct Example { _inner: () }
606 pub fn n$0ew() -> Self {
614 struct Example { _inner: () }
617 pub fn new() -> Self {
622 impl Default for Example {
623 fn default() -> Self {
633 fn struct_in_module_with_default() {
634 cov_mark::check!(struct_in_module_with_default);
635 check_assist_not_applicable(
636 generate_default_from_new,
638 //- minicore: default
640 struct Example { _inner: () }
643 pub fn n$0ew() -> Self {
648 impl Default for Example {
649 fn default() -> Self {