Skip to content

Commit 1ce1f08

Browse files
authored
Merge pull request #19253 from ShoyuVanilla/migrate-convert-bool-then
internal: Migrate `convert_bool_then` to `SyntaxEditor`
2 parents 76567ee + 37822d5 commit 1ce1f08

File tree

4 files changed

+174
-60
lines changed

4 files changed

+174
-60
lines changed

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

+52-30
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ use ide_db::{
88
};
99
use itertools::Itertools;
1010
use syntax::{
11-
ast::{self, edit::AstNodeEdit, make, HasArgList},
12-
ted, AstNode, SyntaxNode,
11+
ast::{self, edit::AstNodeEdit, syntax_factory::SyntaxFactory, HasArgList},
12+
syntax_editor::SyntaxEditor,
13+
AstNode, SyntaxNode,
1314
};
1415

1516
use crate::{
16-
utils::{invert_boolean_expression_legacy, unwrap_trivial_block},
17+
utils::{invert_boolean_expression, unwrap_trivial_block},
1718
AssistContext, AssistId, AssistKind, Assists,
1819
};
1920

@@ -76,9 +77,9 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
7677
"Convert `if` expression to `bool::then` call",
7778
target,
7879
|builder| {
79-
let closure_body = closure_body.clone_for_update();
80+
let closure_body = closure_body.clone_subtree();
81+
let mut editor = SyntaxEditor::new(closure_body.syntax().clone());
8082
// Rewrite all `Some(e)` in tail position to `e`
81-
let mut replacements = Vec::new();
8283
for_each_tail_expr(&closure_body, &mut |e| {
8384
let e = match e {
8485
ast::Expr::BreakExpr(e) => e.expr(),
@@ -88,12 +89,16 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
8889
if let Some(ast::Expr::CallExpr(call)) = e {
8990
if let Some(arg_list) = call.arg_list() {
9091
if let Some(arg) = arg_list.args().next() {
91-
replacements.push((call.syntax().clone(), arg.syntax().clone()));
92+
editor.replace(call.syntax(), arg.syntax());
9293
}
9394
}
9495
}
9596
});
96-
replacements.into_iter().for_each(|(old, new)| ted::replace(old, new));
97+
let edit = editor.finish();
98+
let closure_body = ast::Expr::cast(edit.new_root().clone()).unwrap();
99+
100+
let mut editor = builder.make_editor(expr.syntax());
101+
let make = SyntaxFactory::new();
97102
let closure_body = match closure_body {
98103
ast::Expr::BlockExpr(block) => unwrap_trivial_block(block),
99104
e => e,
@@ -119,11 +124,18 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
119124
| ast::Expr::WhileExpr(_)
120125
| ast::Expr::YieldExpr(_)
121126
);
122-
let cond = if invert_cond { invert_boolean_expression_legacy(cond) } else { cond };
123-
let cond = if parenthesize { make::expr_paren(cond) } else { cond };
124-
let arg_list = make::arg_list(Some(make::expr_closure(None, closure_body)));
125-
let mcall = make::expr_method_call(cond, make::name_ref("then"), arg_list);
126-
builder.replace(target, mcall.to_string());
127+
let cond = if invert_cond {
128+
invert_boolean_expression(&make, cond)
129+
} else {
130+
cond.clone_for_update()
131+
};
132+
let cond = if parenthesize { make.expr_paren(cond).into() } else { cond };
133+
let arg_list = make.arg_list(Some(make.expr_closure(None, closure_body).into()));
134+
let mcall = make.expr_method_call(cond, make.name_ref("then"), arg_list);
135+
editor.replace(expr.syntax(), mcall.syntax());
136+
137+
editor.add_mappings(make.finish_with_mappings());
138+
builder.add_file_edits(ctx.file_id(), editor);
127139
},
128140
)
129141
}
@@ -173,45 +185,55 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_>
173185
"Convert `bool::then` call to `if`",
174186
target,
175187
|builder| {
176-
let closure_body = match closure_body {
188+
let mapless_make = SyntaxFactory::without_mappings();
189+
let closure_body = match closure_body.reset_indent() {
177190
ast::Expr::BlockExpr(block) => block,
178-
e => make::block_expr(None, Some(e)),
191+
e => mapless_make.block_expr(None, Some(e)),
179192
};
180193

181-
let closure_body = closure_body.clone_for_update();
194+
let closure_body = closure_body.clone_subtree();
195+
let mut editor = SyntaxEditor::new(closure_body.syntax().clone());
182196
// Wrap all tails in `Some(...)`
183-
let none_path = make::expr_path(make::ext::ident_path("None"));
184-
let some_path = make::expr_path(make::ext::ident_path("Some"));
185-
let mut replacements = Vec::new();
197+
let none_path = mapless_make.expr_path(mapless_make.ident_path("None"));
198+
let some_path = mapless_make.expr_path(mapless_make.ident_path("Some"));
186199
for_each_tail_expr(&ast::Expr::BlockExpr(closure_body.clone()), &mut |e| {
187200
let e = match e {
188201
ast::Expr::BreakExpr(e) => e.expr(),
189202
ast::Expr::ReturnExpr(e) => e.expr(),
190203
_ => Some(e.clone()),
191204
};
192205
if let Some(expr) = e {
193-
replacements.push((
206+
editor.replace(
194207
expr.syntax().clone(),
195-
make::expr_call(some_path.clone(), make::arg_list(Some(expr)))
208+
mapless_make
209+
.expr_call(some_path.clone(), mapless_make.arg_list(Some(expr)))
196210
.syntax()
197-
.clone_for_update(),
198-
));
211+
.clone(),
212+
);
199213
}
200214
});
201-
replacements.into_iter().for_each(|(old, new)| ted::replace(old, new));
215+
let edit = editor.finish();
216+
let closure_body = ast::BlockExpr::cast(edit.new_root().clone()).unwrap();
217+
218+
let mut editor = builder.make_editor(mcall.syntax());
219+
let make = SyntaxFactory::new();
202220

203221
let cond = match &receiver {
204222
ast::Expr::ParenExpr(expr) => expr.expr().unwrap_or(receiver),
205223
_ => receiver,
206224
};
207-
let if_expr = make::expr_if(
208-
cond,
209-
closure_body.reset_indent(),
210-
Some(ast::ElseBranch::Block(make::block_expr(None, Some(none_path)))),
211-
)
212-
.indent(mcall.indent_level());
225+
let if_expr = make
226+
.expr_if(
227+
cond,
228+
closure_body,
229+
Some(ast::ElseBranch::Block(make.block_expr(None, Some(none_path)))),
230+
)
231+
.indent(mcall.indent_level())
232+
.clone_for_update();
233+
editor.replace(mcall.syntax().clone(), if_expr.syntax().clone());
213234

214-
builder.replace(target, if_expr.to_string());
235+
editor.add_mappings(make.finish_with_mappings());
236+
builder.add_file_edits(ctx.file_id(), editor);
215237
},
216238
)
217239
}

0 commit comments

Comments
 (0)