@@ -2,6 +2,7 @@ use syntax::{
22 ast:: {
33 self ,
44 edit:: { AstNodeEdit , IndentLevel } ,
5+ make,
56 } ,
67 AstNode , SyntaxKind , TextRange , T ,
78} ;
@@ -37,61 +38,89 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
3738 parent = parent. ancestors ( ) . find ( |it| ast:: MatchExpr :: can_cast ( it. kind ( ) ) ) ?
3839 }
3940
40- if matches ! ( parent. kind( ) , SyntaxKind :: STMT_LIST | SyntaxKind :: EXPR_STMT | SyntaxKind :: LET_STMT )
41- {
42- return acc. add ( assist_id, assist_label, target, |builder| {
41+ let kind = parent. kind ( ) ;
42+ if matches ! ( kind , SyntaxKind :: STMT_LIST | SyntaxKind :: EXPR_STMT ) {
43+ acc. add ( assist_id, assist_label, target, |builder| {
4344 builder. replace ( block. syntax ( ) . text_range ( ) , update_expr_string ( block. to_string ( ) ) ) ;
44- } ) ;
45- }
46-
47- let parent = ast:: Expr :: cast ( parent) ?;
48-
49- match parent. clone ( ) {
50- ast:: Expr :: ForExpr ( _) | ast:: Expr :: WhileExpr ( _) | ast:: Expr :: LoopExpr ( _) => ( ) ,
51- ast:: Expr :: MatchExpr ( _) => block = block. dedent ( IndentLevel ( 1 ) ) ,
52- ast:: Expr :: IfExpr ( if_expr) => {
53- let then_branch = if_expr. then_branch ( ) ?;
54- if then_branch == block {
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-
45+ } )
46+ } else if matches ! ( kind, SyntaxKind :: LET_STMT ) {
47+ let parent = ast:: LetStmt :: cast ( parent) ?;
48+ let pattern = ast:: Pat :: cast ( parent. syntax ( ) . first_child ( ) ?) ?;
49+ let ty = parent. ty ( ) ;
50+ let list = block. stmt_list ( ) ?;
51+ let replaced = match list. syntax ( ) . last_child ( ) {
52+ Some ( last) => {
53+ let stmts: Vec < ast:: Stmt > = list. statements ( ) . collect ( ) ;
54+ let initializer = ast:: Expr :: cast ( last. clone ( ) ) ?;
55+ let let_stmt = make:: let_stmt ( pattern, ty, Some ( initializer) ) ;
56+ if stmts. len ( ) > 0 {
57+ let block = make:: block_expr ( stmts, None ) ;
58+ format ! (
59+ "{}\n {}" ,
60+ update_expr_string( block. to_string( ) ) ,
61+ let_stmt. to_string( )
62+ )
63+ } else {
64+ let_stmt. to_string ( )
65+ }
66+ }
67+ None => {
68+ let empty_tuple = make:: expr_tuple ( [ ] ) ;
69+ make:: let_stmt ( pattern, ty, Some ( empty_tuple) ) . to_string ( )
70+ }
71+ } ;
72+ acc. add ( assist_id, assist_label, target, |builder| {
73+ builder. replace ( parent. syntax ( ) . text_range ( ) , replaced) ;
74+ } )
75+ } else {
76+ let parent = ast:: Expr :: cast ( parent) ?;
77+ match parent. clone ( ) {
78+ ast:: Expr :: ForExpr ( _) | ast:: Expr :: WhileExpr ( _) | ast:: Expr :: LoopExpr ( _) => ( ) ,
79+ ast:: Expr :: MatchExpr ( _) => block = block. dedent ( IndentLevel ( 1 ) ) ,
80+ ast:: Expr :: IfExpr ( if_expr) => {
81+ let then_branch = if_expr. then_branch ( ) ?;
82+ if then_branch == block {
83+ if let Some ( ancestor) = if_expr. syntax ( ) . parent ( ) . and_then ( ast:: IfExpr :: cast) {
84+ // For `else if` blocks
85+ let ancestor_then_branch = ancestor. then_branch ( ) ?;
86+
87+ return acc. add ( assist_id, assist_label, target, |edit| {
88+ let range_to_del_else_if = TextRange :: new (
89+ ancestor_then_branch. syntax ( ) . text_range ( ) . end ( ) ,
90+ l_curly_token. text_range ( ) . start ( ) ,
91+ ) ;
92+ let range_to_del_rest = TextRange :: new (
93+ then_branch. syntax ( ) . text_range ( ) . end ( ) ,
94+ if_expr. syntax ( ) . text_range ( ) . end ( ) ,
95+ ) ;
96+
97+ edit. delete ( range_to_del_rest) ;
98+ edit. delete ( range_to_del_else_if) ;
99+ edit. replace (
100+ target,
101+ update_expr_string_without_newline ( then_branch. to_string ( ) ) ,
102+ ) ;
103+ } ) ;
104+ }
105+ } else {
59106 return acc. add ( assist_id, assist_label, target, |edit| {
60- let range_to_del_else_if = TextRange :: new (
61- ancestor_then_branch. syntax ( ) . text_range ( ) . end ( ) ,
62- l_curly_token. text_range ( ) . start ( ) ,
63- ) ;
64- let range_to_del_rest = TextRange :: new (
107+ let range_to_del = TextRange :: new (
65108 then_branch. syntax ( ) . text_range ( ) . end ( ) ,
66- if_expr . syntax ( ) . text_range ( ) . end ( ) ,
109+ l_curly_token . text_range ( ) . start ( ) ,
67110 ) ;
68111
69- edit. delete ( range_to_del_rest) ;
70- edit. delete ( range_to_del_else_if) ;
71- edit. replace (
72- target,
73- update_expr_string_without_newline ( then_branch. to_string ( ) ) ,
74- ) ;
112+ edit. delete ( range_to_del) ;
113+ edit. replace ( target, update_expr_string_without_newline ( block. to_string ( ) ) ) ;
75114 } ) ;
76115 }
77- } else {
78- return acc. add ( assist_id, assist_label, target, |edit| {
79- let range_to_del = TextRange :: new (
80- then_branch. syntax ( ) . text_range ( ) . end ( ) ,
81- l_curly_token. text_range ( ) . start ( ) ,
82- ) ;
83-
84- edit. delete ( range_to_del) ;
85- edit. replace ( target, update_expr_string_without_newline ( block. to_string ( ) ) ) ;
86- } ) ;
87116 }
88- }
89- _ => return None ,
90- } ;
117+ _ => return None ,
118+ } ;
91119
92- acc. add ( assist_id, assist_label, target, |builder| {
93- builder. replace ( parent. syntax ( ) . text_range ( ) , update_expr_string ( block. to_string ( ) ) ) ;
94- } )
120+ acc. add ( assist_id, assist_label, target, |builder| {
121+ builder. replace ( parent. syntax ( ) . text_range ( ) , update_expr_string ( block. to_string ( ) ) ) ;
122+ } )
123+ }
95124}
96125
97126fn update_expr_string ( expr_string : String ) -> String {
@@ -724,6 +753,19 @@ fn main() -> i32 {
724753 check_assist (
725754 unwrap_block,
726755 r#"
756+ fn main() {
757+ let x = {$0};
758+ }
759+ "# ,
760+ r#"
761+ fn main() {
762+ let x = ();
763+ }
764+ "# ,
765+ ) ;
766+ check_assist (
767+ unwrap_block,
768+ r#"
727769fn main() {
728770 let x = {$0
729771 bar
@@ -734,6 +776,34 @@ fn main() {
734776fn main() {
735777 let x = bar;
736778}
779+ "# ,
780+ ) ;
781+ check_assist (
782+ unwrap_block,
783+ r#"
784+ fn main() -> i32 {
785+ let _ = {$01; 2};
786+ }
787+ "# ,
788+ r#"
789+ fn main() -> i32 {
790+ 1;
791+ let _ = 2;
792+ }
793+ "# ,
794+ ) ;
795+ check_assist (
796+ unwrap_block,
797+ r#"
798+ fn main() -> i32 {
799+ let mut a = {$01; 2};
800+ }
801+ "# ,
802+ r#"
803+ fn main() -> i32 {
804+ 1;
805+ let mut a = 2;
806+ }
737807"# ,
738808 ) ;
739809 }
0 commit comments