diff options
Diffstat (limited to 'crates/assists/src/handlers/generate_impl.rs')
-rw-r--r-- | crates/assists/src/handlers/generate_impl.rs | 148 |
1 files changed, 0 insertions, 148 deletions
diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs deleted file mode 100644 index 9af45192b..000000000 --- a/crates/assists/src/handlers/generate_impl.rs +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | use itertools::Itertools; | ||
2 | use stdx::format_to; | ||
3 | use syntax::ast::{self, AstNode, AttrsOwner, GenericParamsOwner, NameOwner}; | ||
4 | |||
5 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | ||
6 | |||
7 | // Assist: generate_impl | ||
8 | // | ||
9 | // Adds a new inherent impl for a type. | ||
10 | // | ||
11 | // ``` | ||
12 | // struct Ctx<T: Clone> { | ||
13 | // data: T,$0 | ||
14 | // } | ||
15 | // ``` | ||
16 | // -> | ||
17 | // ``` | ||
18 | // struct Ctx<T: Clone> { | ||
19 | // data: T, | ||
20 | // } | ||
21 | // | ||
22 | // impl<T: Clone> Ctx<T> { | ||
23 | // $0 | ||
24 | // } | ||
25 | // ``` | ||
26 | pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
27 | let nominal = ctx.find_node_at_offset::<ast::AdtDef>()?; | ||
28 | let name = nominal.name()?; | ||
29 | let target = nominal.syntax().text_range(); | ||
30 | |||
31 | acc.add( | ||
32 | AssistId("generate_impl", AssistKind::Generate), | ||
33 | format!("Generate impl for `{}`", name), | ||
34 | target, | ||
35 | |edit| { | ||
36 | let type_params = nominal.generic_param_list(); | ||
37 | let start_offset = nominal.syntax().text_range().end(); | ||
38 | let mut buf = String::new(); | ||
39 | buf.push_str("\n\n"); | ||
40 | nominal | ||
41 | .attrs() | ||
42 | .filter(|attr| { | ||
43 | attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false) | ||
44 | }) | ||
45 | .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str())); | ||
46 | |||
47 | buf.push_str("impl"); | ||
48 | if let Some(type_params) = &type_params { | ||
49 | format_to!(buf, "{}", type_params.syntax()); | ||
50 | } | ||
51 | buf.push_str(" "); | ||
52 | buf.push_str(name.text().as_str()); | ||
53 | if let Some(type_params) = type_params { | ||
54 | let lifetime_params = type_params | ||
55 | .lifetime_params() | ||
56 | .filter_map(|it| it.lifetime()) | ||
57 | .map(|it| it.text().clone()); | ||
58 | let type_params = type_params | ||
59 | .type_params() | ||
60 | .filter_map(|it| it.name()) | ||
61 | .map(|it| it.text().clone()); | ||
62 | |||
63 | let generic_params = lifetime_params.chain(type_params).format(", "); | ||
64 | format_to!(buf, "<{}>", generic_params) | ||
65 | } | ||
66 | match ctx.config.snippet_cap { | ||
67 | Some(cap) => { | ||
68 | buf.push_str(" {\n $0\n}"); | ||
69 | edit.insert_snippet(cap, start_offset, buf); | ||
70 | } | ||
71 | None => { | ||
72 | buf.push_str(" {\n}"); | ||
73 | edit.insert(start_offset, buf); | ||
74 | } | ||
75 | } | ||
76 | }, | ||
77 | ) | ||
78 | } | ||
79 | |||
80 | #[cfg(test)] | ||
81 | mod tests { | ||
82 | use crate::tests::{check_assist, check_assist_target}; | ||
83 | |||
84 | use super::*; | ||
85 | |||
86 | #[test] | ||
87 | fn test_add_impl() { | ||
88 | check_assist( | ||
89 | generate_impl, | ||
90 | "struct Foo {$0}\n", | ||
91 | "struct Foo {}\n\nimpl Foo {\n $0\n}\n", | ||
92 | ); | ||
93 | check_assist( | ||
94 | generate_impl, | ||
95 | "struct Foo<T: Clone> {$0}", | ||
96 | "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n $0\n}", | ||
97 | ); | ||
98 | check_assist( | ||
99 | generate_impl, | ||
100 | "struct Foo<'a, T: Foo<'a>> {$0}", | ||
101 | "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}", | ||
102 | ); | ||
103 | check_assist( | ||
104 | generate_impl, | ||
105 | r#" | ||
106 | #[cfg(feature = "foo")] | ||
107 | struct Foo<'a, T: Foo<'a>> {$0}"#, | ||
108 | r#" | ||
109 | #[cfg(feature = "foo")] | ||
110 | struct Foo<'a, T: Foo<'a>> {} | ||
111 | |||
112 | #[cfg(feature = "foo")] | ||
113 | impl<'a, T: Foo<'a>> Foo<'a, T> { | ||
114 | $0 | ||
115 | }"#, | ||
116 | ); | ||
117 | |||
118 | check_assist( | ||
119 | generate_impl, | ||
120 | r#" | ||
121 | #[cfg(not(feature = "foo"))] | ||
122 | struct Foo<'a, T: Foo<'a>> {$0}"#, | ||
123 | r#" | ||
124 | #[cfg(not(feature = "foo"))] | ||
125 | struct Foo<'a, T: Foo<'a>> {} | ||
126 | |||
127 | #[cfg(not(feature = "foo"))] | ||
128 | impl<'a, T: Foo<'a>> Foo<'a, T> { | ||
129 | $0 | ||
130 | }"#, | ||
131 | ); | ||
132 | } | ||
133 | |||
134 | #[test] | ||
135 | fn add_impl_target() { | ||
136 | check_assist_target( | ||
137 | generate_impl, | ||
138 | " | ||
139 | struct SomeThingIrrelevant; | ||
140 | /// Has a lifetime parameter | ||
141 | struct Foo<'a, T: Foo<'a>> {$0} | ||
142 | struct EvenMoreIrrelevant; | ||
143 | ", | ||
144 | "/// Has a lifetime parameter | ||
145 | struct Foo<'a, T: Foo<'a>> {}", | ||
146 | ); | ||
147 | } | ||
148 | } | ||