diff options
Diffstat (limited to 'crates/assists/src/handlers/generate_impl.rs')
-rw-r--r-- | crates/assists/src/handlers/generate_impl.rs | 70 |
1 files changed, 30 insertions, 40 deletions
diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs index 61d1bd25c..16a600e6f 100644 --- a/crates/assists/src/handlers/generate_impl.rs +++ b/crates/assists/src/handlers/generate_impl.rs | |||
@@ -1,11 +1,6 @@ | |||
1 | use itertools::Itertools; | 1 | use syntax::ast::{self, AstNode, NameOwner}; |
2 | use stdx::format_to; | ||
3 | use syntax::{ | ||
4 | ast::{self, AstNode, AttrsOwner, GenericParamsOwner, NameOwner}, | ||
5 | SmolStr, | ||
6 | }; | ||
7 | 2 | ||
8 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 3 | use crate::{utils::generate_impl_text, AssistContext, AssistId, AssistKind, Assists}; |
9 | 4 | ||
10 | // Assist: generate_impl | 5 | // Assist: generate_impl |
11 | // | 6 | // |
@@ -36,44 +31,15 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<() | |||
36 | format!("Generate impl for `{}`", name), | 31 | format!("Generate impl for `{}`", name), |
37 | target, | 32 | target, |
38 | |edit| { | 33 | |edit| { |
39 | let type_params = nominal.generic_param_list(); | ||
40 | let start_offset = nominal.syntax().text_range().end(); | 34 | let start_offset = nominal.syntax().text_range().end(); |
41 | let mut buf = String::new(); | ||
42 | buf.push_str("\n\n"); | ||
43 | nominal | ||
44 | .attrs() | ||
45 | .filter(|attr| { | ||
46 | attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false) | ||
47 | }) | ||
48 | .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str())); | ||
49 | |||
50 | buf.push_str("impl"); | ||
51 | if let Some(type_params) = &type_params { | ||
52 | format_to!(buf, "{}", type_params.syntax()); | ||
53 | } | ||
54 | buf.push_str(" "); | ||
55 | buf.push_str(name.text()); | ||
56 | if let Some(type_params) = type_params { | ||
57 | let lifetime_params = type_params | ||
58 | .lifetime_params() | ||
59 | .filter_map(|it| it.lifetime()) | ||
60 | .map(|it| SmolStr::from(it.text())); | ||
61 | let type_params = type_params | ||
62 | .type_params() | ||
63 | .filter_map(|it| it.name()) | ||
64 | .map(|it| SmolStr::from(it.text())); | ||
65 | |||
66 | let generic_params = lifetime_params.chain(type_params).format(", "); | ||
67 | format_to!(buf, "<{}>", generic_params) | ||
68 | } | ||
69 | match ctx.config.snippet_cap { | 35 | match ctx.config.snippet_cap { |
70 | Some(cap) => { | 36 | Some(cap) => { |
71 | buf.push_str(" {\n $0\n}"); | 37 | let snippet = generate_impl_text(&nominal, " $0"); |
72 | edit.insert_snippet(cap, start_offset, buf); | 38 | edit.insert_snippet(cap, start_offset, snippet); |
73 | } | 39 | } |
74 | None => { | 40 | None => { |
75 | buf.push_str(" {\n}"); | 41 | let snippet = generate_impl_text(&nominal, ""); |
76 | edit.insert(start_offset, buf); | 42 | edit.insert(start_offset, snippet); |
77 | } | 43 | } |
78 | } | 44 | } |
79 | }, | 45 | }, |
@@ -132,6 +98,30 @@ mod tests { | |||
132 | $0 | 98 | $0 |
133 | }"#, | 99 | }"#, |
134 | ); | 100 | ); |
101 | |||
102 | check_assist( | ||
103 | generate_impl, | ||
104 | r#" | ||
105 | struct Defaulted<T = i32> {}$0"#, | ||
106 | r#" | ||
107 | struct Defaulted<T = i32> {} | ||
108 | |||
109 | impl<T> Defaulted<T> { | ||
110 | $0 | ||
111 | }"#, | ||
112 | ); | ||
113 | |||
114 | check_assist( | ||
115 | generate_impl, | ||
116 | r#" | ||
117 | struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String> {}$0"#, | ||
118 | r#" | ||
119 | struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String> {} | ||
120 | |||
121 | impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b> Defaulted<'a, 'b, T> { | ||
122 | $0 | ||
123 | }"#, | ||
124 | ); | ||
135 | } | 125 | } |
136 | 126 | ||
137 | #[test] | 127 | #[test] |