2 use ide_db::traits::resolve_target_trait;
3 use syntax::ast::{self, make, AstNode};
6 assist_context::{AssistContext, Assists},
8 add_trait_assoc_items_to_impl, filter_assoc_items, gen_trait_body, render_snippet, Cursor,
14 // Assist: add_impl_missing_members
16 // Adds scaffold for required impl members.
21 // fn foo(&self) -> T;
25 // impl Trait<u32> for () {$0
33 // fn foo(&self) -> T;
37 // impl Trait<u32> for () {
40 // fn foo(&self) -> u32 {
45 pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
46 add_missing_impl_members_inner(
50 "add_impl_missing_members",
51 "Implement missing members",
55 // Assist: add_impl_default_members
57 // Adds scaffold for overriding default impl members.
66 // impl Trait for () {
79 // impl Trait for () {
86 pub(crate) fn add_missing_default_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
87 add_missing_impl_members_inner(
91 "add_impl_default_members",
92 "Implement default members",
96 fn add_missing_impl_members_inner(
100 assist_id: &'static str,
103 let _p = profile::span("add_missing_impl_members_inner");
104 let impl_def = ctx.find_node_at_offset::<ast::Impl>()?;
105 let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?;
107 let missing_items = filter_assoc_items(
109 &ide_db::traits::get_missing_assoc_items(&ctx.sema, &impl_def),
113 if missing_items.is_empty() {
117 let target = impl_def.syntax().text_range();
118 acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |builder| {
119 let target_scope = ctx.sema.scope(impl_def.syntax());
120 let (new_impl_def, first_new_item) = add_trait_assoc_items_to_impl(
127 match ctx.config.snippet_cap {
128 None => builder.replace(target, new_impl_def.to_string()),
130 let mut cursor = Cursor::Before(first_new_item.syntax());
132 if let ast::AssocItem::Fn(func) = &first_new_item {
133 if try_gen_trait_body(ctx, func, &trait_, &impl_def).is_none() {
134 if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast)
136 if m.syntax().text() == "todo!()" {
138 cursor = Cursor::Replace(placeholder.syntax());
143 builder.replace_snippet(
146 render_snippet(cap, new_impl_def.syntax(), cursor),
153 fn try_gen_trait_body(
157 impl_def: &ast::Impl,
159 let trait_path = make::path_from_text(&trait_.name(ctx.db()).to_string());
160 let hir_ty = ctx.sema.resolve_type(&impl_def.self_ty()?)?;
161 let adt = hir_ty.as_adt()?.source(ctx.db())?;
162 gen_trait_body(func, &trait_path, &adt.value)
167 use crate::tests::{check_assist, check_assist_not_applicable};
172 fn test_add_missing_impl_members() {
174 add_missing_impl_members,
179 const CONST: usize = 42;
196 const CONST: usize = 42;
210 const CONST: usize = 42;
225 fn test_copied_overriden_members() {
227 add_missing_impl_members,
231 fn bar(&self) -> bool { true }
232 fn baz(&self) -> u32 { 42 }
244 fn bar(&self) -> bool { true }
245 fn baz(&self) -> u32 { 42 }
262 fn test_empty_impl_def() {
264 add_missing_impl_members,
266 trait Foo { fn foo(&self); }
268 impl Foo for S { $0 }"#,
270 trait Foo { fn foo(&self); }
281 fn test_impl_def_without_braces() {
283 add_missing_impl_members,
285 trait Foo { fn foo(&self); }
289 trait Foo { fn foo(&self); }
300 fn fill_in_type_params_1() {
302 add_missing_impl_members,
304 trait Foo<T> { fn foo(&self, t: T) -> &T; }
306 impl Foo<u32> for S { $0 }"#,
308 trait Foo<T> { fn foo(&self, t: T) -> &T; }
310 impl Foo<u32> for S {
311 fn foo(&self, t: u32) -> &u32 {
319 fn fill_in_type_params_2() {
321 add_missing_impl_members,
323 trait Foo<T> { fn foo(&self, t: T) -> &T; }
325 impl<U> Foo<U> for S { $0 }"#,
327 trait Foo<T> { fn foo(&self, t: T) -> &T; }
329 impl<U> Foo<U> for S {
330 fn foo(&self, t: U) -> &U {
338 fn test_cursor_after_empty_impl_def() {
340 add_missing_impl_members,
342 trait Foo { fn foo(&self); }
344 impl Foo for S {}$0"#,
346 trait Foo { fn foo(&self); }
357 fn test_qualify_path_1() {
359 add_missing_impl_members,
363 trait Foo { fn foo(&self, bar: Bar); }
366 impl foo::Foo for S { $0 }"#,
370 trait Foo { fn foo(&self, bar: Bar); }
373 impl foo::Foo for S {
374 fn foo(&self, bar: foo::Bar) {
382 fn test_qualify_path_2() {
384 add_missing_impl_members,
389 pub trait Foo { fn foo(&self, bar: Bar); }
396 impl bar::Foo for S { $0 }"#,
401 pub trait Foo { fn foo(&self, bar: Bar); }
408 impl bar::Foo for S {
409 fn foo(&self, bar: bar::Bar) {
417 fn test_qualify_path_generic() {
419 add_missing_impl_members,
423 trait Foo { fn foo(&self, bar: Bar<u32>); }
426 impl foo::Foo for S { $0 }"#,
430 trait Foo { fn foo(&self, bar: Bar<u32>); }
433 impl foo::Foo for S {
434 fn foo(&self, bar: foo::Bar<u32>) {
442 fn test_qualify_path_and_substitute_param() {
444 add_missing_impl_members,
448 trait Foo<T> { fn foo(&self, bar: Bar<T>); }
451 impl foo::Foo<u32> for S { $0 }"#,
455 trait Foo<T> { fn foo(&self, bar: Bar<T>); }
458 impl foo::Foo<u32> for S {
459 fn foo(&self, bar: foo::Bar<u32>) {
467 fn test_substitute_param_no_qualify() {
468 // when substituting params, the substituted param should not be qualified!
470 add_missing_impl_members,
473 trait Foo<T> { fn foo(&self, bar: T); }
478 impl foo::Foo<Param> for S { $0 }"#,
481 trait Foo<T> { fn foo(&self, bar: T); }
486 impl foo::Foo<Param> for S {
487 fn foo(&self, bar: Param) {
495 fn test_qualify_path_associated_item() {
497 add_missing_impl_members,
501 impl Bar<T> { type Assoc = u32; }
502 trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
505 impl foo::Foo for S { $0 }"#,
509 impl Bar<T> { type Assoc = u32; }
510 trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
513 impl foo::Foo for S {
514 fn foo(&self, bar: foo::Bar<u32>::Assoc) {
522 fn test_qualify_path_nested() {
524 add_missing_impl_members,
529 trait Foo { fn foo(&self, bar: Bar<Baz>); }
532 impl foo::Foo for S { $0 }"#,
537 trait Foo { fn foo(&self, bar: Bar<Baz>); }
540 impl foo::Foo for S {
541 fn foo(&self, bar: foo::Bar<foo::Baz>) {
549 fn test_qualify_path_fn_trait_notation() {
551 add_missing_impl_members,
554 pub trait Fn<Args> { type Output; }
555 trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
558 impl foo::Foo for S { $0 }"#,
561 pub trait Fn<Args> { type Output; }
562 trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
565 impl foo::Foo for S {
566 fn foo(&self, bar: dyn Fn(u32) -> i32) {
574 fn test_empty_trait() {
575 check_assist_not_applicable(
576 add_missing_impl_members,
580 impl Foo for S { $0 }"#,
585 fn test_ignore_unnamed_trait_members_and_default_methods() {
586 check_assist_not_applicable(
587 add_missing_impl_members,
591 fn valid(some: u32) -> bool { false }
594 impl Foo for S { $0 }"#,
599 fn test_with_docstring_and_attrs() {
601 add_missing_impl_members,
603 #[doc(alias = "test alias")]
612 impl Foo for S {}$0"#,
614 #[doc(alias = "test alias")]
634 fn test_default_methods() {
636 add_missing_default_members,
641 const CONST: usize = 42;
643 fn valid(some: u32) -> bool { false }
644 fn foo(some: u32) -> bool;
647 impl Foo for S { $0 }"#,
652 const CONST: usize = 42;
654 fn valid(some: u32) -> bool { false }
655 fn foo(some: u32) -> bool;
659 $0fn valid(some: u32) -> bool { false }
665 fn test_generic_single_default_parameter() {
667 add_missing_impl_members,
669 trait Foo<T = Self> {
670 fn bar(&self, other: &T);
674 impl Foo for S { $0 }"#,
676 trait Foo<T = Self> {
677 fn bar(&self, other: &T);
682 fn bar(&self, other: &Self) {
690 fn test_generic_default_parameter_is_second() {
692 add_missing_impl_members,
694 trait Foo<T1, T2 = Self> {
695 fn bar(&self, this: &T1, that: &T2);
699 impl Foo<T> for S<T> { $0 }"#,
701 trait Foo<T1, T2 = Self> {
702 fn bar(&self, this: &T1, that: &T2);
706 impl Foo<T> for S<T> {
707 fn bar(&self, this: &T, that: &Self) {
715 fn test_assoc_type_bounds_are_removed() {
717 add_missing_impl_members,
720 type Ty: Copy + 'static;
727 type Ty: Copy + 'static;
737 fn test_whitespace_fixup_preserves_bad_tokens() {
739 add_missing_impl_members,
763 fn test_whitespace_fixup_preserves_comments() {
765 add_missing_impl_members,
791 add_missing_impl_members,
794 fn foo(&self, x: crate)
802 fn foo(&self, x: crate)
805 fn foo(&self, x: crate) {
814 fn missing_generic_type() {
816 add_missing_impl_members,
819 fn foo(&self, bar: BAR);
827 fn foo(&self, bar: BAR);
830 fn foo(&self, bar: BAR) {
839 fn does_not_requalify_self_as_crate() {
841 add_missing_default_members,
843 struct Wrapper<T>(T);
846 fn f(self) -> Wrapper<Self> {
856 struct Wrapper<T>(T);
859 fn f(self) -> Wrapper<Self> {
865 $0fn f(self) -> Wrapper<Self> {
874 fn test_default_body_generation() {
876 add_missing_impl_members,
878 //- minicore: default
881 impl Default for Foo {
888 impl Default for Foo {
889 $0fn default() -> Self {
890 Self(Default::default())