Skip to content

Commit a071c5c

Browse files
authored
Merge pull request #21174 from Young-Flash/migrate_convert_iter_for_each_to_for
internal: migrate `convert_iter_for_each_to_for` to SyntaxEditor api
2 parents 3dfe74e + 03d0e79 commit a071c5c

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use ide_db::famous_defs::FamousDefs;
33
use stdx::format_to;
44
use syntax::{
55
AstNode,
6-
ast::{self, HasArgList, HasLoopBody, edit_in_place::Indent, make},
6+
ast::{self, HasArgList, HasLoopBody, edit_in_place::Indent, syntax_factory::SyntaxFactory},
77
};
88

99
use crate::{AssistContext, AssistId, Assists};
@@ -57,18 +57,22 @@ pub(crate) fn convert_iter_for_each_to_for(
5757
"Replace this `Iterator::for_each` with a for loop",
5858
range,
5959
|builder| {
60+
let make = SyntaxFactory::with_mappings();
6061
let indent =
6162
stmt.as_ref().map_or_else(|| method.indent_level(), ast::ExprStmt::indent_level);
6263

6364
let block = match body {
64-
ast::Expr::BlockExpr(block) => block,
65-
_ => make::block_expr(Vec::new(), Some(body)),
66-
}
67-
.clone_for_update();
65+
ast::Expr::BlockExpr(block) => block.clone_for_update(),
66+
_ => make.block_expr(Vec::new(), Some(body)),
67+
};
6868
block.reindent_to(indent);
6969

70-
let expr_for_loop = make::expr_for_loop(param, receiver, block);
71-
builder.replace(range, expr_for_loop.to_string())
70+
let expr_for_loop = make.expr_for_loop(param, receiver, block);
71+
72+
let target_node = stmt.as_ref().map_or(method.syntax(), AstNode::syntax);
73+
let mut editor = builder.make_editor(target_node);
74+
editor.replace(target_node, expr_for_loop.syntax());
75+
builder.add_file_edits(ctx.vfs_file_id(), editor);
7276
},
7377
)
7478
}

crates/syntax/src/ast/make.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ pub fn expr_if(
658658
};
659659
expr_from_text(&format!("if {condition} {then_branch} {else_branch}"))
660660
}
661-
pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::Expr {
661+
pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::ForExpr {
662662
expr_from_text(&format!("for {pat} in {expr} {block}"))
663663
}
664664

crates/syntax/src/ast/syntax_factory/constructors.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,26 @@ impl SyntaxFactory {
853853
ast
854854
}
855855

856+
pub fn expr_for_loop(
857+
&self,
858+
pat: ast::Pat,
859+
iterable: ast::Expr,
860+
body: ast::BlockExpr,
861+
) -> ast::ForExpr {
862+
let ast =
863+
make::expr_for_loop(pat.clone(), iterable.clone(), body.clone()).clone_for_update();
864+
865+
if let Some(mut mapping) = self.mappings() {
866+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
867+
builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone());
868+
builder.map_node(iterable.syntax().clone(), ast.iterable().unwrap().syntax().clone());
869+
builder.map_node(body.syntax().clone(), ast.loop_body().unwrap().syntax().clone());
870+
builder.finish(&mut mapping);
871+
}
872+
873+
ast
874+
}
875+
856876
pub fn expr_let(&self, pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr {
857877
let ast = make::expr_let(pattern.clone(), expr.clone()).clone_for_update();
858878

0 commit comments

Comments
 (0)