2 assist_context::{AssistContext, Assists},
5 use ide_db::helpers::FamousDefs;
6 use itertools::Itertools;
9 ast::{self, GenericParamsOwner, Impl, NameOwner, TypeBoundsOwner},
13 // Assist: generate_default_from_new
15 // Generates default implementation from new method.
18 // struct Example { _inner: () }
21 // pub fn n$0ew() -> Self {
22 // Self { _inner: () }
28 // struct Example { _inner: () }
31 // pub fn new() -> Self {
32 // Self { _inner: () }
36 // impl Default for Example {
37 // fn default() -> Self {
42 pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
43 let fn_node = ctx.find_node_at_offset::<ast::Fn>()?;
44 let fn_name = fn_node.name()?;
46 if fn_name.text() != "new" {
47 cov_mark::hit!(other_function_than_new);
51 if fn_node.param_list()?.params().next().is_some() {
52 cov_mark::hit!(new_function_with_parameters);
56 let impl_ = fn_node.syntax().ancestors().into_iter().find_map(ast::Impl::cast)?;
57 if is_default_implemented(ctx, &impl_) {
58 cov_mark::hit!(default_block_is_already_present);
59 cov_mark::hit!(struct_in_module_with_default);
63 let insert_location = impl_.syntax().text_range();
66 AssistId("generate_default_from_new", crate::AssistKind::Generate),
67 "Generate a Default impl from a new fn",
70 let default_code = " fn default() -> Self {
73 let code = generate_trait_impl_text_from_impl(&impl_, "Default", default_code);
74 builder.insert(insert_location.end(), code);
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());
85 if let Some(generic_params) = &generic_params {
86 let lifetimes = generic_params.lifetime_params().map(|lt| format!("{}", lt.syntax()));
87 let type_params = generic_params.type_params().map(|type_param| {
88 let mut buf = String::new();
89 if let Some(it) = type_param.name() {
90 format_to!(buf, "{}", it.syntax());
92 if let Some(it) = type_param.colon_token() {
93 format_to!(buf, "{} ", it);
95 if let Some(it) = type_param.type_bound_list() {
96 format_to!(buf, "{}", it.syntax());
100 let const_params = generic_params.const_params().map(|t| t.syntax().to_string());
101 let generics = lifetimes.chain(type_params).chain(const_params).format(", ");
102 format_to!(buf, "<{}>", generics);
106 buf.push_str(trait_text);
107 buf.push_str(" for ");
108 buf.push_str(&impl_.self_ty().unwrap().syntax().text().to_string());
110 match impl_.where_clause() {
111 Some(where_clause) => {
112 format_to!(buf, "\n{}\n{{\n{}\n}}", where_clause, code);
115 format_to!(buf, " {{\n{}\n}}", code);
122 fn is_default_implemented(ctx: &AssistContext, impl_: &Impl) -> bool {
123 let db = ctx.sema.db;
124 let impl_ = ctx.sema.to_def(impl_);
125 let impl_def = match impl_ {
126 Some(value) => value,
127 None => return false,
130 let ty = impl_def.self_ty(db);
131 let krate = impl_def.module(db).krate();
132 let default = FamousDefs(&ctx.sema, Some(krate)).core_default_Default();
133 let default_trait = match default {
134 Some(value) => value,
135 None => return false,
138 ty.impls_trait(db, default_trait, &[])
143 use ide_db::helpers::FamousDefs;
145 use crate::tests::{check_assist, check_assist_not_applicable};
150 fn generate_default() {
153 struct Example { _inner: () }
156 pub fn ne$0w() -> Self {
164 struct Example { _inner: () }
167 pub fn new() -> Self {
172 impl Default for Example {
173 fn default() -> Self {
184 fn generate_default2() {
187 struct Test { value: u32 }
190 pub fn ne$0w() -> Self {
196 struct Test { value: u32 }
199 pub fn new() -> Self {
204 impl Default for Test {
205 fn default() -> Self {
214 fn new_function_with_generic() {
222 pub fn ne$0w() -> Self {
233 pub fn new() -> Self {
238 impl<T> Default for Foo<T> {
239 fn default() -> Self {
248 fn new_function_with_generics() {
251 pub struct Foo<T, B> {
256 impl<T, B> Foo<T, B> {
257 pub fn ne$0w() -> Self {
263 pub struct Foo<T, B> {
268 impl<T, B> Foo<T, B> {
269 pub fn new() -> Self {
274 impl<T, B> Default for Foo<T, B> {
275 fn default() -> Self {
284 fn new_function_with_generic_and_bound() {
291 impl<T: From<i32>> Foo<T> {
292 pub fn ne$0w() -> Self {
302 impl<T: From<i32>> Foo<T> {
303 pub fn new() -> Self {
308 impl<T: From<i32>> Default for Foo<T> {
309 fn default() -> Self {
318 fn new_function_with_generics_and_bounds() {
321 pub struct Foo<T, B> {
326 impl<T: From<i32>, B: From<i64>> Foo<T, B> {
327 pub fn ne$0w() -> Self {
333 pub struct Foo<T, B> {
338 impl<T: From<i32>, B: From<i64>> Foo<T, B> {
339 pub fn new() -> Self {
344 impl<T: From<i32>, B: From<i64>> Default for Foo<T, B> {
345 fn default() -> Self {
354 fn new_function_with_generic_and_where() {
361 impl<T: From<i32>> Foo<T>
365 pub fn ne$0w() -> Self {
375 impl<T: From<i32>> Foo<T>
379 pub fn new() -> Self {
384 impl<T: From<i32>> Default for Foo<T>
388 fn default() -> Self {
397 fn new_function_with_generics_and_wheres() {
400 pub struct Foo<T, B> {
405 impl<T: From<i32>, B: From<i64>> Foo<T, B>
407 Option<T>: Debug, Option<B>: Debug,
409 pub fn ne$0w() -> Self {
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 new() -> Self {
429 impl<T: From<i32>, B: From<i64>> Default for Foo<T, B>
431 Option<T>: Debug, Option<B>: Debug,
433 fn default() -> Self {
442 fn new_function_with_parameters() {
443 cov_mark::check!(new_function_with_parameters);
444 check_not_applicable(
446 struct Example { _inner: () }
449 pub fn $0new(value: ()) -> Self {
450 Self { _inner: value }
458 fn other_function_than_new() {
459 cov_mark::check!(other_function_than_new);
460 check_not_applicable(
462 struct Example { _inner: () }
465 pub fn a$0dd() -> Self {
475 fn default_block_is_already_present() {
476 cov_mark::check!(default_block_is_already_present);
477 check_not_applicable(
479 struct Example { _inner: () }
482 pub fn n$0ew() -> Self {
487 impl Default for Example {
488 fn default() -> Self {
497 fn standalone_new_function() {
498 check_not_applicable(
508 fn multiple_struct_blocks() {
511 struct Example { _inner: () }
512 struct Test { value: u32 }
515 pub fn new$0() -> Self {
521 struct Example { _inner: () }
522 struct Test { value: u32 }
525 pub fn new() -> Self {
530 impl Default for Example {
531 fn default() -> Self {
540 fn when_struct_is_after_impl() {
544 pub fn $0new() -> Self {
549 struct Example { _inner: () }
553 pub fn new() -> Self {
558 impl Default for Example {
559 fn default() -> Self {
564 struct Example { _inner: () }
570 fn struct_in_module() {
574 struct Example { _inner: () }
577 pub fn n$0ew() -> Self {
585 struct Example { _inner: () }
588 pub fn new() -> Self {
593 impl Default for Example {
594 fn default() -> Self {
604 fn struct_in_module_with_default() {
605 cov_mark::check!(struct_in_module_with_default);
606 check_not_applicable(
609 struct Example { _inner: () }
612 pub fn n$0ew() -> Self {
617 impl Default for Example {
618 fn default() -> Self {
627 fn check_pass(before: &str, after: &str) {
628 let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
629 check_assist(generate_default_from_new, before, after);
632 fn check_not_applicable(before: &str) {
633 let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
634 check_assist_not_applicable(generate_default_from_new, before);