diff options
-rw-r--r-- | crates/ra_assists/src/assists/early_return.rs | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/crates/ra_assists/src/assists/early_return.rs b/crates/ra_assists/src/assists/early_return.rs index 8536b015b..570a07a20 100644 --- a/crates/ra_assists/src/assists/early_return.rs +++ b/crates/ra_assists/src/assists/early_return.rs | |||
@@ -3,9 +3,10 @@ use std::ops::RangeInclusive; | |||
3 | use hir::db::HirDatabase; | 3 | use hir::db::HirDatabase; |
4 | use ra_syntax::{ | 4 | use ra_syntax::{ |
5 | algo::replace_children, | 5 | algo::replace_children, |
6 | ast::{self, edit::IndentLevel, make, Pat::TupleStructPat}, | 6 | ast::{self, edit::IndentLevel, make, Block, Pat::TupleStructPat}, |
7 | AstNode, | 7 | AstNode, |
8 | SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE}, | 8 | SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE}, |
9 | SyntaxNode, | ||
9 | }; | 10 | }; |
10 | 11 | ||
11 | use crate::{ | 12 | use crate::{ |
@@ -97,68 +98,54 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx<impl HirDatabase>) -> Opt | |||
97 | None => { | 98 | None => { |
98 | // If. | 99 | // If. |
99 | let early_expression = &(early_expression.to_owned() + ";"); | 100 | let early_expression = &(early_expression.to_owned() + ";"); |
100 | let new_if_expr = | 101 | let new_expr = |
101 | if_indent_level.increase_indent(make::if_expression(&expr, early_expression)); | 102 | if_indent_level.increase_indent(make::if_expression(&expr, early_expression)); |
102 | let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone()); | 103 | replace(new_expr, &then_block, &parent_block, &if_expr) |
103 | let end_of_then = then_block_items.syntax().last_child_or_token().unwrap(); | ||
104 | let end_of_then = | ||
105 | if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) { | ||
106 | end_of_then.prev_sibling_or_token().unwrap() | ||
107 | } else { | ||
108 | end_of_then | ||
109 | }; | ||
110 | let mut new_if_and_then_statements = | ||
111 | new_if_expr.syntax().children_with_tokens().chain( | ||
112 | then_block_items | ||
113 | .syntax() | ||
114 | .children_with_tokens() | ||
115 | .skip(1) | ||
116 | .take_while(|i| *i != end_of_then), | ||
117 | ); | ||
118 | replace_children( | ||
119 | &parent_block.syntax(), | ||
120 | RangeInclusive::new( | ||
121 | if_expr.clone().syntax().clone().into(), | ||
122 | if_expr.syntax().clone().into(), | ||
123 | ), | ||
124 | &mut new_if_and_then_statements, | ||
125 | ) | ||
126 | } | 104 | } |
127 | Some(if_let_ident) => { | 105 | Some(if_let_ident) => { |
128 | // If-let. | 106 | // If-let. |
129 | let new_match_expr = if_indent_level.increase_indent(make::let_match_early( | 107 | let new_expr = if_indent_level.increase_indent(make::let_match_early( |
130 | expr, | 108 | expr, |
131 | &if_let_ident, | 109 | &if_let_ident, |
132 | early_expression, | 110 | early_expression, |
133 | )); | 111 | )); |
134 | let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone()); | 112 | replace(new_expr, &then_block, &parent_block, &if_expr) |
135 | let end_of_then = then_block_items.syntax().last_child_or_token().unwrap(); | ||
136 | let end_of_then = | ||
137 | if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) { | ||
138 | end_of_then.prev_sibling_or_token().unwrap() | ||
139 | } else { | ||
140 | end_of_then | ||
141 | }; | ||
142 | let mut then_statements = new_match_expr.syntax().children_with_tokens().chain( | ||
143 | then_block_items | ||
144 | .syntax() | ||
145 | .children_with_tokens() | ||
146 | .skip(1) | ||
147 | .take_while(|i| *i != end_of_then), | ||
148 | ); | ||
149 | replace_children( | ||
150 | &parent_block.syntax(), | ||
151 | RangeInclusive::new( | ||
152 | if_expr.clone().syntax().clone().into(), | ||
153 | if_expr.syntax().clone().into(), | ||
154 | ), | ||
155 | &mut then_statements, | ||
156 | ) | ||
157 | } | 113 | } |
158 | }; | 114 | }; |
159 | edit.target(if_expr.syntax().text_range()); | 115 | edit.target(if_expr.syntax().text_range()); |
160 | edit.replace_ast(parent_block, ast::Block::cast(new_block).unwrap()); | 116 | edit.replace_ast(parent_block, ast::Block::cast(new_block).unwrap()); |
161 | edit.set_cursor(cursor_position); | 117 | edit.set_cursor(cursor_position); |
118 | |||
119 | fn replace( | ||
120 | new_expr: impl AstNode, | ||
121 | then_block: &Block, | ||
122 | parent_block: &Block, | ||
123 | if_expr: &ast::IfExpr, | ||
124 | ) -> SyntaxNode { | ||
125 | let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone()); | ||
126 | let end_of_then = then_block_items.syntax().last_child_or_token().unwrap(); | ||
127 | let end_of_then = | ||
128 | if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) { | ||
129 | end_of_then.prev_sibling_or_token().unwrap() | ||
130 | } else { | ||
131 | end_of_then | ||
132 | }; | ||
133 | let mut then_statements = new_expr.syntax().children_with_tokens().chain( | ||
134 | then_block_items | ||
135 | .syntax() | ||
136 | .children_with_tokens() | ||
137 | .skip(1) | ||
138 | .take_while(|i| *i != end_of_then), | ||
139 | ); | ||
140 | replace_children( | ||
141 | &parent_block.syntax(), | ||
142 | RangeInclusive::new( | ||
143 | if_expr.clone().syntax().clone().into(), | ||
144 | if_expr.syntax().clone().into(), | ||
145 | ), | ||
146 | &mut then_statements, | ||
147 | ) | ||
148 | } | ||
162 | }) | 149 | }) |
163 | } | 150 | } |
164 | 151 | ||