11use syntax:: {
2- ast:: { edit:: AstNodeEdit , make, AstNode , IfExpr , MatchArm } ,
2+ ast:: { edit:: AstNodeEdit , make, AstNode , BlockExpr , Expr , IfExpr , MatchArm } ,
33 SyntaxKind :: WHITESPACE ,
44} ;
55
@@ -92,9 +92,20 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) ->
9292pub ( crate ) fn move_arm_cond_to_match_guard ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
9393 let match_arm: MatchArm = ctx. find_node_at_offset :: < MatchArm > ( ) ?;
9494 let match_pat = match_arm. pat ( ) ?;
95-
9695 let arm_body = match_arm. expr ( ) ?;
97- let if_expr: IfExpr = IfExpr :: cast ( arm_body. syntax ( ) . clone ( ) ) ?;
96+
97+ let mut replace_node = None ;
98+ let if_expr: IfExpr = IfExpr :: cast ( arm_body. syntax ( ) . clone ( ) ) . or_else ( || {
99+ let block_expr = BlockExpr :: cast ( arm_body. syntax ( ) . clone ( ) ) ?;
100+ if let Expr :: IfExpr ( e) = block_expr. expr ( ) ? {
101+ replace_node = Some ( block_expr. syntax ( ) . clone ( ) ) ;
102+ Some ( e)
103+ } else {
104+ None
105+ }
106+ } ) ?;
107+ let replace_node = replace_node. unwrap_or_else ( || if_expr. syntax ( ) . clone ( ) ) ;
108+
98109 let cond = if_expr. condition ( ) ?;
99110 let then_block = if_expr. then_branch ( ) ?;
100111
@@ -109,19 +120,23 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex
109120
110121 let buf = format ! ( " if {}" , cond. syntax( ) . text( ) ) ;
111122
112- let target = if_expr. syntax ( ) . text_range ( ) ;
113123 acc. add (
114124 AssistId ( "move_arm_cond_to_match_guard" , AssistKind :: RefactorRewrite ) ,
115125 "Move condition to match guard" ,
116- target ,
126+ replace_node . text_range ( ) ,
117127 |edit| {
118128 let then_only_expr = then_block. statements ( ) . next ( ) . is_none ( ) ;
119129
120130 match & then_block. expr ( ) {
121131 Some ( then_expr) if then_only_expr => {
122- edit. replace ( if_expr . syntax ( ) . text_range ( ) , then_expr. syntax ( ) . text ( ) )
132+ edit. replace ( replace_node . text_range ( ) , then_expr. syntax ( ) . text ( ) )
123133 }
124- _ => edit. replace ( if_expr. syntax ( ) . text_range ( ) , then_block. syntax ( ) . text ( ) ) ,
134+ _ if replace_node != * if_expr. syntax ( ) => {
135+ // Dedent because if_expr is in a BlockExpr
136+ let replace_with = then_block. dedent ( 1 . into ( ) ) . syntax ( ) . text ( ) ;
137+ edit. replace ( replace_node. text_range ( ) , replace_with)
138+ }
139+ _ => edit. replace ( replace_node. text_range ( ) , then_block. syntax ( ) . text ( ) ) ,
125140 }
126141
127142 edit. insert ( match_pat. syntax ( ) . text_range ( ) . end ( ) , buf) ;
@@ -224,6 +239,33 @@ fn main() {
224239 ) ;
225240 }
226241
242+ #[ test]
243+ fn move_arm_cond_in_block_to_match_guard_works ( ) {
244+ check_assist (
245+ move_arm_cond_to_match_guard,
246+ r#"
247+ fn main() {
248+ match 92 {
249+ x => {
250+ <|>if x > 10 {
251+ false
252+ }
253+ },
254+ _ => true
255+ }
256+ }
257+ "# ,
258+ r#"
259+ fn main() {
260+ match 92 {
261+ x if x > 10 => false,
262+ _ => true
263+ }
264+ }
265+ "# ,
266+ ) ;
267+ }
268+
227269 #[ test]
228270 fn move_arm_cond_to_match_guard_if_let_not_works ( ) {
229271 check_assist_not_applicable (
@@ -290,4 +332,35 @@ fn main() {
290332"# ,
291333 ) ;
292334 }
335+
336+ #[ test]
337+ fn move_arm_cond_in_block_to_match_guard_if_multiline_body_works ( ) {
338+ check_assist (
339+ move_arm_cond_to_match_guard,
340+ r#"
341+ fn main() {
342+ match 92 {
343+ x => {
344+ if x > 10 {
345+ 92;<|>
346+ false
347+ }
348+ }
349+ _ => true
350+ }
351+ }
352+ "# ,
353+ r#"
354+ fn main() {
355+ match 92 {
356+ x if x > 10 => {
357+ 92;
358+ false
359+ }
360+ _ => true
361+ }
362+ }
363+ "# ,
364+ )
365+ }
293366}
0 commit comments