diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-05-07 15:28:47 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-05-07 15:28:47 +0100 |
commit | c7e305731c922a2d32eda89ff22cb636059bc4e7 (patch) | |
tree | 4f3ab3a70fbbb901ccec3cd162da00eaa9cbad09 /crates/ra_assists/src/handlers/early_return.rs | |
parent | f4cd75ac06dff7f5a95065a6c3868669e5c2ab27 (diff) | |
parent | 4867968d22899395e6551f22641b3617e995140c (diff) |
Merge #4350
4350: Refactor assists API to be more convenient for adding new assists r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_assists/src/handlers/early_return.rs')
-rw-r--r-- | crates/ra_assists/src/handlers/early_return.rs | 161 |
1 files changed, 78 insertions, 83 deletions
diff --git a/crates/ra_assists/src/handlers/early_return.rs b/crates/ra_assists/src/handlers/early_return.rs index 4bd6040b2..ccf91797c 100644 --- a/crates/ra_assists/src/handlers/early_return.rs +++ b/crates/ra_assists/src/handlers/early_return.rs | |||
@@ -9,7 +9,7 @@ use ra_syntax::{ | |||
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | assist_ctx::{Assist, AssistCtx}, | 12 | assist_context::{AssistContext, Assists}, |
13 | utils::invert_boolean_expression, | 13 | utils::invert_boolean_expression, |
14 | AssistId, | 14 | AssistId, |
15 | }; | 15 | }; |
@@ -36,7 +36,7 @@ use crate::{ | |||
36 | // bar(); | 36 | // bar(); |
37 | // } | 37 | // } |
38 | // ``` | 38 | // ``` |
39 | pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> { | 39 | pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
40 | let if_expr: ast::IfExpr = ctx.find_node_at_offset()?; | 40 | let if_expr: ast::IfExpr = ctx.find_node_at_offset()?; |
41 | if if_expr.else_branch().is_some() { | 41 | if if_expr.else_branch().is_some() { |
42 | return None; | 42 | return None; |
@@ -96,93 +96,88 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> { | |||
96 | let cursor_position = ctx.frange.range.start(); | 96 | let cursor_position = ctx.frange.range.start(); |
97 | 97 | ||
98 | let target = if_expr.syntax().text_range(); | 98 | let target = if_expr.syntax().text_range(); |
99 | ctx.add_assist( | 99 | acc.add(AssistId("convert_to_guarded_return"), "Convert to guarded return", target, |edit| { |
100 | AssistId("convert_to_guarded_return"), | 100 | let if_indent_level = IndentLevel::from_node(&if_expr.syntax()); |
101 | "Convert to guarded return", | 101 | let new_block = match if_let_pat { |
102 | target, | 102 | None => { |
103 | |edit| { | 103 | // If. |
104 | let if_indent_level = IndentLevel::from_node(&if_expr.syntax()); | 104 | let new_expr = { |
105 | let new_block = match if_let_pat { | 105 | let then_branch = |
106 | None => { | 106 | make::block_expr(once(make::expr_stmt(early_expression).into()), None); |
107 | // If. | 107 | let cond = invert_boolean_expression(cond_expr); |
108 | let new_expr = { | 108 | let e = make::expr_if(make::condition(cond, None), then_branch); |
109 | let then_branch = | 109 | if_indent_level.increase_indent(e) |
110 | make::block_expr(once(make::expr_stmt(early_expression).into()), None); | 110 | }; |
111 | let cond = invert_boolean_expression(cond_expr); | 111 | replace(new_expr.syntax(), &then_block, &parent_block, &if_expr) |
112 | let e = make::expr_if(make::condition(cond, None), then_branch); | 112 | } |
113 | if_indent_level.increase_indent(e) | 113 | Some((path, bound_ident)) => { |
114 | }; | 114 | // If-let. |
115 | replace(new_expr.syntax(), &then_block, &parent_block, &if_expr) | 115 | let match_expr = { |
116 | } | 116 | let happy_arm = { |
117 | Some((path, bound_ident)) => { | 117 | let pat = make::tuple_struct_pat( |
118 | // If-let. | 118 | path, |
119 | let match_expr = { | 119 | once(make::bind_pat(make::name("it")).into()), |
120 | let happy_arm = { | ||
121 | let pat = make::tuple_struct_pat( | ||
122 | path, | ||
123 | once(make::bind_pat(make::name("it")).into()), | ||
124 | ); | ||
125 | let expr = { | ||
126 | let name_ref = make::name_ref("it"); | ||
127 | let segment = make::path_segment(name_ref); | ||
128 | let path = make::path_unqualified(segment); | ||
129 | make::expr_path(path) | ||
130 | }; | ||
131 | make::match_arm(once(pat.into()), expr) | ||
132 | }; | ||
133 | |||
134 | let sad_arm = make::match_arm( | ||
135 | // FIXME: would be cool to use `None` or `Err(_)` if appropriate | ||
136 | once(make::placeholder_pat().into()), | ||
137 | early_expression, | ||
138 | ); | 120 | ); |
139 | 121 | let expr = { | |
140 | make::expr_match(cond_expr, make::match_arm_list(vec![happy_arm, sad_arm])) | 122 | let name_ref = make::name_ref("it"); |
123 | let segment = make::path_segment(name_ref); | ||
124 | let path = make::path_unqualified(segment); | ||
125 | make::expr_path(path) | ||
126 | }; | ||
127 | make::match_arm(once(pat.into()), expr) | ||
141 | }; | 128 | }; |
142 | 129 | ||
143 | let let_stmt = make::let_stmt( | 130 | let sad_arm = make::match_arm( |
144 | make::bind_pat(make::name(&bound_ident.syntax().to_string())).into(), | 131 | // FIXME: would be cool to use `None` or `Err(_)` if appropriate |
145 | Some(match_expr), | 132 | once(make::placeholder_pat().into()), |
133 | early_expression, | ||
146 | ); | 134 | ); |
147 | let let_stmt = if_indent_level.increase_indent(let_stmt); | 135 | |
148 | replace(let_stmt.syntax(), &then_block, &parent_block, &if_expr) | 136 | make::expr_match(cond_expr, make::match_arm_list(vec![happy_arm, sad_arm])) |
149 | } | 137 | }; |
150 | }; | 138 | |
151 | edit.replace_ast(parent_block, ast::BlockExpr::cast(new_block).unwrap()); | 139 | let let_stmt = make::let_stmt( |
152 | edit.set_cursor(cursor_position); | 140 | make::bind_pat(make::name(&bound_ident.syntax().to_string())).into(), |
153 | 141 | Some(match_expr), | |
154 | fn replace( | ||
155 | new_expr: &SyntaxNode, | ||
156 | then_block: &ast::BlockExpr, | ||
157 | parent_block: &ast::BlockExpr, | ||
158 | if_expr: &ast::IfExpr, | ||
159 | ) -> SyntaxNode { | ||
160 | let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone()); | ||
161 | let end_of_then = then_block_items.syntax().last_child_or_token().unwrap(); | ||
162 | let end_of_then = | ||
163 | if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) { | ||
164 | end_of_then.prev_sibling_or_token().unwrap() | ||
165 | } else { | ||
166 | end_of_then | ||
167 | }; | ||
168 | let mut then_statements = new_expr.children_with_tokens().chain( | ||
169 | then_block_items | ||
170 | .syntax() | ||
171 | .children_with_tokens() | ||
172 | .skip(1) | ||
173 | .take_while(|i| *i != end_of_then), | ||
174 | ); | 142 | ); |
175 | replace_children( | 143 | let let_stmt = if_indent_level.increase_indent(let_stmt); |
176 | &parent_block.syntax(), | 144 | replace(let_stmt.syntax(), &then_block, &parent_block, &if_expr) |
177 | RangeInclusive::new( | ||
178 | if_expr.clone().syntax().clone().into(), | ||
179 | if_expr.syntax().clone().into(), | ||
180 | ), | ||
181 | &mut then_statements, | ||
182 | ) | ||
183 | } | 145 | } |
184 | }, | 146 | }; |
185 | ) | 147 | edit.replace_ast(parent_block, ast::BlockExpr::cast(new_block).unwrap()); |
148 | edit.set_cursor(cursor_position); | ||
149 | |||
150 | fn replace( | ||
151 | new_expr: &SyntaxNode, | ||
152 | then_block: &ast::BlockExpr, | ||
153 | parent_block: &ast::BlockExpr, | ||
154 | if_expr: &ast::IfExpr, | ||
155 | ) -> SyntaxNode { | ||
156 | let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone()); | ||
157 | let end_of_then = then_block_items.syntax().last_child_or_token().unwrap(); | ||
158 | let end_of_then = | ||
159 | if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) { | ||
160 | end_of_then.prev_sibling_or_token().unwrap() | ||
161 | } else { | ||
162 | end_of_then | ||
163 | }; | ||
164 | let mut then_statements = new_expr.children_with_tokens().chain( | ||
165 | then_block_items | ||
166 | .syntax() | ||
167 | .children_with_tokens() | ||
168 | .skip(1) | ||
169 | .take_while(|i| *i != end_of_then), | ||
170 | ); | ||
171 | replace_children( | ||
172 | &parent_block.syntax(), | ||
173 | RangeInclusive::new( | ||
174 | if_expr.clone().syntax().clone().into(), | ||
175 | if_expr.syntax().clone().into(), | ||
176 | ), | ||
177 | &mut then_statements, | ||
178 | ) | ||
179 | } | ||
180 | }) | ||
186 | } | 181 | } |
187 | 182 | ||
188 | #[cfg(test)] | 183 | #[cfg(test)] |