1 use syntax::ast::{self, AstNode, HasName};
3 use crate::{utils::generate_impl_text, AssistContext, AssistId, AssistKind, Assists};
5 // Assist: generate_impl
7 // Adds a new inherent impl for a type.
10 // struct Ctx<T: Clone> {
16 // struct Ctx<T: Clone> {
20 // impl<T: Clone> Ctx<T> {
24 pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
25 let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
26 let name = nominal.name()?;
27 let target = nominal.syntax().text_range();
30 AssistId("generate_impl", AssistKind::Generate),
31 format!("Generate impl for `{}`", name),
34 let start_offset = nominal.syntax().text_range().end();
35 match ctx.config.snippet_cap {
37 let snippet = generate_impl_text(&nominal, " $0");
38 edit.insert_snippet(cap, start_offset, snippet);
41 let snippet = generate_impl_text(&nominal, "");
42 edit.insert(start_offset, snippet);
51 use crate::tests::{check_assist, check_assist_target};
55 // FIXME: break up into separate test fns
61 "struct Foo {}\n\nimpl Foo {\n $0\n}\n",
65 "struct Foo<T: Clone> {$0}",
66 "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n $0\n}",
70 "struct Foo<'a, T: Foo<'a>> {$0}",
71 "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}",
76 struct MyOwnArray<T, const S: usize> {}$0"#,
78 struct MyOwnArray<T, const S: usize> {}
80 impl<T, const S: usize> MyOwnArray<T, S> {
87 #[cfg(feature = "foo")]
88 struct Foo<'a, T: Foo<'a>> {$0}"#,
90 #[cfg(feature = "foo")]
91 struct Foo<'a, T: Foo<'a>> {}
93 #[cfg(feature = "foo")]
94 impl<'a, T: Foo<'a>> Foo<'a, T> {
102 #[cfg(not(feature = "foo"))]
103 struct Foo<'a, T: Foo<'a>> {$0}"#,
105 #[cfg(not(feature = "foo"))]
106 struct Foo<'a, T: Foo<'a>> {}
108 #[cfg(not(feature = "foo"))]
109 impl<'a, T: Foo<'a>> Foo<'a, T> {
117 struct Defaulted<T = i32> {}$0"#,
119 struct Defaulted<T = i32> {}
121 impl<T> Defaulted<T> {
129 struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {}$0"#,
131 struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {}
133 impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> Defaulted<'a, 'b, T, S> {
141 struct Defaulted<const N: i32 = 0> {}$0"#,
143 struct Defaulted<const N: i32 = 0> {}
145 impl<const N: i32> Defaulted<N> {
152 r#"pub trait Trait {}
159 r#"pub trait Trait {}
177 fn add_impl_target() {
181 struct SomeThingIrrelevant;
182 /// Has a lifetime parameter
183 struct Foo<'a, T: Foo<'a>> {$0}
184 struct EvenMoreIrrelevant;
186 "/// Has a lifetime parameter
187 struct Foo<'a, T: Foo<'a>> {}",