1 use ide_db::famous_defs::FamousDefs;
4 ast::{self, make, HasGenericParams, HasName, Impl},
9 assist_context::{AssistContext, Assists},
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 // FIXME: based on from utils::generate_impl_text_inner
80 fn generate_trait_impl_text_from_impl(impl_: &ast::Impl, trait_text: &str, code: &str) -> String {
81 let impl_ty = impl_.self_ty().unwrap();
82 let generic_params = impl_.generic_param_list().map(|generic_params| {
84 generic_params.lifetime_params().map(ast::GenericParam::LifetimeParam);
85 let ty_or_const_params = generic_params.type_or_const_params().filter_map(|param| {
86 // remove defaults since they can't be specified in impls
88 ast::TypeOrConstParam::Type(param) => {
89 let param = param.clone_for_update();
90 param.remove_default();
91 Some(ast::GenericParam::TypeParam(param))
93 ast::TypeOrConstParam::Const(param) => {
94 let param = param.clone_for_update();
95 param.remove_default();
96 Some(ast::GenericParam::ConstParam(param))
101 make::generic_param_list(itertools::chain(lifetime_params, ty_or_const_params))
104 let mut buf = String::with_capacity(code.len());
105 buf.push_str("\n\n");
107 // `impl{generic_params} {trait_text} for {impl_.self_ty()}`
108 buf.push_str("impl");
109 if let Some(generic_params) = &generic_params {
110 format_to!(buf, "{generic_params}")
112 format_to!(buf, " {trait_text} for {impl_ty}");
114 match impl_.where_clause() {
115 Some(where_clause) => {
116 format_to!(buf, "\n{where_clause}\n{{\n{code}\n}}");
119 format_to!(buf, " {{\n{code}\n}}");
126 fn is_default_implemented(ctx: &AssistContext<'_>, impl_: &Impl) -> bool {
127 let db = ctx.sema.db;
128 let impl_ = ctx.sema.to_def(impl_);
129 let impl_def = match impl_ {
130 Some(value) => value,
131 None => return false,
134 let ty = impl_def.self_ty(db);
135 let krate = impl_def.module(db).krate();
136 let default = FamousDefs(&ctx.sema, krate).core_default_Default();
137 let default_trait = match default {
138 Some(value) => value,
139 None => return false,
142 ty.impls_trait(db, default_trait, &[])
147 use crate::tests::{check_assist, check_assist_not_applicable};
152 fn generate_default() {
154 generate_default_from_new,
156 //- minicore: default
157 struct Example { _inner: () }
160 pub fn ne$0w() -> Self {
168 struct Example { _inner: () }
171 pub fn new() -> Self {
176 impl Default for Example {
177 fn default() -> Self {
188 fn generate_default2() {
190 generate_default_from_new,
192 //- minicore: default
193 struct Test { value: u32 }
196 pub fn ne$0w() -> Self {
202 struct Test { value: u32 }
205 pub fn new() -> Self {
210 impl Default for Test {
211 fn default() -> Self {
220 fn new_function_with_generic() {
222 generate_default_from_new,
224 //- minicore: default
230 pub fn ne$0w() -> Self {
241 pub fn new() -> Self {
246 impl<T> Default for Foo<T> {
247 fn default() -> Self {
256 fn new_function_with_generics() {
258 generate_default_from_new,
260 //- minicore: default
261 pub struct Foo<T, B> {
266 impl<T, B> Foo<T, B> {
267 pub fn ne$0w() -> Self {
273 pub struct Foo<T, B> {
278 impl<T, B> Foo<T, B> {
279 pub fn new() -> Self {
284 impl<T, B> Default for Foo<T, B> {
285 fn default() -> Self {
294 fn new_function_with_generic_and_bound() {
296 generate_default_from_new,
298 //- minicore: default
303 impl<T: From<i32>> Foo<T> {
304 pub fn ne$0w() -> Self {
314 impl<T: From<i32>> Foo<T> {
315 pub fn new() -> Self {
320 impl<T: From<i32>> Default for Foo<T> {
321 fn default() -> Self {
330 fn new_function_with_generics_and_bounds() {
332 generate_default_from_new,
334 //- minicore: default
335 pub struct Foo<T, B> {
340 impl<T: From<i32>, B: From<i64>> Foo<T, B> {
341 pub fn ne$0w() -> Self {
347 pub struct Foo<T, B> {
352 impl<T: From<i32>, B: From<i64>> Foo<T, B> {
353 pub fn new() -> Self {
358 impl<T: From<i32>, B: From<i64>> Default for Foo<T, B> {
359 fn default() -> Self {
368 fn new_function_with_generic_and_where() {
370 generate_default_from_new,
372 //- minicore: default
377 impl<T: From<i32>> Foo<T>
381 pub fn ne$0w() -> Self {
391 impl<T: From<i32>> Foo<T>
395 pub fn new() -> Self {
400 impl<T: From<i32>> Default for Foo<T>
404 fn default() -> Self {
413 fn new_function_with_generics_and_wheres() {
415 generate_default_from_new,
417 //- minicore: default
418 pub struct Foo<T, B> {
423 impl<T: From<i32>, B: From<i64>> Foo<T, B>
425 Option<T>: Debug, Option<B>: Debug,
427 pub fn ne$0w() -> Self {
433 pub struct Foo<T, B> {
438 impl<T: From<i32>, B: From<i64>> Foo<T, B>
440 Option<T>: Debug, Option<B>: Debug,
442 pub fn new() -> Self {
447 impl<T: From<i32>, B: From<i64>> Default for Foo<T, B>
449 Option<T>: Debug, Option<B>: Debug,
451 fn default() -> Self {
460 fn new_function_with_parameters() {
461 cov_mark::check!(new_function_with_parameters);
462 check_assist_not_applicable(
463 generate_default_from_new,
465 //- minicore: default
466 struct Example { _inner: () }
469 pub fn $0new(value: ()) -> Self {
470 Self { _inner: value }
478 fn other_function_than_new() {
479 cov_mark::check!(other_function_than_new);
480 check_assist_not_applicable(
481 generate_default_from_new,
483 struct Example { _inner: () }
486 pub fn a$0dd() -> Self {
496 fn default_block_is_already_present() {
497 cov_mark::check!(default_block_is_already_present);
498 check_assist_not_applicable(
499 generate_default_from_new,
501 //- minicore: default
502 struct Example { _inner: () }
505 pub fn n$0ew() -> Self {
510 impl Default for Example {
511 fn default() -> Self {
520 fn standalone_new_function() {
521 check_assist_not_applicable(
522 generate_default_from_new,
532 fn multiple_struct_blocks() {
534 generate_default_from_new,
536 //- minicore: default
537 struct Example { _inner: () }
538 struct Test { value: u32 }
541 pub fn new$0() -> Self {
547 struct Example { _inner: () }
548 struct Test { value: u32 }
551 pub fn new() -> Self {
556 impl Default for Example {
557 fn default() -> Self {
566 fn when_struct_is_after_impl() {
568 generate_default_from_new,
570 //- minicore: default
572 pub fn $0new() -> Self {
577 struct Example { _inner: () }
581 pub fn new() -> Self {
586 impl Default for Example {
587 fn default() -> Self {
592 struct Example { _inner: () }
598 fn struct_in_module() {
600 generate_default_from_new,
602 //- minicore: default
604 struct Example { _inner: () }
607 pub fn n$0ew() -> Self {
615 struct Example { _inner: () }
618 pub fn new() -> Self {
623 impl Default for Example {
624 fn default() -> Self {
634 fn struct_in_module_with_default() {
635 cov_mark::check!(struct_in_module_with_default);
636 check_assist_not_applicable(
637 generate_default_from_new,
639 //- minicore: default
641 struct Example { _inner: () }
644 pub fn n$0ew() -> Self {
649 impl Default for Example {
650 fn default() -> Self {