1- use std:: { iter:: once, ops :: RangeInclusive } ;
1+ use std:: iter:: once;
22
33use syntax:: {
4- algo:: replace_children,
54 ast:: {
65 self ,
76 edit:: { AstNodeEdit , IndentLevel } ,
87 make,
98 } ,
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 ,
1312} ;
1413
1514use crate :: {
@@ -53,17 +52,16 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
5352 None => None , // No IfLet, supported.
5453 Some ( ast:: Pat :: TupleStructPat ( pat) ) if pat. fields ( ) . count ( ) == 1 => {
5554 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 ;
6662 }
63+
64+ Some ( ( path, bound_ident) )
6765 }
6866 Some ( _) => return None , // Unsupported IfLet.
6967 } ;
@@ -96,20 +94,21 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
9694 _ => return None ,
9795 } ;
9896
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 ( ) {
10098 return None ;
10199 }
102100
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 ! [ '}' ] ) ?;
104102
105103 let target = if_expr. syntax ( ) . text_range ( ) ;
106104 acc. add (
107105 AssistId ( "convert_to_guarded_return" , AssistKind :: RefactorRewrite ) ,
108106 "Convert to guarded return" ,
109107 target,
110108 |edit| {
109+ let if_expr = edit. make_mut ( if_expr) ;
111110 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 {
113112 None => {
114113 // If.
115114 let new_expr = {
@@ -119,7 +118,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
119118 make:: expr_if ( make:: condition ( cond, None ) , then_branch, None )
120119 . indent ( if_indent_level)
121120 } ;
122- replace ( new_expr. syntax ( ) , & then_block , & parent_block , & if_expr )
121+ new_expr. syntax ( ) . clone_for_update ( )
123122 }
124123 Some ( ( path, bound_ident) ) => {
125124 // If-let.
@@ -148,41 +147,32 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
148147
149148 let let_stmt = make:: let_stmt ( bound_ident, None , Some ( match_expr) ) ;
150149 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 ( )
152151 }
153152 } ;
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 (
171167 then_block_items
172168 . syntax ( )
173169 . children_with_tokens ( )
174170 . skip ( 1 )
175171 . 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,
184172 )
185- }
173+ . collect ( ) ;
174+
175+ ted:: replace_with_many ( if_expr. syntax ( ) , then_statements)
186176 } ,
187177 )
188178}
0 commit comments