diff options
Diffstat (limited to 'crates/assists/src/handlers')
-rw-r--r-- | crates/assists/src/handlers/replace_derive_with_manual_impl.rs (renamed from crates/assists/src/handlers/add_custom_impl.rs) | 103 |
1 files changed, 58 insertions, 45 deletions
diff --git a/crates/assists/src/handlers/add_custom_impl.rs b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs index c13493fd8..82625516c 100644 --- a/crates/assists/src/handlers/add_custom_impl.rs +++ b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs | |||
@@ -16,24 +16,31 @@ use crate::{ | |||
16 | AssistId, AssistKind, | 16 | AssistId, AssistKind, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | // Assist: add_custom_impl | 19 | // Assist: replace_derive_with_manual_impl |
20 | // | 20 | // |
21 | // Adds impl block for derived trait. | 21 | // Converts a `derive` impl into a manual one. |
22 | // | 22 | // |
23 | // ``` | 23 | // ``` |
24 | // # trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; } | ||
24 | // #[derive(Deb<|>ug, Display)] | 25 | // #[derive(Deb<|>ug, Display)] |
25 | // struct S; | 26 | // struct S; |
26 | // ``` | 27 | // ``` |
27 | // -> | 28 | // -> |
28 | // ``` | 29 | // ``` |
30 | // # trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; } | ||
29 | // #[derive(Display)] | 31 | // #[derive(Display)] |
30 | // struct S; | 32 | // struct S; |
31 | // | 33 | // |
32 | // impl Debug for S { | 34 | // impl Debug for S { |
33 | // $0 | 35 | // fn fmt(&self, f: &mut Formatter) -> Result<()> { |
36 | // ${0:todo!()} | ||
37 | // } | ||
34 | // } | 38 | // } |
35 | // ``` | 39 | // ``` |
36 | pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 40 | pub(crate) fn replace_derive_with_manual_impl( |
41 | acc: &mut Assists, | ||
42 | ctx: &AssistContext, | ||
43 | ) -> Option<()> { | ||
37 | let attr = ctx.find_node_at_offset::<ast::Attr>()?; | 44 | let attr = ctx.find_node_at_offset::<ast::Attr>()?; |
38 | 45 | ||
39 | let attr_name = attr | 46 | let attr_name = attr |
@@ -90,43 +97,49 @@ fn add_assist( | |||
90 | ) -> Option<()> { | 97 | ) -> Option<()> { |
91 | let target = attr.syntax().text_range(); | 98 | let target = attr.syntax().text_range(); |
92 | let input = attr.token_tree()?; | 99 | let input = attr.token_tree()?; |
93 | let label = format!("Add custom impl `{}` for `{}`", trait_path, annotated_name); | 100 | let label = format!("Convert to manual `impl {} for {}`", trait_path, annotated_name); |
94 | let trait_name = trait_path.segment().and_then(|seg| seg.name_ref())?; | 101 | let trait_name = trait_path.segment().and_then(|seg| seg.name_ref())?; |
95 | 102 | ||
96 | acc.add(AssistId("add_custom_impl", AssistKind::Refactor), label, target, |builder| { | 103 | acc.add( |
97 | let impl_def_with_items = | 104 | AssistId("replace_derive_with_manual_impl", AssistKind::Refactor), |
98 | impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path); | 105 | label, |
99 | update_attribute(builder, &input, &trait_name, &attr); | 106 | target, |
100 | match (ctx.config.snippet_cap, impl_def_with_items) { | 107 | |builder| { |
101 | (None, _) => builder.insert( | 108 | let impl_def_with_items = |
102 | insert_pos, | 109 | impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path); |
103 | format!("\n\nimpl {} for {} {{\n\n}}", trait_path, annotated_name), | 110 | update_attribute(builder, &input, &trait_name, &attr); |
104 | ), | 111 | match (ctx.config.snippet_cap, impl_def_with_items) { |
105 | (Some(cap), None) => builder.insert_snippet( | 112 | (None, _) => builder.insert( |
106 | cap, | 113 | insert_pos, |
107 | insert_pos, | 114 | format!("\n\nimpl {} for {} {{\n\n}}", trait_path, annotated_name), |
108 | format!("\n\nimpl {} for {} {{\n $0\n}}", trait_path, annotated_name), | 115 | ), |
109 | ), | 116 | (Some(cap), None) => builder.insert_snippet( |
110 | (Some(cap), Some((impl_def, first_assoc_item))) => { | 117 | cap, |
111 | let mut cursor = Cursor::Before(first_assoc_item.syntax()); | 118 | insert_pos, |
112 | let placeholder; | 119 | format!("\n\nimpl {} for {} {{\n $0\n}}", trait_path, annotated_name), |
113 | if let ast::AssocItem::Fn(ref func) = first_assoc_item { | 120 | ), |
114 | if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast) { | 121 | (Some(cap), Some((impl_def, first_assoc_item))) => { |
115 | if m.syntax().text() == "todo!()" { | 122 | let mut cursor = Cursor::Before(first_assoc_item.syntax()); |
116 | placeholder = m; | 123 | let placeholder; |
117 | cursor = Cursor::Replace(placeholder.syntax()); | 124 | if let ast::AssocItem::Fn(ref func) = first_assoc_item { |
125 | if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast) | ||
126 | { | ||
127 | if m.syntax().text() == "todo!()" { | ||
128 | placeholder = m; | ||
129 | cursor = Cursor::Replace(placeholder.syntax()); | ||
130 | } | ||
118 | } | 131 | } |
119 | } | 132 | } |
120 | } | ||
121 | 133 | ||
122 | builder.insert_snippet( | 134 | builder.insert_snippet( |
123 | cap, | 135 | cap, |
124 | insert_pos, | 136 | insert_pos, |
125 | format!("\n\n{}", render_snippet(cap, impl_def.syntax(), cursor)), | 137 | format!("\n\n{}", render_snippet(cap, impl_def.syntax(), cursor)), |
126 | ) | 138 | ) |
127 | } | 139 | } |
128 | }; | 140 | }; |
129 | }) | 141 | }, |
142 | ) | ||
130 | } | 143 | } |
131 | 144 | ||
132 | fn impl_def_from_trait( | 145 | fn impl_def_from_trait( |
@@ -192,7 +205,7 @@ mod tests { | |||
192 | #[test] | 205 | #[test] |
193 | fn add_custom_impl_debug() { | 206 | fn add_custom_impl_debug() { |
194 | check_assist( | 207 | check_assist( |
195 | add_custom_impl, | 208 | replace_derive_with_manual_impl, |
196 | " | 209 | " |
197 | mod fmt { | 210 | mod fmt { |
198 | pub struct Error; | 211 | pub struct Error; |
@@ -233,7 +246,7 @@ impl fmt::Debug for Foo { | |||
233 | #[test] | 246 | #[test] |
234 | fn add_custom_impl_all() { | 247 | fn add_custom_impl_all() { |
235 | check_assist( | 248 | check_assist( |
236 | add_custom_impl, | 249 | replace_derive_with_manual_impl, |
237 | " | 250 | " |
238 | mod foo { | 251 | mod foo { |
239 | pub trait Bar { | 252 | pub trait Bar { |
@@ -282,7 +295,7 @@ impl foo::Bar for Foo { | |||
282 | #[test] | 295 | #[test] |
283 | fn add_custom_impl_for_unique_input() { | 296 | fn add_custom_impl_for_unique_input() { |
284 | check_assist( | 297 | check_assist( |
285 | add_custom_impl, | 298 | replace_derive_with_manual_impl, |
286 | " | 299 | " |
287 | #[derive(Debu<|>g)] | 300 | #[derive(Debu<|>g)] |
288 | struct Foo { | 301 | struct Foo { |
@@ -304,7 +317,7 @@ impl Debug for Foo { | |||
304 | #[test] | 317 | #[test] |
305 | fn add_custom_impl_for_with_visibility_modifier() { | 318 | fn add_custom_impl_for_with_visibility_modifier() { |
306 | check_assist( | 319 | check_assist( |
307 | add_custom_impl, | 320 | replace_derive_with_manual_impl, |
308 | " | 321 | " |
309 | #[derive(Debug<|>)] | 322 | #[derive(Debug<|>)] |
310 | pub struct Foo { | 323 | pub struct Foo { |
@@ -326,7 +339,7 @@ impl Debug for Foo { | |||
326 | #[test] | 339 | #[test] |
327 | fn add_custom_impl_when_multiple_inputs() { | 340 | fn add_custom_impl_when_multiple_inputs() { |
328 | check_assist( | 341 | check_assist( |
329 | add_custom_impl, | 342 | replace_derive_with_manual_impl, |
330 | " | 343 | " |
331 | #[derive(Display, Debug<|>, Serialize)] | 344 | #[derive(Display, Debug<|>, Serialize)] |
332 | struct Foo {} | 345 | struct Foo {} |
@@ -345,7 +358,7 @@ impl Debug for Foo { | |||
345 | #[test] | 358 | #[test] |
346 | fn test_ignore_derive_macro_without_input() { | 359 | fn test_ignore_derive_macro_without_input() { |
347 | check_assist_not_applicable( | 360 | check_assist_not_applicable( |
348 | add_custom_impl, | 361 | replace_derive_with_manual_impl, |
349 | " | 362 | " |
350 | #[derive(<|>)] | 363 | #[derive(<|>)] |
351 | struct Foo {} | 364 | struct Foo {} |
@@ -356,7 +369,7 @@ struct Foo {} | |||
356 | #[test] | 369 | #[test] |
357 | fn test_ignore_if_cursor_on_param() { | 370 | fn test_ignore_if_cursor_on_param() { |
358 | check_assist_not_applicable( | 371 | check_assist_not_applicable( |
359 | add_custom_impl, | 372 | replace_derive_with_manual_impl, |
360 | " | 373 | " |
361 | #[derive<|>(Debug)] | 374 | #[derive<|>(Debug)] |
362 | struct Foo {} | 375 | struct Foo {} |
@@ -364,7 +377,7 @@ struct Foo {} | |||
364 | ); | 377 | ); |
365 | 378 | ||
366 | check_assist_not_applicable( | 379 | check_assist_not_applicable( |
367 | add_custom_impl, | 380 | replace_derive_with_manual_impl, |
368 | " | 381 | " |
369 | #[derive(Debug)<|>] | 382 | #[derive(Debug)<|>] |
370 | struct Foo {} | 383 | struct Foo {} |
@@ -375,7 +388,7 @@ struct Foo {} | |||
375 | #[test] | 388 | #[test] |
376 | fn test_ignore_if_not_derive() { | 389 | fn test_ignore_if_not_derive() { |
377 | check_assist_not_applicable( | 390 | check_assist_not_applicable( |
378 | add_custom_impl, | 391 | replace_derive_with_manual_impl, |
379 | " | 392 | " |
380 | #[allow(non_camel_<|>case_types)] | 393 | #[allow(non_camel_<|>case_types)] |
381 | struct Foo {} | 394 | struct Foo {} |