@@ -2,6 +2,7 @@ use syntax::{
2
2
ast:: {
3
3
self ,
4
4
edit:: { AstNodeEdit , IndentLevel } ,
5
+ make,
5
6
} ,
6
7
AstNode , SyntaxKind , TextRange , T ,
7
8
} ;
@@ -37,61 +38,89 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
37
38
parent = parent. ancestors ( ) . find ( |it| ast:: MatchExpr :: can_cast ( it. kind ( ) ) ) ?
38
39
}
39
40
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| {
43
44
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 {
59
106
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 (
65
108
then_branch. syntax ( ) . text_range ( ) . end ( ) ,
66
- if_expr . syntax ( ) . text_range ( ) . end ( ) ,
109
+ l_curly_token . text_range ( ) . start ( ) ,
67
110
) ;
68
111
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 ( ) ) ) ;
75
114
} ) ;
76
115
}
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
- } ) ;
87
116
}
88
- }
89
- _ => return None ,
90
- } ;
117
+ _ => return None ,
118
+ } ;
91
119
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
+ }
95
124
}
96
125
97
126
fn update_expr_string ( expr_string : String ) -> String {
@@ -724,6 +753,19 @@ fn main() -> i32 {
724
753
check_assist (
725
754
unwrap_block,
726
755
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#"
727
769
fn main() {
728
770
let x = {$0
729
771
bar
@@ -734,6 +776,34 @@ fn main() {
734
776
fn main() {
735
777
let x = bar;
736
778
}
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
+ }
737
807
"# ,
738
808
) ;
739
809
}
0 commit comments