1
1
use ide_db:: helpers:: FamousDefs ;
2
- use stdx:: format_to;
3
- use syntax:: { AstNode , ast:: { self , ArgListOwner } } ;
2
+ use syntax:: { AstNode , ast:: { self , make, ArgListOwner , edit:: AstNodeEdit } } ;
4
3
5
4
use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
6
5
@@ -47,24 +46,23 @@ pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContex
47
46
let ( total_expr, parent) = validate_method_call_expr ( & ctx. sema , total_expr) ?;
48
47
49
48
let param_list = closure. param_list ( ) ?;
50
- let param = param_list. params ( ) . next ( ) ?;
49
+ let param = param_list. params ( ) . next ( ) ?. pat ( ) ? ;
51
50
let body = closure. body ( ) ?;
52
51
53
52
acc. add (
54
53
AssistId ( "convert_iter_for_each_to_for" , AssistKind :: RefactorRewrite ) ,
55
54
"Replace this `Iterator::for_each` with a for loop" ,
56
55
total_expr. syntax ( ) . text_range ( ) ,
57
56
|builder| {
58
- let mut buf = String :: new ( ) ;
57
+ let original_indentation = total_expr . indent_level ( ) ;
59
58
60
- format_to ! ( buf, "for {} in {} " , param, parent) ;
59
+ let block = match body {
60
+ ast:: Expr :: BlockExpr ( block) => block,
61
+ _ => make:: block_expr ( Vec :: new ( ) , Some ( body) )
62
+ } . reset_indent ( ) . indent ( original_indentation) ;
61
63
62
- match body {
63
- ast:: Expr :: BlockExpr ( body) => format_to ! ( buf, "{}" , body) ,
64
- _ => format_to ! ( buf, "{{\n {}\n }}" , body)
65
- }
66
-
67
- builder. replace ( total_expr. syntax ( ) . text_range ( ) , buf)
64
+ let expr_for_loop = make:: expr_for_loop ( param, parent, block) ;
65
+ builder. replace_ast ( total_expr, expr_for_loop)
68
66
} ,
69
67
)
70
68
}
@@ -94,45 +92,68 @@ mod tests {
94
92
95
93
use super :: * ;
96
94
95
+ fn check_assist_with_fixtures ( before : & str , after : & str ) {
96
+ let before = & format ! (
97
+ "//- /main.rs crate:main deps:core,empty_iter{}{}" ,
98
+ before,
99
+ FamousDefs :: FIXTURE ,
100
+ ) ;
101
+ check_assist ( convert_iter_for_each_to_for, before, after) ;
102
+ }
103
+
97
104
#[ test]
98
105
fn test_for_each_in_method ( ) {
99
- check_assist (
100
- convert_iter_for_each_to_for,
101
- r"
106
+ check_assist_with_fixtures (
107
+ r#"
102
108
fn main() {
103
109
let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
104
110
x.iter().$0for_each(|(x, y)| {
105
- dbg!(x , y)
111
+ println!("x: {} , y: {}", x, y);
106
112
});
107
- }" ,
108
- r"
113
+ }"# ,
114
+ r#"
115
+ fn main() {
116
+ let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
117
+ for (x, y) in x.iter() {
118
+ println!("x: {}, y: {}", x, y);
119
+ };
120
+ }"# ,
121
+ )
122
+ }
123
+
124
+ #[ test]
125
+ fn test_for_each_without_braces ( ) {
126
+ check_assist_with_fixtures (
127
+ r#"
128
+ fn main() {
129
+ let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
130
+ x.iter().$0for_each(|(x, y)| println!("x: {}, y: {}", x, y));
131
+ }"# ,
132
+ r#"
109
133
fn main() {
110
134
let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
111
135
for (x, y) in x.iter() {
112
- dbg!( x, y)
136
+ println!("x: {}, y: {}", x, y)
113
137
};
114
- }" ,
138
+ }"# ,
115
139
)
116
140
}
117
141
118
142
#[ test]
119
143
fn test_for_each_in_closure ( ) {
120
- check_assist (
121
- convert_iter_for_each_to_for,
122
- r"
144
+ check_assist_with_fixtures (
145
+ r#"
123
146
fn main() {
124
147
let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
125
- x.iter().for_each($0|(x, y)| {
126
- dbg!(x, y)
127
- });
128
- }" ,
129
- r"
148
+ x.iter().for_each($0|(x, y)| println!("x: {}, y: {}", x, y));
149
+ }"# ,
150
+ r#"
130
151
fn main() {
131
152
let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
132
153
for (x, y) in x.iter() {
133
- dbg!( x, y)
154
+ println!("x: {}, y: {}", x, y)
134
155
};
135
- }" ,
156
+ }"# ,
136
157
)
137
158
}
138
159
}
0 commit comments