@@ -2,7 +2,7 @@ use hir::db::HirDatabase;
2
2
use ra_syntax:: {
3
3
TextUnit ,
4
4
SyntaxElement ,
5
- ast:: { MatchArm , AstNode , AstToken } ,
5
+ ast:: { MatchArm , AstNode , AstToken , IfExpr } ,
6
6
ast,
7
7
} ;
8
8
@@ -39,6 +39,37 @@ pub(crate) fn move_guard_to_arm_body(mut ctx: AssistCtx<impl HirDatabase>) -> Op
39
39
ctx. build ( )
40
40
}
41
41
42
+ pub ( crate ) fn move_arm_cond_to_match_guard ( mut ctx : AssistCtx < impl HirDatabase > ) -> Option < Assist > {
43
+ let match_arm: & MatchArm = ctx. node_at_offset :: < MatchArm > ( ) ?;
44
+ let last_match_pat = match_arm. pats ( ) . last ( ) ?;
45
+
46
+ let arm_body = match_arm. expr ( ) ?;
47
+ let if_expr: & IfExpr = IfExpr :: cast ( arm_body. syntax ( ) ) ?;
48
+ let cond = if_expr. condition ( ) ?;
49
+ let then_block = if_expr. then_branch ( ) ?;
50
+
51
+ // Not support if with else branch
52
+ if let Some ( _) = if_expr. else_branch ( ) {
53
+ return None ;
54
+ }
55
+
56
+ let buf = format ! ( " if {}" , cond. syntax( ) . text( ) ) ;
57
+
58
+ ctx. add_action ( AssistId ( "move_arm_cond_to_match_guard" ) , "move condition to match guard" , |edit| {
59
+ edit. target ( last_match_pat. syntax ( ) . range ( ) ) ;
60
+
61
+ if then_block. statements ( ) . next ( ) . is_none ( ) && then_block. expr ( ) . is_some ( ) {
62
+ edit. replace ( if_expr. syntax ( ) . range ( ) , then_block. expr ( ) . unwrap ( ) . syntax ( ) . text ( ) ) ;
63
+ } else {
64
+ edit. replace ( if_expr. syntax ( ) . range ( ) , then_block. syntax ( ) . text ( ) ) ;
65
+ }
66
+
67
+ edit. insert ( last_match_pat. syntax ( ) . range ( ) . end ( ) , buf) ;
68
+ edit. set_cursor ( last_match_pat. syntax ( ) . range ( ) . end ( ) + TextUnit :: from ( 1 ) ) ;
69
+ } ) ;
70
+ ctx. build ( )
71
+ }
72
+
42
73
#[ cfg( test) ]
43
74
mod tests {
44
75
use super :: * ;
@@ -112,4 +143,118 @@ mod tests {
112
143
"# ,
113
144
) ;
114
145
}
146
+
147
+ #[ test]
148
+ fn move_arm_cond_to_match_guard_works ( ) {
149
+ check_assist (
150
+ move_arm_cond_to_match_guard,
151
+ r#"
152
+ fn f() {
153
+ let t = 'a';
154
+ let chars = "abcd";
155
+ match t {
156
+ '\r' => if chars.clone().next() == Some('\n') { <|>false },
157
+ _ => true
158
+ }
159
+ }
160
+ "# ,
161
+ r#"
162
+ fn f() {
163
+ let t = 'a';
164
+ let chars = "abcd";
165
+ match t {
166
+ '\r' <|>if chars.clone().next() == Some('\n') => false,
167
+ _ => true
168
+ }
169
+ }
170
+ "# ,
171
+ ) ;
172
+ }
173
+
174
+ #[ test]
175
+ fn move_arm_cond_to_match_guard_if_let_works ( ) {
176
+ check_assist (
177
+ move_arm_cond_to_match_guard,
178
+ r#"
179
+ fn f() {
180
+ let t = 'a';
181
+ let chars = "abcd";
182
+ match t {
183
+ '\r' => if let Some(_) = chars.clone().next() { <|>false },
184
+ _ => true
185
+ }
186
+ }
187
+ "# ,
188
+ r#"
189
+ fn f() {
190
+ let t = 'a';
191
+ let chars = "abcd";
192
+ match t {
193
+ '\r' <|>if let Some(_) = chars.clone().next() => false,
194
+ _ => true
195
+ }
196
+ }
197
+ "# ,
198
+ ) ;
199
+ }
200
+
201
+ #[ test]
202
+ fn move_arm_cond_to_match_guard_if_empty_body_works ( ) {
203
+ check_assist (
204
+ move_arm_cond_to_match_guard,
205
+ r#"
206
+ fn f() {
207
+ let t = 'a';
208
+ let chars = "abcd";
209
+ match t {
210
+ '\r' => if let Some(_) = chars.clone().next() { <|> },
211
+ _ => true
212
+ }
213
+ }
214
+ "# ,
215
+ r#"
216
+ fn f() {
217
+ let t = 'a';
218
+ let chars = "abcd";
219
+ match t {
220
+ '\r' <|>if let Some(_) = chars.clone().next() => { },
221
+ _ => true
222
+ }
223
+ }
224
+ "# ,
225
+ ) ;
226
+ }
227
+
228
+ #[ test]
229
+ fn move_arm_cond_to_match_guard_if_multiline_body_works ( ) {
230
+ check_assist (
231
+ move_arm_cond_to_match_guard,
232
+ r#"
233
+ fn f() {
234
+ let mut t = 'a';
235
+ let chars = "abcd";
236
+ match t {
237
+ '\r' => if let Some(_) = chars.clone().next() {
238
+ t = 'e';<|>
239
+ false
240
+ },
241
+ _ => true
242
+ }
243
+ }
244
+ "# ,
245
+ r#"
246
+ fn f() {
247
+ let mut t = 'a';
248
+ let chars = "abcd";
249
+ match t {
250
+ '\r' <|>if let Some(_) = chars.clone().next() => {
251
+ t = 'e';
252
+ false
253
+ },
254
+ _ => true
255
+ }
256
+ }
257
+ "# ,
258
+ ) ;
259
+ }
115
260
}
0 commit comments