diff options
author | Aleksei Sidorov <[email protected]> | 2020-09-02 23:32:18 +0100 |
---|---|---|
committer | Aleksei Sidorov <[email protected]> | 2020-09-03 12:47:07 +0100 |
commit | fe3170dc344f73126cd4ff2f197d49a8b7f2fe1f (patch) | |
tree | 579359e7cc3ee6c132da02f43bc9d83d46a5dbef /crates/assists/src | |
parent | 74e7422b69d35c55ff6fde77258047f0292d36e0 (diff) |
Initial implementation of the #5085 issue
Diffstat (limited to 'crates/assists/src')
-rw-r--r-- | crates/assists/src/handlers/replace_impl_trait_with_generic.rs | 62 | ||||
-rw-r--r-- | crates/assists/src/lib.rs | 2 |
2 files changed, 64 insertions, 0 deletions
diff --git a/crates/assists/src/handlers/replace_impl_trait_with_generic.rs b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs new file mode 100644 index 000000000..8af2d16dd --- /dev/null +++ b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs | |||
@@ -0,0 +1,62 @@ | |||
1 | use syntax::ast::{self, edit::AstNodeEdit, make, AstNode, GenericParamsOwner}; | ||
2 | |||
3 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | ||
4 | |||
5 | // Assist: replace_impl_trait_with_generic | ||
6 | // | ||
7 | // Replaces `impl Trait` function argument with the named generic. | ||
8 | pub(crate) fn replace_impl_trait_with_generic( | ||
9 | acc: &mut Assists, | ||
10 | ctx: &AssistContext, | ||
11 | ) -> Option<()> { | ||
12 | let type_impl_trait = ctx.find_node_at_offset::<ast::ImplTraitType>()?; | ||
13 | let type_param = type_impl_trait.syntax().parent().and_then(ast::Param::cast)?; | ||
14 | let type_fn = type_param.syntax().ancestors().nth(2).and_then(ast::Fn::cast)?; | ||
15 | |||
16 | let generic_param_list = | ||
17 | type_fn.generic_param_list().unwrap_or_else(|| make::generic_param_list(None)); | ||
18 | |||
19 | let impl_trait_ty = type_impl_trait | ||
20 | .syntax() | ||
21 | .descendants() | ||
22 | .last() | ||
23 | .and_then(ast::NameRef::cast)? | ||
24 | .text() | ||
25 | .to_string(); | ||
26 | |||
27 | let target = type_fn.syntax().text_range(); | ||
28 | acc.add( | ||
29 | AssistId("replace_impl_trait_with_generic", AssistKind::RefactorRewrite), | ||
30 | "Replace impl trait with generic", | ||
31 | target, | ||
32 | |edit| { | ||
33 | let generic_letter = impl_trait_ty[..1].to_string(); | ||
34 | edit.replace_ast::<ast::Type>(type_impl_trait.into(), make::ty(&generic_letter)); | ||
35 | |||
36 | let new_params = generic_param_list | ||
37 | .append_param(make::generic_param(generic_letter, Some(impl_trait_ty))); | ||
38 | let new_type_fn = type_fn.replace_descendant(generic_param_list, new_params); | ||
39 | edit.replace_ast(type_fn.clone(), new_type_fn); | ||
40 | }, | ||
41 | ) | ||
42 | } | ||
43 | |||
44 | #[cfg(test)] | ||
45 | mod tests { | ||
46 | use super::*; | ||
47 | |||
48 | use crate::tests::check_assist; | ||
49 | |||
50 | #[test] | ||
51 | fn replace_with_generic_params() { | ||
52 | check_assist( | ||
53 | replace_impl_trait_with_generic, | ||
54 | r#" | ||
55 | fn foo<G>(bar: <|>impl Bar) {} | ||
56 | "#, | ||
57 | r#" | ||
58 | fn foo<G, B: Bar>(bar: B) {} | ||
59 | "#, | ||
60 | ); | ||
61 | } | ||
62 | } | ||
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index 2e0d191a6..cbac53e71 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs | |||
@@ -155,6 +155,7 @@ mod handlers { | |||
155 | mod remove_unused_param; | 155 | mod remove_unused_param; |
156 | mod reorder_fields; | 156 | mod reorder_fields; |
157 | mod replace_if_let_with_match; | 157 | mod replace_if_let_with_match; |
158 | mod replace_impl_trait_with_generic; | ||
158 | mod replace_let_with_if_let; | 159 | mod replace_let_with_if_let; |
159 | mod replace_qualified_name_with_use; | 160 | mod replace_qualified_name_with_use; |
160 | mod replace_unwrap_with_match; | 161 | mod replace_unwrap_with_match; |
@@ -202,6 +203,7 @@ mod handlers { | |||
202 | remove_unused_param::remove_unused_param, | 203 | remove_unused_param::remove_unused_param, |
203 | reorder_fields::reorder_fields, | 204 | reorder_fields::reorder_fields, |
204 | replace_if_let_with_match::replace_if_let_with_match, | 205 | replace_if_let_with_match::replace_if_let_with_match, |
206 | replace_impl_trait_with_generic::replace_impl_trait_with_generic, | ||
205 | replace_let_with_if_let::replace_let_with_if_let, | 207 | replace_let_with_if_let::replace_let_with_if_let, |
206 | replace_qualified_name_with_use::replace_qualified_name_with_use, | 208 | replace_qualified_name_with_use::replace_qualified_name_with_use, |
207 | replace_unwrap_with_match::replace_unwrap_with_match, | 209 | replace_unwrap_with_match::replace_unwrap_with_match, |