Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/unmerge_match_arm.rs')
| -rw-r--r-- | crates/ide-assists/src/handlers/unmerge_match_arm.rs | 63 |
1 files changed, 25 insertions, 38 deletions
diff --git a/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/crates/ide-assists/src/handlers/unmerge_match_arm.rs index 5aedff5cc7..7b0f2dc65a 100644 --- a/crates/ide-assists/src/handlers/unmerge_match_arm.rs +++ b/crates/ide-assists/src/handlers/unmerge_match_arm.rs @@ -1,8 +1,7 @@ use syntax::{ Direction, SyntaxKind, T, - algo::neighbor, - ast::{self, AstNode, edit::IndentLevel, make}, - ted::{self, Position}, + ast::{self, AstNode, edit::IndentLevel, syntax_factory::SyntaxFactory}, + syntax_editor::{Element, Position}, }; use crate::{AssistContext, AssistId, Assists}; @@ -33,7 +32,7 @@ use crate::{AssistContext, AssistId, Assists}; // ``` pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let pipe_token = ctx.find_token_syntax_at_offset(T![|])?; - let or_pat = ast::OrPat::cast(pipe_token.parent()?)?.clone_for_update(); + let or_pat = ast::OrPat::cast(pipe_token.parent()?)?; if or_pat.leading_pipe().is_some_and(|it| it == pipe_token) { return None; } @@ -44,13 +43,14 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O // without `OrPat`. let new_parent = match_arm.syntax().parent()?; - let old_parent_range = new_parent.text_range(); acc.add( AssistId::refactor_rewrite("unmerge_match_arm"), "Unmerge match arm", pipe_token.text_range(), |edit| { + let make = SyntaxFactory::with_mappings(); + let mut editor = edit.make_editor(&new_parent); let pats_after = pipe_token .siblings_with_tokens(Direction::Next) .filter_map(|it| ast::Pat::cast(it.into_node()?)) @@ -59,11 +59,9 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O let new_pat = if pats_after.len() == 1 { pats_after[0].clone() } else { - make::or_pat(pats_after, or_pat.leading_pipe().is_some()).into() + make.or_pat(pats_after, or_pat.leading_pipe().is_some()).into() }; - let new_match_arm = - make::match_arm(new_pat, match_arm.guard(), match_arm_body).clone_for_update(); - + let new_match_arm = make.match_arm(new_pat, match_arm.guard(), match_arm_body); let mut pipe_index = pipe_token.index(); if pipe_token .prev_sibling_or_token() @@ -71,10 +69,13 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O { pipe_index -= 1; } - or_pat.syntax().splice_children( - pipe_index..or_pat.syntax().children_with_tokens().count(), - Vec::new(), - ); + for child in or_pat + .syntax() + .children_with_tokens() + .skip_while(|child| child.index() < pipe_index) + { + editor.delete(child.syntax_element()); + } let mut insert_after_old_arm = Vec::new(); @@ -86,33 +87,19 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O // body is a block, but we don't bother to check that. // - Missing after the arm with arms after, if the arm body is a block. In this case // we don't want to insert a comma at all. - let has_comma_after = - std::iter::successors(match_arm.syntax().last_child_or_token(), |it| { - it.prev_sibling_or_token() - }) - .map(|it| it.kind()) - .find(|it| !it.is_trivia()) - == Some(T![,]); - let has_arms_after = neighbor(&match_arm, Direction::Next).is_some(); - if !has_comma_after && !has_arms_after { - insert_after_old_arm.push(make::token(T![,]).into()); + let has_comma_after = match_arm.comma_token().is_some(); + if !has_comma_after && !match_arm.expr().unwrap().is_block_like() { + insert_after_old_arm.push(make.token(T![,]).into()); } let indent = IndentLevel::from_node(match_arm.syntax()); - insert_after_old_arm.push(make::tokens::whitespace(&format!("\n{indent}")).into()); + insert_after_old_arm.push(make.whitespace(&format!("\n{indent}")).into()); insert_after_old_arm.push(new_match_arm.syntax().clone().into()); - ted::insert_all_raw(Position::after(match_arm.syntax()), insert_after_old_arm); - - if has_comma_after { - ted::insert_raw( - Position::last_child_of(new_match_arm.syntax()), - make::token(T![,]), - ); - } - - edit.replace(old_parent_range, new_parent.to_string()); + editor.insert_all(Position::after(match_arm.syntax()), insert_after_old_arm); + editor.add_mappings(make.finish_with_mappings()); + edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) } @@ -258,7 +245,7 @@ fn main() { let x = X::A; let y = match x { X::A => 1i32, - X::B => 1i32 + X::B => 1i32, }; } "#, @@ -276,7 +263,7 @@ enum X { A, B } fn main() { let x = X::A; match x { - X::A $0| X::B => {}, + X::A $0| X::B => {} } } "#, @@ -287,8 +274,8 @@ enum X { A, B } fn main() { let x = X::A; match x { - X::A => {}, - X::B => {}, + X::A => {} + X::B => {} } } "#, |