diff options
Diffstat (limited to 'crates/ide_assists/src/handlers/move_bounds.rs')
-rw-r--r-- | crates/ide_assists/src/handlers/move_bounds.rs | 62 |
1 files changed, 21 insertions, 41 deletions
diff --git a/crates/ide_assists/src/handlers/move_bounds.rs b/crates/ide_assists/src/handlers/move_bounds.rs index cf260c6f8..48efa67ed 100644 --- a/crates/ide_assists/src/handlers/move_bounds.rs +++ b/crates/ide_assists/src/handlers/move_bounds.rs | |||
@@ -1,8 +1,6 @@ | |||
1 | use syntax::{ | 1 | use syntax::{ |
2 | ast::{self, edit::AstNodeEdit, make, AstNode, NameOwner, TypeBoundsOwner}, | 2 | ast::{self, edit_in_place::GenericParamsOwnerEdit, make, AstNode, NameOwner, TypeBoundsOwner}, |
3 | match_ast, | 3 | match_ast, |
4 | SyntaxKind::*, | ||
5 | T, | ||
6 | }; | 4 | }; |
7 | 5 | ||
8 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 6 | use crate::{AssistContext, AssistId, AssistKind, Assists}; |
@@ -23,7 +21,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
23 | // } | 21 | // } |
24 | // ``` | 22 | // ``` |
25 | pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 23 | 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::GenericParamList>()?; | 24 | let type_param_list = ctx.find_node_at_offset::<ast::GenericParamList>()?.clone_for_update(); |
27 | 25 | ||
28 | let mut type_params = type_param_list.type_params(); | 26 | let mut type_params = type_param_list.type_params(); |
29 | if type_params.all(|p| p.type_bound_list().is_none()) { | 27 | if type_params.all(|p| p.type_bound_list().is_none()) { |
@@ -31,23 +29,7 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext | |||
31 | } | 29 | } |
32 | 30 | ||
33 | let parent = type_param_list.syntax().parent()?; | 31 | let parent = type_param_list.syntax().parent()?; |
34 | if parent.children_with_tokens().any(|it| it.kind() == WHERE_CLAUSE) { | 32 | let original_parent_range = parent.text_range(); |
35 | return None; | ||
36 | } | ||
37 | |||
38 | let anchor = match_ast! { | ||
39 | match parent { | ||
40 | ast::Fn(it) => it.body()?.syntax().clone().into(), | ||
41 | ast::Trait(it) => it.assoc_item_list()?.syntax().clone().into(), | ||
42 | ast::Impl(it) => it.assoc_item_list()?.syntax().clone().into(), | ||
43 | ast::Enum(it) => it.variant_list()?.syntax().clone().into(), | ||
44 | ast::Struct(it) => { | ||
45 | it.syntax().children_with_tokens() | ||
46 | .find(|it| it.kind() == RECORD_FIELD_LIST || it.kind() == T![;])? | ||
47 | }, | ||
48 | _ => return None | ||
49 | } | ||
50 | }; | ||
51 | 33 | ||
52 | let target = type_param_list.syntax().text_range(); | 34 | let target = type_param_list.syntax().text_range(); |
53 | acc.add( | 35 | acc.add( |
@@ -55,29 +37,27 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext | |||
55 | "Move to where clause", | 37 | "Move to where clause", |
56 | target, | 38 | target, |
57 | |edit| { | 39 | |edit| { |
58 | let new_params = type_param_list | 40 | let where_clause: ast::WhereClause = match_ast! { |
59 | .type_params() | 41 | match parent { |
60 | .filter(|it| it.type_bound_list().is_some()) | 42 | ast::Fn(it) => it.get_or_create_where_clause(), |
61 | .map(|type_param| { | 43 | // ast::Trait(it) => it.get_or_create_where_clause(), |
62 | let without_bounds = type_param.remove_bounds(); | 44 | ast::Impl(it) => it.get_or_create_where_clause(), |
63 | (type_param, without_bounds) | 45 | // ast::Enum(it) => it.get_or_create_where_clause(), |
64 | }); | 46 | ast::Struct(it) => it.get_or_create_where_clause(), |
65 | 47 | _ => return, | |
66 | let new_type_param_list = type_param_list.replace_descendants(new_params); | 48 | } |
67 | edit.replace_ast(type_param_list.clone(), new_type_param_list); | ||
68 | |||
69 | let where_clause = { | ||
70 | let predicates = type_param_list.type_params().filter_map(build_predicate); | ||
71 | make::where_clause(predicates) | ||
72 | }; | 49 | }; |
73 | 50 | ||
74 | let to_insert = match anchor.prev_sibling_or_token() { | 51 | for type_param in type_param_list.type_params() { |
75 | Some(ref elem) if elem.kind() == WHITESPACE => { | 52 | if let Some(tbl) = type_param.type_bound_list() { |
76 | format!("{} ", where_clause.syntax()) | 53 | if let Some(predicate) = build_predicate(type_param.clone()) { |
54 | where_clause.add_predicate(predicate.clone_for_update()) | ||
55 | } | ||
56 | tbl.remove() | ||
77 | } | 57 | } |
78 | _ => format!(" {}", where_clause.syntax()), | 58 | } |
79 | }; | 59 | |
80 | edit.insert(anchor.text_range().start(), to_insert); | 60 | edit.replace(original_parent_range, parent.to_string()) |
81 | }, | 61 | }, |
82 | ) | 62 | ) |
83 | } | 63 | } |