aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assists/move_bounds.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/assists/move_bounds.rs')
-rw-r--r--crates/ra_assists/src/assists/move_bounds.rs77
1 files changed, 41 insertions, 36 deletions
diff --git a/crates/ra_assists/src/assists/move_bounds.rs b/crates/ra_assists/src/assists/move_bounds.rs
index d2444b6b9..3145d7625 100644
--- a/crates/ra_assists/src/assists/move_bounds.rs
+++ b/crates/ra_assists/src/assists/move_bounds.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use hir::db::HirDatabase; 1use hir::db::HirDatabase;
4use ra_syntax::{ 2use ra_syntax::{
5 ast::{self, edit, make, AstNode, NameOwner, TypeBoundsOwner}, 3 ast::{self, edit, make, AstNode, NameOwner, TypeBoundsOwner},
@@ -9,8 +7,23 @@ use ra_syntax::{
9 7
10use crate::{Assist, AssistCtx, AssistId}; 8use crate::{Assist, AssistCtx, AssistId};
11 9
12pub(crate) fn move_bounds_to_where_clause(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 10// Assist: move_bounds_to_where_clause
13 let type_param_list = ctx.node_at_offset::<ast::TypeParamList>()?; 11//
12// Moves inline type bounds to a where clause.
13//
14// ```
15// fn apply<T, U, <|>F: FnOnce(T) -> U>(f: F, x: T) -> U {
16// f(x)
17// }
18// ```
19// ->
20// ```
21// fn apply<T, U, F>(f: F, x: T) -> U where F: FnOnce(T) -> U {
22// f(x)
23// }
24// ```
25pub(crate) fn move_bounds_to_where_clause(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
26 let type_param_list = ctx.find_node_at_offset::<ast::TypeParamList>()?;
14 27
15 let mut type_params = type_param_list.type_params(); 28 let mut type_params = type_param_list.type_params();
16 if type_params.all(|p| p.type_bound_list().is_none()) { 29 if type_params.all(|p| p.type_bound_list().is_none()) {
@@ -33,38 +46,30 @@ pub(crate) fn move_bounds_to_where_clause(mut ctx: AssistCtx<impl HirDatabase>)
33 _ => return None, 46 _ => return None,
34 }; 47 };
35 48
36 ctx.add_action( 49 ctx.add_assist(AssistId("move_bounds_to_where_clause"), "move_bounds_to_where_clause", |edit| {
37 AssistId("move_bounds_to_where_clause"), 50 let new_params = type_param_list
38 "move_bounds_to_where_clause", 51 .type_params()
39 |edit| { 52 .filter(|it| it.type_bound_list().is_some())
40 let new_params = type_param_list 53 .map(|type_param| {
41 .type_params() 54 let without_bounds = type_param.remove_bounds();
42 .filter(|it| it.type_bound_list().is_some()) 55 (type_param, without_bounds)
43 .map(|type_param| { 56 });
44 let without_bounds = type_param.remove_bounds(); 57
45 (type_param, without_bounds) 58 let new_type_param_list = edit::replace_descendants(&type_param_list, new_params);
46 }); 59 edit.replace_ast(type_param_list.clone(), new_type_param_list);
47 60
48 let new_type_param_list = edit::replace_descendants(&type_param_list, new_params); 61 let where_clause = {
49 edit.replace_ast(type_param_list.clone(), new_type_param_list); 62 let predicates = type_param_list.type_params().filter_map(build_predicate);
50 63 make::where_clause(predicates)
51 let where_clause = { 64 };
52 let predicates = type_param_list.type_params().filter_map(build_predicate); 65
53 make::where_clause(predicates) 66 let to_insert = match anchor.prev_sibling_or_token() {
54 }; 67 Some(ref elem) if elem.kind() == WHITESPACE => format!("{} ", where_clause.syntax()),
55 68 _ => format!(" {}", where_clause.syntax()),
56 let to_insert = match anchor.prev_sibling_or_token() { 69 };
57 Some(ref elem) if elem.kind() == WHITESPACE => { 70 edit.insert(anchor.text_range().start(), to_insert);
58 format!("{} ", where_clause.syntax()) 71 edit.target(type_param_list.syntax().text_range());
59 } 72 })
60 _ => format!(" {}", where_clause.syntax()),
61 };
62 edit.insert(anchor.text_range().start(), to_insert);
63 edit.target(type_param_list.syntax().text_range());
64 },
65 );
66
67 ctx.build()
68} 73}
69 74
70fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> { 75fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> {