11use 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 } ;
63
74use crate :: { AssistContext , AssistId , Assists } ;
85
@@ -29,89 +26,62 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
2926 let parent = block. syntax ( ) . parent ( ) ?;
3027 let assist_id = AssistId ( "unwrap_block" ) ;
3128 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+ } ) ;
8858 }
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+ }
9371 }
72+ _ => return None ,
9473 } ;
9574
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' ] ) ,
10181 ) ;
10282 } )
10383}
10484
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-
11585fn update_expr_string ( expr_str : String , trim_start_pat : & [ char ] ) -> String {
11686 let expr_string = expr_str. trim_start_matches ( trim_start_pat) ;
11787 let mut expr_string_lines: Vec < & str > = expr_string. lines ( ) . collect ( ) ;
0 commit comments