aboutsummaryrefslogtreecommitdiff
path: root/crates/assists
diff options
context:
space:
mode:
authorAleksei Sidorov <[email protected]>2020-09-02 23:32:18 +0100
committerAleksei Sidorov <[email protected]>2020-09-03 12:47:07 +0100
commitfe3170dc344f73126cd4ff2f197d49a8b7f2fe1f (patch)
tree579359e7cc3ee6c132da02f43bc9d83d46a5dbef /crates/assists
parent74e7422b69d35c55ff6fde77258047f0292d36e0 (diff)
Initial implementation of the #5085 issue
Diffstat (limited to 'crates/assists')
-rw-r--r--crates/assists/src/handlers/replace_impl_trait_with_generic.rs62
-rw-r--r--crates/assists/src/lib.rs2
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 @@
1use syntax::ast::{self, edit::AstNodeEdit, make, AstNode, GenericParamsOwner};
2
3use crate::{AssistContext, AssistId, AssistKind, Assists};
4
5// Assist: replace_impl_trait_with_generic
6//
7// Replaces `impl Trait` function argument with the named generic.
8pub(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)]
45mod 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,