|
1 | 1 | use syntax::{
|
2 | 2 | AstNode,
|
3 |
| - ast::{self, make}, |
4 |
| - ted, |
| 3 | + algo::find_node_at_range, |
| 4 | + ast::{self, syntax_factory::SyntaxFactory}, |
| 5 | + syntax_editor::SyntaxEditor, |
5 | 6 | };
|
6 | 7 |
|
7 | 8 | use crate::{
|
@@ -66,33 +67,51 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) ->
|
66 | 67 | return None;
|
67 | 68 | }
|
68 | 69 | }
|
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)?; |
70 | 102 | acc.add(
|
71 | 103 | AssistId::refactor_extract("pull_assignment_up"),
|
72 | 104 | "Pull assignment up",
|
73 |
| - tgt.syntax().text_range(), |
| 105 | + target, |
74 | 106 | 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); |
96 | 115 | },
|
97 | 116 | )
|
98 | 117 | }
|
|
0 commit comments