Skip to content

Commit c6ce2ab

Browse files
committed
Migrate pull_assignment_up assist to SyntaxEditor
Signed-off-by: Hayashi Mikihiro <[email protected]>
1 parent 9a1fc3c commit c6ce2ab

File tree

4 files changed

+59
-27
lines changed

4 files changed

+59
-27
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ fn generate_setter_from_info(info: &AssistInfo, record_field_info: &RecordFieldI
294294
let self_expr = make::ext::expr_self();
295295
let lhs = make::expr_field(self_expr, field_name);
296296
let rhs = make::expr_path(make::ext::ident_path(field_name));
297-
let assign_stmt = make::expr_stmt(make::expr_assignment(lhs, rhs));
297+
let assign_stmt = make::expr_stmt(make::expr_assignment(lhs, rhs).into());
298298
let body = make::block_expr([assign_stmt.into()], None);
299299

300300
// Make the setter fn

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

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use syntax::{
22
AstNode,
3-
ast::{self, make},
4-
ted,
3+
algo::find_node_at_range,
4+
ast::{self, syntax_factory::SyntaxFactory},
5+
syntax_editor::SyntaxEditor,
56
};
67

78
use crate::{
@@ -66,33 +67,51 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) ->
6667
return None;
6768
}
6869
}
69-
70+
let target = tgt.syntax().text_range();
71+
72+
let edit_tgt = tgt.syntax().clone_subtree();
73+
let assignments: Vec<_> = collector
74+
.assignments
75+
.into_iter()
76+
.filter_map(|(stmt, rhs)| {
77+
Some((
78+
find_node_at_range::<ast::BinExpr>(
79+
&edit_tgt,
80+
stmt.syntax().text_range() - target.start(),
81+
)?,
82+
find_node_at_range::<ast::Expr>(
83+
&edit_tgt,
84+
rhs.syntax().text_range() - target.start(),
85+
)?,
86+
))
87+
})
88+
.collect();
89+
90+
let mut editor = SyntaxEditor::new(edit_tgt);
91+
for (stmt, rhs) in assignments {
92+
let mut stmt = stmt.syntax().clone();
93+
if let Some(parent) = stmt.parent() {
94+
if ast::ExprStmt::cast(parent.clone()).is_some() {
95+
stmt = parent.clone();
96+
}
97+
}
98+
editor.replace(stmt, rhs.syntax());
99+
}
100+
let new_tgt_root = editor.finish().new_root().clone();
101+
let new_tgt = ast::Expr::cast(new_tgt_root)?;
70102
acc.add(
71103
AssistId::refactor_extract("pull_assignment_up"),
72104
"Pull assignment up",
73-
tgt.syntax().text_range(),
105+
target,
74106
move |edit| {
75-
let assignments: Vec<_> = collector
76-
.assignments
77-
.into_iter()
78-
.map(|(stmt, rhs)| (edit.make_mut(stmt), rhs.clone_for_update()))
79-
.collect();
80-
81-
let tgt = edit.make_mut(tgt);
82-
83-
for (stmt, rhs) in assignments {
84-
let mut stmt = stmt.syntax().clone();
85-
if let Some(parent) = stmt.parent() {
86-
if ast::ExprStmt::cast(parent.clone()).is_some() {
87-
stmt = parent.clone();
88-
}
89-
}
90-
ted::replace(stmt, rhs.syntax());
91-
}
92-
let assign_expr = make::expr_assignment(collector.common_lhs, tgt.clone());
93-
let assign_stmt = make::expr_stmt(assign_expr);
94-
95-
ted::replace(tgt.syntax(), assign_stmt.syntax().clone_for_update());
107+
let make = SyntaxFactory::with_mappings();
108+
let mut editor = edit.make_editor(tgt.syntax());
109+
let assign_expr = make.expr_assignment(collector.common_lhs, new_tgt.clone());
110+
let assign_stmt = make.expr_stmt(assign_expr.into());
111+
112+
editor.replace(tgt.syntax(), assign_stmt.syntax());
113+
editor.add_mappings(make.finish_with_mappings());
114+
edit.add_file_edits(ctx.vfs_file_id(), editor);
96115
},
97116
)
98117
}

crates/syntax/src/ast/make.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::TupleEx
680680
let expr = elements.into_iter().format(", ");
681681
expr_from_text(&format!("({expr})"))
682682
}
683-
pub fn expr_assignment(lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
683+
pub fn expr_assignment(lhs: ast::Expr, rhs: ast::Expr) -> ast::BinExpr {
684684
expr_from_text(&format!("{lhs} = {rhs}"))
685685
}
686686
fn expr_from_text<E: Into<ast::Expr> + AstNode>(text: &str) -> E {

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,19 @@ impl SyntaxFactory {
440440
ast
441441
}
442442

443+
pub fn expr_assignment(&self, lhs: ast::Expr, rhs: ast::Expr) -> ast::BinExpr {
444+
let ast = make::expr_assignment(lhs.clone(), rhs.clone()).clone_for_update();
445+
446+
if let Some(mut mapping) = self.mappings() {
447+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
448+
builder.map_node(lhs.syntax().clone(), ast.lhs().unwrap().syntax().clone());
449+
builder.map_node(rhs.syntax().clone(), ast.rhs().unwrap().syntax().clone());
450+
builder.finish(&mut mapping);
451+
}
452+
453+
ast
454+
}
455+
443456
pub fn expr_bin(&self, lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::BinExpr {
444457
let ast::Expr::BinExpr(ast) =
445458
make::expr_bin_op(lhs.clone(), op, rhs.clone()).clone_for_update()

0 commit comments

Comments
 (0)