aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists')
-rw-r--r--crates/ra_assists/src/assists/early_return.rs87
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;
3use hir::db::HirDatabase; 3use hir::db::HirDatabase;
4use ra_syntax::{ 4use 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
11use crate::{ 12use 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