aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs79
1 files changed, 50 insertions, 29 deletions
diff --git a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
index 3220f2f46..2dc4fbcd4 100644
--- a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
+++ b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
@@ -1,6 +1,5 @@
1use ide_db::helpers::FamousDefs; 1use ide_db::helpers::FamousDefs;
2use stdx::format_to; 2use syntax::{AstNode, ast::{self, make, ArgListOwner, edit::AstNodeEdit}};
3use syntax::{AstNode, ast::{self, ArgListOwner}};
4 3
5use crate::{AssistContext, AssistId, AssistKind, Assists}; 4use crate::{AssistContext, AssistId, AssistKind, Assists};
6 5
@@ -47,7 +46,7 @@ pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContex
47 let (total_expr, parent) = validate_method_call_expr(&ctx.sema, total_expr)?; 46 let (total_expr, parent) = validate_method_call_expr(&ctx.sema, total_expr)?;
48 47
49 let param_list = closure.param_list()?; 48 let param_list = closure.param_list()?;
50 let param = param_list.params().next()?; 49 let param = param_list.params().next()?.pat()?;
51 let body = closure.body()?; 50 let body = closure.body()?;
52 51
53 acc.add( 52 acc.add(
@@ -55,16 +54,15 @@ pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContex
55 "Replace this `Iterator::for_each` with a for loop", 54 "Replace this `Iterator::for_each` with a for loop",
56 total_expr.syntax().text_range(), 55 total_expr.syntax().text_range(),
57 |builder| { 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 { 64 let expr_for_loop = make::expr_for_loop(param, parent, block);
63 ast::Expr::BlockExpr(body) => format_to!(buf, "{}", body), 65 builder.replace_ast(total_expr, expr_for_loop)
64 _ => format_to!(buf, "{{\n{}\n}}", body)
65 }
66
67 builder.replace(total_expr.syntax().text_range(), buf)
68 }, 66 },
69 ) 67 )
70} 68}
@@ -94,45 +92,68 @@ mod tests {
94 92
95 use super::*; 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 #[test] 104 #[test]
98 fn test_for_each_in_method() { 105 fn test_for_each_in_method() {
99 check_assist( 106 check_assist_with_fixtures(
100 convert_iter_for_each_to_for, 107 r#"
101 r"
102fn main() { 108fn main() {
103 let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)]; 109 let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
104 x.iter().$0for_each(|(x, y)| { 110 x.iter().$0for_each(|(x, y)| {
105 dbg!(x, y) 111 println!("x: {}, y: {}", x, y);
106 }); 112 });
107}", 113}"#,
108 r" 114 r#"
115fn 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#"
128fn 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#"
109fn main() { 133fn main() {
110 let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)]; 134 let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
111 for (x, y) in x.iter() { 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 #[test] 142 #[test]
119 fn test_for_each_in_closure() { 143 fn test_for_each_in_closure() {
120 check_assist( 144 check_assist_with_fixtures(
121 convert_iter_for_each_to_for, 145 r#"
122 r"
123fn main() { 146fn main() {
124 let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)]; 147 let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
125 x.iter().for_each($0|(x, y)| { 148 x.iter().for_each($0|(x, y)| println!("x: {}, y: {}", x, y));
126 dbg!(x, y) 149}"#,
127 }); 150 r#"
128}",
129 r"
130fn main() { 151fn main() {
131 let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)]; 152 let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
132 for (x, y) in x.iter() { 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} \ No newline at end of file 159} \ No newline at end of file