1
- use std:: { iter:: once, ops :: RangeInclusive } ;
1
+ use std:: iter:: once;
2
2
3
3
use syntax:: {
4
- algo:: replace_children,
5
4
ast:: {
6
5
self ,
7
6
edit:: { AstNodeEdit , IndentLevel } ,
8
7
make,
9
8
} ,
10
- AstNode ,
11
- SyntaxKind :: { FN , LOOP_EXPR , L_CURLY , R_CURLY , WHILE_EXPR , WHITESPACE } ,
12
- SyntaxNode ,
9
+ ted , AstNode ,
10
+ SyntaxKind :: { FN , LOOP_EXPR , WHILE_EXPR , WHITESPACE } ,
11
+ T ,
13
12
} ;
14
13
15
14
use crate :: {
@@ -53,17 +52,16 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
53
52
None => None , // No IfLet, supported.
54
53
Some ( ast:: Pat :: TupleStructPat ( pat) ) if pat. fields ( ) . count ( ) == 1 => {
55
54
let path = pat. path ( ) ?;
56
- match path. qualifier ( ) {
57
- None => {
58
- let bound_ident = pat. fields ( ) . next ( ) . unwrap ( ) ;
59
- if ast:: IdentPat :: can_cast ( bound_ident. syntax ( ) . kind ( ) ) {
60
- Some ( ( path, bound_ident) )
61
- } else {
62
- return None ;
63
- }
64
- }
65
- Some ( _) => return None ,
55
+ if path. qualifier ( ) . is_some ( ) {
56
+ return None ;
57
+ }
58
+
59
+ let bound_ident = pat. fields ( ) . next ( ) . unwrap ( ) ;
60
+ if !ast:: IdentPat :: can_cast ( bound_ident. syntax ( ) . kind ( ) ) {
61
+ return None ;
66
62
}
63
+
64
+ Some ( ( path, bound_ident) )
67
65
}
68
66
Some ( _) => return None , // Unsupported IfLet.
69
67
} ;
@@ -96,20 +94,21 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
96
94
_ => return None ,
97
95
} ;
98
96
99
- if then_block. syntax ( ) . first_child_or_token ( ) . map ( |t| t. kind ( ) == L_CURLY ) . is_none ( ) {
97
+ if then_block. syntax ( ) . first_child_or_token ( ) . map ( |t| t. kind ( ) == T ! [ '{' ] ) . is_none ( ) {
100
98
return None ;
101
99
}
102
100
103
- then_block. syntax ( ) . last_child_or_token ( ) . filter ( |t| t. kind ( ) == R_CURLY ) ?;
101
+ then_block. syntax ( ) . last_child_or_token ( ) . filter ( |t| t. kind ( ) == T ! [ '}' ] ) ?;
104
102
105
103
let target = if_expr. syntax ( ) . text_range ( ) ;
106
104
acc. add (
107
105
AssistId ( "convert_to_guarded_return" , AssistKind :: RefactorRewrite ) ,
108
106
"Convert to guarded return" ,
109
107
target,
110
108
|edit| {
109
+ let if_expr = edit. make_mut ( if_expr) ;
111
110
let if_indent_level = IndentLevel :: from_node ( if_expr. syntax ( ) ) ;
112
- let new_block = match if_let_pat {
111
+ let replacement = match if_let_pat {
113
112
None => {
114
113
// If.
115
114
let new_expr = {
@@ -119,7 +118,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
119
118
make:: expr_if ( make:: condition ( cond, None ) , then_branch, None )
120
119
. indent ( if_indent_level)
121
120
} ;
122
- replace ( new_expr. syntax ( ) , & then_block , & parent_block , & if_expr )
121
+ new_expr. syntax ( ) . clone_for_update ( )
123
122
}
124
123
Some ( ( path, bound_ident) ) => {
125
124
// If-let.
@@ -148,41 +147,32 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
148
147
149
148
let let_stmt = make:: let_stmt ( bound_ident, None , Some ( match_expr) ) ;
150
149
let let_stmt = let_stmt. indent ( if_indent_level) ;
151
- replace ( let_stmt. syntax ( ) , & then_block , & parent_block , & if_expr )
150
+ let_stmt. syntax ( ) . clone_for_update ( )
152
151
}
153
152
} ;
154
- edit. replace_ast ( parent_block, ast:: BlockExpr :: cast ( new_block) . unwrap ( ) ) ;
155
-
156
- fn replace (
157
- new_expr : & SyntaxNode ,
158
- then_block : & ast:: BlockExpr ,
159
- parent_block : & ast:: BlockExpr ,
160
- if_expr : & ast:: IfExpr ,
161
- ) -> SyntaxNode {
162
- let then_block_items = then_block. dedent ( IndentLevel ( 1 ) ) ;
163
- let end_of_then = then_block_items. syntax ( ) . last_child_or_token ( ) . unwrap ( ) ;
164
- let end_of_then =
165
- if end_of_then. prev_sibling_or_token ( ) . map ( |n| n. kind ( ) ) == Some ( WHITESPACE ) {
166
- end_of_then. prev_sibling_or_token ( ) . unwrap ( )
167
- } else {
168
- end_of_then
169
- } ;
170
- let mut then_statements = new_expr. children_with_tokens ( ) . chain (
153
+
154
+ let then_block_items = then_block. dedent ( IndentLevel ( 1 ) ) . clone_for_update ( ) ;
155
+
156
+ let end_of_then = then_block_items. syntax ( ) . last_child_or_token ( ) . unwrap ( ) ;
157
+ let end_of_then =
158
+ if end_of_then. prev_sibling_or_token ( ) . map ( |n| n. kind ( ) ) == Some ( WHITESPACE ) {
159
+ end_of_then. prev_sibling_or_token ( ) . unwrap ( )
160
+ } else {
161
+ end_of_then
162
+ } ;
163
+
164
+ let then_statements = replacement
165
+ . children_with_tokens ( )
166
+ . chain (
171
167
then_block_items
172
168
. syntax ( )
173
169
. children_with_tokens ( )
174
170
. skip ( 1 )
175
171
. take_while ( |i| * i != end_of_then) ,
176
- ) ;
177
- replace_children (
178
- parent_block. syntax ( ) ,
179
- RangeInclusive :: new (
180
- if_expr. clone ( ) . syntax ( ) . clone ( ) . into ( ) ,
181
- if_expr. syntax ( ) . clone ( ) . into ( ) ,
182
- ) ,
183
- & mut then_statements,
184
172
)
185
- }
173
+ . collect ( ) ;
174
+
175
+ ted:: replace_with_many ( if_expr. syntax ( ) , then_statements)
186
176
} ,
187
177
)
188
178
}
0 commit comments