1
1
use ra_fmt:: unwrap_trivial_block;
2
- use ra_syntax:: {
3
- ast:: { self , ElseBranch , Expr , LoopBodyOwner } ,
4
- match_ast, AstNode , TextRange , T ,
5
- } ;
2
+ use ra_syntax:: { ast, AstNode , TextRange , T } ;
6
3
7
4
use crate :: { AssistContext , AssistId , Assists } ;
8
5
@@ -29,89 +26,62 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
29
26
let parent = block. syntax ( ) . parent ( ) ?;
30
27
let assist_id = AssistId ( "unwrap_block" ) ;
31
28
let assist_label = "Unwrap block" ;
32
-
33
- let ( expr, expr_to_unwrap) = match_ast ! {
34
- match parent {
35
- ast:: ForExpr ( for_expr) => {
36
- let block_expr = for_expr. loop_body( ) ?;
37
- let expr_to_unwrap = extract_expr( ctx. frange. range, block_expr) ?;
38
- ( ast:: Expr :: ForExpr ( for_expr) , expr_to_unwrap)
39
- } ,
40
- ast:: WhileExpr ( while_expr) => {
41
- let block_expr = while_expr. loop_body( ) ?;
42
- let expr_to_unwrap = extract_expr( ctx. frange. range, block_expr) ?;
43
- ( ast:: Expr :: WhileExpr ( while_expr) , expr_to_unwrap)
44
- } ,
45
- ast:: LoopExpr ( loop_expr) => {
46
- let block_expr = loop_expr. loop_body( ) ?;
47
- let expr_to_unwrap = extract_expr( ctx. frange. range, block_expr) ?;
48
- ( ast:: Expr :: LoopExpr ( loop_expr) , expr_to_unwrap)
49
- } ,
50
- ast:: IfExpr ( if_expr) => {
51
- let mut resp = None ;
52
-
53
- let then_branch = if_expr. then_branch( ) ?;
54
- if then_branch. l_curly_token( ) ?. text_range( ) . contains_range( ctx. frange. range) {
55
- if let Some ( ancestor) = if_expr. syntax( ) . parent( ) . and_then( ast:: IfExpr :: cast) {
56
- // For `else if` blocks
57
- let ancestor_then_branch = ancestor. then_branch( ) ?;
58
- let l_curly_token = then_branch. l_curly_token( ) ?;
59
-
60
- let target = then_branch. syntax( ) . text_range( ) ;
61
- return acc. add( assist_id, assist_label, target, |edit| {
62
- let range_to_del_else_if = TextRange :: new( ancestor_then_branch. syntax( ) . text_range( ) . end( ) , l_curly_token. text_range( ) . start( ) ) ;
63
- let range_to_del_rest = TextRange :: new( then_branch. syntax( ) . text_range( ) . end( ) , if_expr. syntax( ) . text_range( ) . end( ) ) ;
64
-
65
- edit. delete( range_to_del_rest) ;
66
- edit. delete( range_to_del_else_if) ;
67
- edit. replace( target, update_expr_string( then_branch. to_string( ) , & [ ' ' , '{' ] ) ) ;
68
- } ) ;
69
- } else {
70
- resp = Some ( ( ast:: Expr :: IfExpr ( if_expr. clone( ) ) , Expr :: BlockExpr ( then_branch) ) ) ;
71
- }
72
- } else if let Some ( else_branch) = if_expr. else_branch( ) {
73
- match else_branch {
74
- ElseBranch :: Block ( else_block) => {
75
- let l_curly_token = else_block. l_curly_token( ) ?;
76
- if l_curly_token. text_range( ) . contains_range( ctx. frange. range) {
77
- let target = else_block. syntax( ) . text_range( ) ;
78
- return acc. add( assist_id, assist_label, target, |edit| {
79
- let range_to_del = TextRange :: new( then_branch. syntax( ) . text_range( ) . end( ) , l_curly_token. text_range( ) . start( ) ) ;
80
-
81
- edit. delete( range_to_del) ;
82
- edit. replace( target, update_expr_string( else_block. to_string( ) , & [ ' ' , '{' ] ) ) ;
83
- } ) ;
84
- }
85
- } ,
86
- ElseBranch :: IfExpr ( _) => { } ,
87
- }
29
+ let parent = ast:: Expr :: cast ( parent) ?;
30
+
31
+ match parent. clone ( ) {
32
+ ast:: Expr :: ForExpr ( _) | ast:: Expr :: WhileExpr ( _) | ast:: Expr :: LoopExpr ( _) => ( ) ,
33
+ ast:: Expr :: IfExpr ( if_expr) => {
34
+ let then_branch = if_expr. then_branch ( ) ?;
35
+ if then_branch == block {
36
+ if let Some ( ancestor) = if_expr. syntax ( ) . parent ( ) . and_then ( ast:: IfExpr :: cast) {
37
+ // For `else if` blocks
38
+ let ancestor_then_branch = ancestor. then_branch ( ) ?;
39
+
40
+ let target = then_branch. syntax ( ) . text_range ( ) ;
41
+ return acc. add ( assist_id, assist_label, target, |edit| {
42
+ let range_to_del_else_if = TextRange :: new (
43
+ ancestor_then_branch. syntax ( ) . text_range ( ) . end ( ) ,
44
+ l_curly_token. text_range ( ) . start ( ) ,
45
+ ) ;
46
+ let range_to_del_rest = TextRange :: new (
47
+ then_branch. syntax ( ) . text_range ( ) . end ( ) ,
48
+ if_expr. syntax ( ) . text_range ( ) . end ( ) ,
49
+ ) ;
50
+
51
+ edit. delete ( range_to_del_rest) ;
52
+ edit. delete ( range_to_del_else_if) ;
53
+ edit. replace (
54
+ target,
55
+ update_expr_string ( then_branch. to_string ( ) , & [ ' ' , '{' ] ) ,
56
+ ) ;
57
+ } ) ;
88
58
}
89
-
90
- resp?
91
- } ,
92
- _ => return None ,
59
+ } else {
60
+ let target = block. syntax ( ) . text_range ( ) ;
61
+ return acc. add ( assist_id, assist_label, target, |edit| {
62
+ let range_to_del = TextRange :: new (
63
+ then_branch. syntax ( ) . text_range ( ) . end ( ) ,
64
+ l_curly_token. text_range ( ) . start ( ) ,
65
+ ) ;
66
+
67
+ edit. delete ( range_to_del) ;
68
+ edit. replace ( target, update_expr_string ( block. to_string ( ) , & [ ' ' , '{' ] ) ) ;
69
+ } ) ;
70
+ }
93
71
}
72
+ _ => return None ,
94
73
} ;
95
74
96
- let target = expr_to_unwrap. syntax ( ) . text_range ( ) ;
97
- acc. add ( assist_id, assist_label, target, |edit| {
98
- edit. replace (
99
- expr. syntax ( ) . text_range ( ) ,
100
- update_expr_string ( expr_to_unwrap. to_string ( ) , & [ ' ' , '{' , '\n' ] ) ,
75
+ let unwrapped = unwrap_trivial_block ( block) ;
76
+ let target = unwrapped. syntax ( ) . text_range ( ) ;
77
+ acc. add ( assist_id, assist_label, target, |builder| {
78
+ builder. replace (
79
+ parent. syntax ( ) . text_range ( ) ,
80
+ update_expr_string ( unwrapped. to_string ( ) , & [ ' ' , '{' , '\n' ] ) ,
101
81
) ;
102
82
} )
103
83
}
104
84
105
- fn extract_expr ( cursor_range : TextRange , block : ast:: BlockExpr ) -> Option < ast:: Expr > {
106
- let cursor_in_range = block. l_curly_token ( ) ?. text_range ( ) . contains_range ( cursor_range) ;
107
-
108
- if cursor_in_range {
109
- Some ( unwrap_trivial_block ( block) )
110
- } else {
111
- None
112
- }
113
- }
114
-
115
85
fn update_expr_string ( expr_str : String , trim_start_pat : & [ char ] ) -> String {
116
86
let expr_string = expr_str. trim_start_matches ( trim_start_pat) ;
117
87
let mut expr_string_lines: Vec < & str > = expr_string. lines ( ) . collect ( ) ;
0 commit comments