diff options
Diffstat (limited to 'crates/ra_assists/src/handlers/move_bounds.rs')
-rw-r--r-- | crates/ra_assists/src/handlers/move_bounds.rs | 69 |
1 files changed, 38 insertions, 31 deletions
diff --git a/crates/ra_assists/src/handlers/move_bounds.rs b/crates/ra_assists/src/handlers/move_bounds.rs index be2a7eddc..6d394443e 100644 --- a/crates/ra_assists/src/handlers/move_bounds.rs +++ b/crates/ra_assists/src/handlers/move_bounds.rs | |||
@@ -5,7 +5,7 @@ use ra_syntax::{ | |||
5 | T, | 5 | T, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{AssistContext, AssistId, Assists}; | 8 | use crate::{AssistContext, AssistId, AssistKind, Assists}; |
9 | 9 | ||
10 | // Assist: move_bounds_to_where_clause | 10 | // Assist: move_bounds_to_where_clause |
11 | // | 11 | // |
@@ -23,7 +23,7 @@ use crate::{AssistContext, AssistId, Assists}; | |||
23 | // } | 23 | // } |
24 | // ``` | 24 | // ``` |
25 | pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 25 | pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
26 | let type_param_list = ctx.find_node_at_offset::<ast::TypeParamList>()?; | 26 | let type_param_list = ctx.find_node_at_offset::<ast::GenericParamList>()?; |
27 | 27 | ||
28 | let mut type_params = type_param_list.type_params(); | 28 | let mut type_params = type_param_list.type_params(); |
29 | if type_params.all(|p| p.type_bound_list().is_none()) { | 29 | if type_params.all(|p| p.type_bound_list().is_none()) { |
@@ -37,42 +37,49 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext | |||
37 | 37 | ||
38 | let anchor = match_ast! { | 38 | let anchor = match_ast! { |
39 | match parent { | 39 | match parent { |
40 | ast::FnDef(it) => it.body()?.syntax().clone().into(), | 40 | ast::Fn(it) => it.body()?.syntax().clone().into(), |
41 | ast::TraitDef(it) => it.item_list()?.syntax().clone().into(), | 41 | ast::Trait(it) => it.assoc_item_list()?.syntax().clone().into(), |
42 | ast::ImplDef(it) => it.item_list()?.syntax().clone().into(), | 42 | ast::Impl(it) => it.assoc_item_list()?.syntax().clone().into(), |
43 | ast::EnumDef(it) => it.variant_list()?.syntax().clone().into(), | 43 | ast::Enum(it) => it.variant_list()?.syntax().clone().into(), |
44 | ast::StructDef(it) => { | 44 | ast::Struct(it) => { |
45 | it.syntax().children_with_tokens() | 45 | it.syntax().children_with_tokens() |
46 | .find(|it| it.kind() == RECORD_FIELD_DEF_LIST || it.kind() == T![;])? | 46 | .find(|it| it.kind() == RECORD_FIELD_LIST || it.kind() == T![;])? |
47 | }, | 47 | }, |
48 | _ => return None | 48 | _ => return None |
49 | } | 49 | } |
50 | }; | 50 | }; |
51 | 51 | ||
52 | let target = type_param_list.syntax().text_range(); | 52 | let target = type_param_list.syntax().text_range(); |
53 | acc.add(AssistId("move_bounds_to_where_clause"), "Move to where clause", target, |edit| { | 53 | acc.add( |
54 | let new_params = type_param_list | 54 | AssistId("move_bounds_to_where_clause", AssistKind::RefactorRewrite), |
55 | .type_params() | 55 | "Move to where clause", |
56 | .filter(|it| it.type_bound_list().is_some()) | 56 | target, |
57 | .map(|type_param| { | 57 | |edit| { |
58 | let without_bounds = type_param.remove_bounds(); | 58 | let new_params = type_param_list |
59 | (type_param, without_bounds) | 59 | .type_params() |
60 | }); | 60 | .filter(|it| it.type_bound_list().is_some()) |
61 | 61 | .map(|type_param| { | |
62 | let new_type_param_list = type_param_list.replace_descendants(new_params); | 62 | let without_bounds = type_param.remove_bounds(); |
63 | edit.replace_ast(type_param_list.clone(), new_type_param_list); | 63 | (type_param, without_bounds) |
64 | 64 | }); | |
65 | let where_clause = { | 65 | |
66 | let predicates = type_param_list.type_params().filter_map(build_predicate); | 66 | let new_type_param_list = type_param_list.replace_descendants(new_params); |
67 | make::where_clause(predicates) | 67 | edit.replace_ast(type_param_list.clone(), new_type_param_list); |
68 | }; | 68 | |
69 | 69 | let where_clause = { | |
70 | let to_insert = match anchor.prev_sibling_or_token() { | 70 | let predicates = type_param_list.type_params().filter_map(build_predicate); |
71 | Some(ref elem) if elem.kind() == WHITESPACE => format!("{} ", where_clause.syntax()), | 71 | make::where_clause(predicates) |
72 | _ => format!(" {}", where_clause.syntax()), | 72 | }; |
73 | }; | 73 | |
74 | edit.insert(anchor.text_range().start(), to_insert); | 74 | let to_insert = match anchor.prev_sibling_or_token() { |
75 | }) | 75 | Some(ref elem) if elem.kind() == WHITESPACE => { |
76 | format!("{} ", where_clause.syntax()) | ||
77 | } | ||
78 | _ => format!(" {}", where_clause.syntax()), | ||
79 | }; | ||
80 | edit.insert(anchor.text_range().start(), to_insert); | ||
81 | }, | ||
82 | ) | ||
76 | } | 83 | } |
77 | 84 | ||
78 | fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> { | 85 | fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> { |