@@ -39,26 +39,52 @@ use crate::{
39
39
pub ( crate ) fn extract_assigment ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
40
40
let name = ctx. find_node_at_offset :: < ast:: NameRef > ( ) ?. to_string ( ) ;
41
41
42
- let if_statement = ctx. find_node_at_offset :: < ast:: IfExpr > ( ) ?;
42
+ let ( old_stmt, new_stmt) = if let Some ( if_expr) = ctx. find_node_at_offset :: < ast:: IfExpr > ( ) {
43
+ (
44
+ ast:: Expr :: cast ( if_expr. syntax ( ) . to_owned ( ) ) ?,
45
+ exprify_if ( & if_expr, & name) ?. indent ( if_expr. indent_level ( ) ) ,
46
+ )
47
+ } else if let Some ( match_expr) = ctx. find_node_at_offset :: < ast:: MatchExpr > ( ) {
48
+ ( ast:: Expr :: cast ( match_expr. syntax ( ) . to_owned ( ) ) ?, exprify_match ( & match_expr, & name) ?)
49
+ } else {
50
+ return None ;
51
+ } ;
43
52
44
- let new_stmt =
45
- exprify_if ( & if_statement, & name. to_string ( ) ) ?. indent ( if_statement. indent_level ( ) ) ;
46
53
let expr_stmt = make:: expr_stmt ( new_stmt) ;
47
54
48
55
acc. add (
49
56
AssistId ( "extract_assignment" , AssistKind :: RefactorExtract ) ,
50
57
"Extract assignment" ,
51
- if_statement . syntax ( ) . text_range ( ) ,
58
+ old_stmt . syntax ( ) . text_range ( ) ,
52
59
move |edit| {
53
- edit. replace ( if_statement . syntax ( ) . text_range ( ) , format ! ( "{} = {};" , name, expr_stmt) ) ;
60
+ edit. replace ( old_stmt . syntax ( ) . text_range ( ) , format ! ( "{} = {};" , name, expr_stmt) ) ;
54
61
} ,
55
62
)
56
63
}
57
64
65
+ fn exprify_match ( match_expr : & ast:: MatchExpr , name : & str ) -> Option < ast:: Expr > {
66
+ let new_arm_list = match_expr
67
+ . match_arm_list ( ) ?
68
+ . arms ( )
69
+ . map ( |arm| {
70
+ if let ast:: Expr :: BlockExpr ( block) = arm. expr ( ) ? {
71
+ let new_block = exprify_block ( & block, name) ?. indent ( block. indent_level ( ) ) ;
72
+ Some ( arm. replace_descendant ( block, new_block) )
73
+ } else {
74
+ None
75
+ }
76
+ } )
77
+ . collect :: < Option < Vec < _ > > > ( ) ?;
78
+ let new_arm_list = match_expr
79
+ . match_arm_list ( ) ?
80
+ . replace_descendants ( match_expr. match_arm_list ( ) ?. arms ( ) . zip ( new_arm_list) ) ;
81
+ Some ( make:: expr_match ( match_expr. expr ( ) ?, new_arm_list) )
82
+ }
83
+
58
84
fn exprify_if ( statement : & ast:: IfExpr , name : & str ) -> Option < ast:: Expr > {
59
- let then_branch = exprify_block ( statement. then_branch ( ) ?, name) ?;
85
+ let then_branch = exprify_block ( & statement. then_branch ( ) ?, name) ?;
60
86
let else_branch = match statement. else_branch ( ) ? {
61
- ast:: ElseBranch :: Block ( block) => ast:: ElseBranch :: Block ( exprify_block ( block, name) ?) ,
87
+ ast:: ElseBranch :: Block ( ref block) => ast:: ElseBranch :: Block ( exprify_block ( block, name) ?) ,
62
88
ast:: ElseBranch :: IfExpr ( expr) => {
63
89
mark:: hit!( test_extract_assigment_chained_if) ;
64
90
ast:: ElseBranch :: IfExpr ( ast:: IfExpr :: cast (
@@ -69,7 +95,7 @@ fn exprify_if(statement: &ast::IfExpr, name: &str) -> Option<ast::Expr> {
69
95
Some ( make:: expr_if ( statement. condition ( ) ?, then_branch, Some ( else_branch) ) )
70
96
}
71
97
72
- fn exprify_block ( block : ast:: BlockExpr , name : & str ) -> Option < ast:: BlockExpr > {
98
+ fn exprify_block ( block : & ast:: BlockExpr , name : & str ) -> Option < ast:: BlockExpr > {
73
99
if block. expr ( ) . is_some ( ) {
74
100
return None ;
75
101
}
@@ -97,7 +123,7 @@ mod tests {
97
123
use crate :: tests:: { check_assist, check_assist_not_applicable} ;
98
124
99
125
#[ test]
100
- fn test_extract_assignment ( ) {
126
+ fn test_extract_assignment_if ( ) {
101
127
check_assist (
102
128
extract_assigment,
103
129
r#"
@@ -123,6 +149,45 @@ fn foo() {
123
149
) ;
124
150
}
125
151
152
+ #[ test]
153
+ fn test_extract_assignment_match ( ) {
154
+ check_assist (
155
+ extract_assigment,
156
+ r#"
157
+ fn foo() {
158
+ let mut a = 1;
159
+
160
+ match 1 {
161
+ 1 => {
162
+ <|>a = 2;
163
+ },
164
+ 2 => {
165
+ a = 3;
166
+ },
167
+ 3 => {
168
+ a = 4;
169
+ }
170
+ }
171
+ }"# ,
172
+ r#"
173
+ fn foo() {
174
+ let mut a = 1;
175
+
176
+ a = match 1 {
177
+ 1 => {
178
+ 2
179
+ },
180
+ 2 => {
181
+ 3
182
+ },
183
+ 3 => {
184
+ 4
185
+ }
186
+ };
187
+ }"# ,
188
+ ) ;
189
+ }
190
+
126
191
#[ test]
127
192
fn test_extract_assignment_not_last_not_applicable ( ) {
128
193
check_assist_not_applicable (
0 commit comments