diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs index bfd7dffb058a..8f513a2bcf66 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs @@ -22,7 +22,7 @@ use syntax::{ ast::{ self, AstNode, FieldList, HasAttrs, HasGenericArgs, HasGenericParams, HasModuleItem, - HasName, HasTypeBounds, make, syntax_factory::SyntaxFactory, + HasName, HasTypeBounds, make, }, syntax_editor::{GetOrCreateWhereClause, SyntaxEditor}, ted, @@ -1294,10 +1294,8 @@ fn coerce_pointee_expand( )); } - let (mut editor, strukt) = SyntaxEditor::with_ast_node(strukt); - let make = SyntaxFactory::with_mappings(); - strukt.get_or_create_where_clause(&mut editor, &make, new_predicates.into_iter()); - editor.add_mappings(make.finish_with_mappings()); + let (editor, strukt) = SyntaxEditor::with_ast_node(strukt); + strukt.get_or_create_where_clause(&editor, new_predicates.into_iter()); let edit = editor.finish(); let strukt = ast::Struct::cast(edit.new_root().clone()).unwrap(); let adt = ast::Adt::Struct(strukt.clone()); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs index da1322de4b64..c5ec88ffb88a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs @@ -1,7 +1,7 @@ use either::Either; use syntax::{ AstNode, T, - ast::{self, edit::AstNodeEdit, syntax_factory::SyntaxFactory}, + ast::{self, edit::AstNodeEdit}, match_ast, }; @@ -56,15 +56,13 @@ pub(crate) fn add_braces(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( }, expr.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(expr.syntax()); + let editor = builder.make_editor(expr.syntax()); + let make = editor.make(); let new_expr = expr.reset_indent().indent(1.into()); let block_expr = make.block_expr(None, Some(new_expr)); editor.replace(expr.syntax(), block_expr.indent(expr.indent_level()).syntax()); - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_dot_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_dot_deref.rs index d27a6b4ce770..1809b8f305b6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_dot_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_dot_deref.rs @@ -53,18 +53,18 @@ pub(crate) fn add_explicit_method_call_deref( "Insert explicit method call derefs", dot_token.text_range(), |builder| { - let mut edit = builder.make_editor(method_call_expr.syntax()); - let make = SyntaxFactory::without_mappings(); + let editor = builder.make_editor(method_call_expr.syntax()); + let make = editor.make(); let mut expr = receiver.clone(); for adjust_kind in adjustments { - expr = adjust_kind.wrap_expr(expr, &make); + expr = adjust_kind.wrap_expr(expr, make); } expr = make.expr_paren(expr).into(); - edit.replace(receiver.syntax(), expr.syntax()); + editor.replace(receiver.syntax(), expr.syntax()); - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs index 6a408e5254fd..41e9b6cc8453 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs @@ -3,7 +3,7 @@ }; use syntax::{ SyntaxToken, T, - ast::{self, AstNode, HasLoopBody, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, HasLoopBody}, syntax_editor::{Position, SyntaxEditor}, }; @@ -42,8 +42,8 @@ pub(crate) fn add_label_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) -> O "Add Label", loop_expr.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(loop_expr.syntax()); + let editor = builder.make_editor(loop_expr.syntax()); + let make = editor.make(); let label = make.lifetime("'l"); let elements = vec![ @@ -65,11 +65,10 @@ pub(crate) fn add_label_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) -> O _ => return, }; if let Some(token) = token { - insert_label_after_token(&mut editor, &make, &token, ctx, builder); + insert_label_after_token(&editor, &token, ctx, builder); } }); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); builder.rename(); }, @@ -85,12 +84,12 @@ fn loop_token(loop_expr: &ast::AnyHasLoopBody) -> Option { } fn insert_label_after_token( - editor: &mut SyntaxEditor, - make: &SyntaxFactory, + editor: &SyntaxEditor, token: &SyntaxToken, ctx: &AssistContext<'_>, builder: &mut SourceChangeBuilder, ) { + let make = editor.make(); let label = make.lifetime("'l"); let elements = vec![make.whitespace(" ").into(), label.syntax().clone().into()]; editor.insert_all(Position::after(token), elements); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs index 44b367059eca..d1f1f9f12338 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -148,9 +148,10 @@ fn add_missing_impl_members_inner( let target = impl_def.syntax().text_range(); acc.add(AssistId::quick_fix(assist_id), label, target, |edit| { - let make = SyntaxFactory::with_mappings(); + let editor = edit.make_editor(impl_def.syntax()); + let make = editor.make(); let new_item = add_trait_assoc_items_to_impl( - &make, + make, &ctx.sema, ctx.config, &missing_items, @@ -166,7 +167,7 @@ fn add_missing_impl_members_inner( let mut first_new_item = if let DefaultMethods::No = mode && let ast::AssocItem::Fn(func) = &first_new_item && let Some(body) = try_gen_trait_body( - &make, + make, ctx, func, trait_ref, @@ -175,7 +176,7 @@ fn add_missing_impl_members_inner( ) && let Some(func_body) = func.body() { - let (mut func_editor, _) = SyntaxEditor::new(first_new_item.syntax().clone()); + let (func_editor, _) = SyntaxEditor::new(first_new_item.syntax().clone()); func_editor.replace(func_body.syntax(), body.syntax()); ast::AssocItem::cast(func_editor.finish().new_root().clone()) } else { @@ -188,9 +189,8 @@ fn add_missing_impl_members_inner( .chain(other_items.iter().cloned()) .collect::>(); - let mut editor = edit.make_editor(impl_def.syntax()); if let Some(assoc_item_list) = impl_def.assoc_item_list() { - assoc_item_list.add_items(&mut editor, new_assoc_items); + assoc_item_list.add_items(&editor, new_assoc_items); } else { let assoc_item_list = make.assoc_item_list(new_assoc_items); editor.insert_all( @@ -218,7 +218,6 @@ fn add_missing_impl_members_inner( editor.add_annotation(first_new_item.syntax(), tabstop); }; }; - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index b7510bb82676..9f267daa10ca 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -74,7 +74,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .filter(|pat| !matches!(pat, Pat::WildcardPat(_))) .collect(); - let make = SyntaxFactory::with_mappings(); + let make = SyntaxFactory::without_mappings(); let scope = ctx.sema.scope(expr.syntax())?; let module = scope.module(); @@ -271,12 +271,12 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) } }; - let mut editor = builder.make_editor(&old_place); + let editor = builder.make_editor(&old_place); let mut arms_edit = ArmsEdit { match_arm_list, place: old_place, last_arm: None }; - arms_edit.remove_wildcard_arms(ctx, &mut editor); - arms_edit.add_comma_after_last_arm(ctx, &make, &mut editor); - arms_edit.append_arms(&missing_arms, &make, &mut editor); + arms_edit.remove_wildcard_arms(ctx, &editor); + arms_edit.add_comma_after_last_arm(ctx, &make, &editor); + arms_edit.append_arms(&missing_arms, &make, &editor); if let Some(cap) = ctx.config.snippet_cap { if let Some(it) = missing_arms @@ -297,7 +297,6 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) } } - editor.add_mappings(make.take()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -358,7 +357,7 @@ struct ArmsEdit { } impl ArmsEdit { - fn remove_wildcard_arms(&mut self, ctx: &AssistContext<'_>, editor: &mut SyntaxEditor) { + fn remove_wildcard_arms(&mut self, ctx: &AssistContext<'_>, editor: &SyntaxEditor) { for arm in self.match_arm_list.arms() { if !matches!(arm.pat(), Some(Pat::WildcardPat(_))) { self.last_arm = Some(arm); @@ -387,7 +386,7 @@ fn remove_wildcard_arms(&mut self, ctx: &AssistContext<'_>, editor: &mut SyntaxE } } - fn append_arms(&self, arms: &[ast::MatchArm], make: &SyntaxFactory, editor: &mut SyntaxEditor) { + fn append_arms(&self, arms: &[ast::MatchArm], make: &SyntaxFactory, editor: &SyntaxEditor) { let Some(mut before) = self.place.last_token() else { stdx::never!("match arm list not contain any token"); return; @@ -420,7 +419,7 @@ fn add_comma_after_last_arm( &self, ctx: &AssistContext<'_>, make: &SyntaxFactory, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, ) { if let Some(last_arm) = &self.last_arm && last_arm.comma_token().is_none() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs index c5e722d87e1a..490a91d59493 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs @@ -93,8 +93,8 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti "Add `: _` before assignment operator", ident.text_range(), |builder| { - let mut editor = builder.make_editor(let_stmt.syntax()); - let make = SyntaxFactory::without_mappings(); + let editor = builder.make_editor(let_stmt.syntax()); + let make = editor.make(); if let_stmt.semicolon_token().is_none() { editor.insert( @@ -103,6 +103,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti ); } + let make = editor.make(); let placeholder_ty = make.ty_placeholder(); if let Some(pat) = let_stmt.pat() { @@ -141,14 +142,12 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti ident.text_range(), |builder| { builder.trigger_parameter_hints(); - - let make = SyntaxFactory::with_mappings(); - let mut editor = match &turbofish_target { + let editor = match &turbofish_target { Either::Left(it) => builder.make_editor(it.syntax()), Either::Right(it) => builder.make_editor(it.syntax()), }; - let fish_head = get_fish_head(&make, number_of_arguments); + let fish_head = get_fish_head(editor.make(), number_of_arguments); match turbofish_target { Either::Left(path_segment) => { @@ -180,8 +179,6 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti editor.add_annotation(arg.syntax(), builder.make_placeholder_snippet(cap)); } } - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs index 2ea0d76b0161..b87a757047ac 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -80,9 +80,8 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti _ => return None, }; - let make = SyntaxFactory::with_mappings(); - - let (mut editor, demorganed) = SyntaxEditor::with_ast_node(&bin_expr); + let (editor, demorganed) = SyntaxEditor::with_ast_node(&bin_expr); + let make = editor.make(); editor.replace(demorganed.op_token()?, make.token(inv_token)); let mut exprs = VecDeque::from([ @@ -98,7 +97,7 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?, prec)); exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?, prec)); } else { - let mut inv = invert_boolean_expression(&make, expr); + let mut inv = invert_boolean_expression(make, expr); if precedence(&inv).needs_parentheses_in(prec) { inv = make.expr_paren(inv).into(); } @@ -108,7 +107,7 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti return None; } } else { - let mut inv = invert_boolean_expression(&make, demorganed.clone()); + let mut inv = invert_boolean_expression(make, demorganed.clone()); if precedence(&inv).needs_parentheses_in(prec) { inv = make.expr_paren(inv).into(); } @@ -116,7 +115,6 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti } } - editor.add_mappings(make.finish_with_mappings()); let edit = editor.finish(); let demorganed = ast::Expr::cast(edit.new_root().clone())?; @@ -126,7 +124,9 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti "Apply De Morgan's law", op_range, |builder| { - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(bin_expr.syntax()); + let make = editor.make(); + let (target_node, result_expr) = if let Some(neg_expr) = bin_expr .syntax() .parent() @@ -141,9 +141,9 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti bin_expr.syntax().parent().and_then(ast::ParenExpr::cast) { cov_mark::hit!(demorgan_double_parens); - (paren_expr.syntax().clone(), add_bang_paren(&make, demorganed)) + (paren_expr.syntax().clone(), add_bang_paren(make, demorganed)) } else { - (bin_expr.syntax().clone(), add_bang_paren(&make, demorganed)) + (bin_expr.syntax().clone(), add_bang_paren(make, demorganed)) }; let final_expr = if target_node @@ -156,9 +156,7 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti result_expr }; - let mut editor = builder.make_editor(&target_node); editor.replace(&target_node, final_expr.syntax()); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -206,8 +204,8 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> label, op_range, |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(method_call.syntax()); + let editor = builder.make_editor(method_call.syntax()); + let make = editor.make(); // replace the method name let new_name = match name.text().as_str() { "all" => make.name_ref("any"), @@ -217,7 +215,7 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> editor.replace(name.syntax(), new_name.syntax()); // negate all tail expressions in the closure body - let tail_cb = &mut |e: &_| tail_cb_impl(&mut editor, &make, e); + let tail_cb = &mut |e: &_| tail_cb_impl(&editor, e); walk_expr(&closure_body, &mut |expr| { if let ast::Expr::ReturnExpr(ret_expr) = expr && let Some(ret_expr_arg) = &ret_expr.expr() @@ -240,8 +238,6 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> } else { editor.insert(Position::before(method_call.syntax()), make.token(SyntaxKind::BANG)); } - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -269,18 +265,18 @@ fn validate_method_call_expr( it_type.impls_trait(sema.db, iter_trait, &[]).then_some((name_ref, arg_expr)) } -fn tail_cb_impl(editor: &mut SyntaxEditor, make: &SyntaxFactory, e: &ast::Expr) { +fn tail_cb_impl(editor: &SyntaxEditor, e: &ast::Expr) { match e { ast::Expr::BreakExpr(break_expr) => { if let Some(break_expr_arg) = break_expr.expr() { - for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(editor, make, e)) + for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(editor, e)) } } ast::Expr::ReturnExpr(_) => { // all return expressions have already been handled by the walk loop } e => { - let inverted_body = invert_boolean_expression(make, e.clone()); + let inverted_body = invert_boolean_expression(editor.make(), e.clone()); editor.replace(e.syntax(), inverted_body.syntax()); } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index c36c79ee998b..cb2e7d6d100b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -77,7 +77,7 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> "Convert `if` expression to `bool::then` call", target, |builder| { - let (mut editor, closure_body) = SyntaxEditor::with_ast_node(&closure_body); + let (editor, closure_body) = SyntaxEditor::with_ast_node(&closure_body); // Rewrite all `Some(e)` in tail position to `e` for_each_tail_expr(&closure_body, &mut |e| { let e = match e { @@ -95,13 +95,13 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> let edit = editor.finish(); let closure_body = ast::Expr::cast(edit.new_root().clone()).unwrap(); - let mut editor = builder.make_editor(expr.syntax()); - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(expr.syntax()); + let make = editor.make(); let closure_body = match closure_body { ast::Expr::BlockExpr(block) => unwrap_trivial_block(block), e => e, }; - let cond = if invert_cond { invert_boolean_expression(&make, cond) } else { cond }; + let cond = if invert_cond { invert_boolean_expression(make, cond) } else { cond }; let parenthesize = matches!( cond, @@ -128,8 +128,6 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> let arg_list = make.arg_list(Some(make.expr_closure(None, closure_body).into())); let mcall = make.expr_method_call(cond, make.name_ref("then"), arg_list); editor.replace(expr.syntax(), mcall.syntax()); - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -187,7 +185,7 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> e => mapless_make.block_expr(None, Some(e)), }; - let (mut editor, closure_body) = SyntaxEditor::with_ast_node(&closure_body); + let (editor, closure_body) = SyntaxEditor::with_ast_node(&closure_body); // Wrap all tails in `Some(...)` let none_path = mapless_make.expr_path(mapless_make.ident_path("None")); let some_path = mapless_make.expr_path(mapless_make.ident_path("Some")); @@ -210,14 +208,15 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> let edit = editor.finish(); let closure_body = ast::BlockExpr::cast(edit.new_root().clone()).unwrap(); - let mut editor = builder.make_editor(mcall.syntax()); - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(mcall.syntax()); + let make = editor.make(); let cond = match &receiver { ast::Expr::ParenExpr(expr) => expr.expr().unwrap_or(receiver), _ => receiver, }; - let if_expr = make + let if_expr = editor + .make() .expr_if( cond, closure_body, @@ -225,8 +224,6 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> ) .indent(mcall.indent_level()); editor.replace(mcall.syntax().clone(), if_expr.syntax().clone()); - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs index a5c29a45a51f..9eb4c0584b36 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs @@ -2,7 +2,7 @@ use ide_db::{famous_defs::FamousDefs, syntax_helpers::suggest_name}; use syntax::{ AstNode, - ast::{self, HasAttrs, HasLoopBody, edit::IndentLevel, syntax_factory::SyntaxFactory}, + ast::{self, HasAttrs, HasLoopBody, edit::IndentLevel}, syntax_editor::Position, }; @@ -48,8 +48,8 @@ pub(crate) fn convert_for_loop_to_while_let( "Replace this for loop with `while let`", for_loop.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(for_loop.syntax()); + let editor = builder.make_editor(for_loop.syntax()); + let make = editor.make(); let (iterable, method) = if impls_core_iter(&ctx.sema, &iterable) { (iterable, None) @@ -85,12 +85,7 @@ pub(crate) fn convert_for_loop_to_while_let( editor.insert(Position::before(for_loop.syntax()), make.whitespace(" ")); editor.insert(Position::before(for_loop.syntax()), label); } - crate::utils::insert_attributes( - for_loop.syntax(), - &mut editor, - for_loop.attrs(), - &make, - ); + crate::utils::insert_attributes(for_loop.syntax(), &editor, for_loop.attrs()); editor.insert( Position::before(for_loop.syntax()), @@ -110,7 +105,6 @@ pub(crate) fn convert_for_loop_to_while_let( editor.replace(for_loop.syntax(), while_loop.syntax()); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs index 66ccd2a4e409..18f3ced41402 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs @@ -74,8 +74,8 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> "Convert From to TryFrom", impl_.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(impl_.syntax()); + let editor = builder.make_editor(impl_.syntax()); + let make = editor.make(); editor.replace(trait_ty.syntax(), make.ty(&format!("TryFrom<{from_type}>")).syntax()); editor.replace( @@ -83,11 +83,11 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> make.ty("Result").syntax(), ); editor.replace(from_fn_name.syntax(), make.name("try_from").syntax()); - editor.replace(tail_expr.syntax(), wrap_ok(&make, tail_expr.clone()).syntax()); + editor.replace(tail_expr.syntax(), wrap_ok(make, tail_expr.clone()).syntax()); for r in return_exprs { let t = r.expr().unwrap_or_else(|| make.expr_unit()); - editor.replace(t.syntax(), wrap_ok(&make, t.clone()).syntax()); + editor.replace(t.syntax(), wrap_ok(make, t.clone()).syntax()); } let error_type_alias = @@ -111,7 +111,6 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> make.whitespace("\n").syntax_element(), ], ); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index 63b1a0193bd6..ecfbc3a07daf 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -3,7 +3,7 @@ use stdx::format_to; use syntax::{ AstNode, - ast::{self, HasArgList, HasLoopBody, edit::AstNodeEdit, syntax_factory::SyntaxFactory}, + ast::{self, HasArgList, HasLoopBody, edit::AstNodeEdit}, }; use crate::{AssistContext, AssistId, Assists}; @@ -57,7 +57,9 @@ pub(crate) fn convert_iter_for_each_to_for( "Replace this `Iterator::for_each` with a for loop", range, |builder| { - let make = SyntaxFactory::with_mappings(); + let target_node = stmt.as_ref().map_or(method.syntax(), AstNode::syntax); + let editor = builder.make_editor(target_node); + let make = editor.make(); let indent = stmt.as_ref().map_or_else(|| method.indent_level(), ast::ExprStmt::indent_level); @@ -68,9 +70,6 @@ pub(crate) fn convert_iter_for_each_to_for( .indent(indent); let expr_for_loop = make.expr_for_loop(param, receiver, block); - - let target_node = stmt.as_ref().map_or(method.syntax(), AstNode::syntax); - let mut editor = builder.make_editor(target_node); editor.replace(target_node, expr_for_loop.syntax()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs index 994fb44279b6..885750b1aabe 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs @@ -1,7 +1,6 @@ use syntax::T; use syntax::ast::RangeItem; use syntax::ast::edit::AstNodeEdit; -use syntax::ast::syntax_factory::SyntaxFactory; use syntax::ast::{self, AstNode, HasName, LetStmt, Pat}; use syntax::syntax_editor::SyntaxEditor; @@ -26,15 +25,13 @@ // } // ``` pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let root = ctx.source_file().syntax().clone(); - let (mut editor, _) = SyntaxEditor::new(root); + let (editor, _) = SyntaxEditor::new(ctx.source_file().syntax().clone()); // Should focus on the `else` token to trigger let let_stmt = ctx .find_token_syntax_at_offset(T![else]) .and_then(|it| it.parent()?.parent()) .or_else(|| ctx.find_token_syntax_at_offset(T![let])?.parent())?; let let_stmt = LetStmt::cast(let_stmt)?; - let make = SyntaxFactory::with_mappings(); let else_block = let_stmt.let_else()?.block_expr()?; let else_expr = if else_block.statements().next().is_none() && let Some(tail_expr) = else_block.tail_expr() @@ -50,7 +47,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<' } let pat = let_stmt.pat()?; let mut idents = Vec::default(); - let pat_without_mut = remove_mut_and_collect_idents(&make, &mut editor, &pat, &mut idents)?; + let pat_without_mut = remove_mut_and_collect_idents(&editor, &pat, &mut idents)?; let bindings = idents .into_iter() .filter_map(|ref pat| { @@ -72,8 +69,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<' }, let_stmt.syntax().text_range(), |builder| { - // let mut editor = builder.make_editor(let_stmt.syntax()); - + let make = editor.make(); let binding_paths = bindings .iter() .map(|(name, _)| make.expr_path(make.ident_path(&name.to_string()))) @@ -117,19 +113,17 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<' ); editor.replace(let_stmt.syntax(), new_let_stmt.syntax()); } - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } fn remove_mut_and_collect_idents( - make: &SyntaxFactory, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, pat: &ast::Pat, acc: &mut Vec, ) -> Option { + let make = editor.make(); Some(match pat { ast::Pat::IdentPat(p) => { acc.push(p.clone()); @@ -139,97 +133,95 @@ fn remove_mut_and_collect_idents( p.name()?, ); let non_mut_pat = if let Some(inner) = p.pat() { - non_mut_pat.set_pat( - remove_mut_and_collect_idents(make, editor, &inner, acc), - editor, - make, - ) + non_mut_pat.set_pat(remove_mut_and_collect_idents(editor, &inner, acc), editor) } else { non_mut_pat }; non_mut_pat.into() } ast::Pat::BoxPat(p) => { - make.box_pat(remove_mut_and_collect_idents(make, editor, &p.pat()?, acc)?).into() + let pat = remove_mut_and_collect_idents(editor, &p.pat()?, acc)?; + make.box_pat(pat).into() + } + ast::Pat::OrPat(p) => { + let pats = p + .pats() + .map(|pat| remove_mut_and_collect_idents(editor, &pat, acc)) + .collect::>>()?; + make.or_pat(pats, p.leading_pipe().is_some()).into() } - ast::Pat::OrPat(p) => make - .or_pat( - p.pats() - .map(|pat| remove_mut_and_collect_idents(make, editor, &pat, acc)) - .collect::>>()?, - p.leading_pipe().is_some(), - ) - .into(), ast::Pat::ParenPat(p) => { - make.paren_pat(remove_mut_and_collect_idents(make, editor, &p.pat()?, acc)?).into() + let pat = remove_mut_and_collect_idents(editor, &p.pat()?, acc)?; + make.paren_pat(pat).into() + } + ast::Pat::RangePat(p) => { + let start = if let Some(start) = p.start() { + Some(remove_mut_and_collect_idents(editor, &start, acc)?) + } else { + None + }; + let end = if let Some(end) = p.end() { + Some(remove_mut_and_collect_idents(editor, &end, acc)?) + } else { + None + }; + make.range_pat(start, end).into() + } + ast::Pat::RecordPat(p) => { + let fields = p + .record_pat_field_list()? + .fields() + .map(|field| { + remove_mut_and_collect_idents(editor, &field.pat()?, acc).map(|pat| { + if let Some(name_ref) = field.name_ref() { + make.record_pat_field(name_ref, pat) + } else { + make.record_pat_field_shorthand(pat) + } + }) + }) + .collect::>>()?; + editor + .make() + .record_pat_with_fields( + p.path()?, + editor + .make() + .record_pat_field_list(fields, p.record_pat_field_list()?.rest_pat()), + ) + .into() } - ast::Pat::RangePat(p) => make - .range_pat( - if let Some(start) = p.start() { - Some(remove_mut_and_collect_idents(make, editor, &start, acc)?) - } else { - None - }, - if let Some(end) = p.end() { - Some(remove_mut_and_collect_idents(make, editor, &end, acc)?) - } else { - None - }, - ) - .into(), - ast::Pat::RecordPat(p) => make - .record_pat_with_fields( - p.path()?, - make.record_pat_field_list( - p.record_pat_field_list()? - .fields() - .map(|field| { - remove_mut_and_collect_idents(make, editor, &field.pat()?, acc).map( - |pat| { - if let Some(name_ref) = field.name_ref() { - make.record_pat_field(name_ref, pat) - } else { - make.record_pat_field_shorthand(pat) - } - }, - ) - }) - .collect::>>()?, - p.record_pat_field_list()?.rest_pat(), - ), - ) - .into(), ast::Pat::RefPat(p) => { let inner = p.pat()?; if let ast::Pat::IdentPat(ident) = inner { acc.push(ident); p.clone().into() } else { - make.ref_pat(remove_mut_and_collect_idents(make, editor, &inner, acc)?).into() + let pat = remove_mut_and_collect_idents(editor, &inner, acc)?; + make.ref_pat(pat).into() } } - ast::Pat::SlicePat(p) => make - .slice_pat( - p.pats() - .map(|pat| remove_mut_and_collect_idents(make, editor, &pat, acc)) - .collect::>>()?, - ) - .into(), - ast::Pat::TuplePat(p) => make - .tuple_pat( - p.fields() - .map(|field| remove_mut_and_collect_idents(make, editor, &field, acc)) - .collect::>>()?, - ) - .into(), - ast::Pat::TupleStructPat(p) => make - .tuple_struct_pat( - p.path()?, - p.fields() - .map(|field| remove_mut_and_collect_idents(make, editor, &field, acc)) - .collect::>>()?, - ) - .into(), + ast::Pat::SlicePat(p) => { + let pats = p + .pats() + .map(|pat| remove_mut_and_collect_idents(editor, &pat, acc)) + .collect::>>()?; + make.slice_pat(pats).into() + } + ast::Pat::TuplePat(p) => { + let pats = p + .fields() + .map(|field| remove_mut_and_collect_idents(editor, &field, acc)) + .collect::>>()?; + make.tuple_pat(pats).into() + } + ast::Pat::TupleStructPat(p) => { + let fields = p + .fields() + .map(|field| remove_mut_and_collect_idents(editor, &field, acc)) + .collect::>>()?; + make.tuple_struct_pat(p.path()?, fields).into() + } ast::Pat::RestPat(_) | ast::Pat::LiteralPat(_) | ast::Pat::PathPat(_) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs index 4b132d68ee3a..2b658248171a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs @@ -1,7 +1,7 @@ use ide_db::defs::{Definition, NameRefClass}; use syntax::{ AstNode, SyntaxNode, - ast::{self, HasName, Name, edit::AstNodeEdit, syntax_factory::SyntaxFactory}, + ast::{self, HasName, Name, edit::AstNodeEdit}, syntax_editor::SyntaxEditor, }; @@ -121,8 +121,8 @@ fn find_extracted_variable(ctx: &AssistContext<'_>, arm: &ast::MatchArm) -> Opti // Rename `extracted` with `binding` in `pat`. fn rename_variable(pat: &ast::Pat, extracted: &[Name], binding: ast::Pat) -> SyntaxNode { - let (mut editor, syntax) = SyntaxEditor::new(pat.syntax().clone()); - let make = SyntaxFactory::with_mappings(); + let (editor, syntax) = SyntaxEditor::new(pat.syntax().clone()); + let make = editor.make(); let extracted = extracted .iter() .map(|e| e.syntax().text_range() - pat.syntax().text_range().start()) @@ -137,7 +137,9 @@ fn rename_variable(pat: &ast::Pat, extracted: &[Name], binding: ast::Pat) -> Syn if let Some(name_ref) = record_pat_field.field_name() { editor.replace( record_pat_field.syntax(), - make.record_pat_field(make.name_ref(&name_ref.text()), binding.clone()) + editor + .make() + .record_pat_field(make.name_ref(&name_ref.text()), binding.clone()) .syntax(), ); } @@ -145,7 +147,6 @@ fn rename_variable(pat: &ast::Pat, extracted: &[Name], binding: ast::Pat) -> Syn editor.replace(extracted_syntax, binding.syntax()); } } - editor.add_mappings(make.finish_with_mappings()); let new_node = editor.finish().new_root().clone(); if let Some(pat) = ast::Pat::cast(new_node.clone()) { pat.dedent(1.into()).syntax().clone() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index 4ea56e3e613f..21404564fac8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -3,9 +3,7 @@ use syntax::{ NodeOrToken, SyntaxKind, SyntaxNode, T, algo::next_non_trivia_token, - ast::{ - self, AstNode, HasAttrs, HasGenericParams, HasVisibility, syntax_factory::SyntaxFactory, - }, + ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility}, match_ast, syntax_editor::{Element, Position, SyntaxEditor}, }; @@ -102,7 +100,7 @@ fn edit_struct_def( // Note that we don't need to consider macro files in this function because this is // currently not triggered for struct definitions inside macro calls. let tuple_fields = record_fields.fields().filter_map(|f| { - let (mut editor, field) = + let (editor, field) = SyntaxEditor::with_ast_node(&ast::make::tuple_field(f.visibility(), f.ty()?)); editor.insert_all( Position::first_child_of(field.syntax()), @@ -113,15 +111,15 @@ fn edit_struct_def( Some(field) }); - let make = SyntaxFactory::without_mappings(); - let mut edit = builder.make_editor(strukt.syntax()); + let editor = builder.make_editor(strukt.syntax()); + let make = editor.make(); let tuple_fields = make.tuple_field_list(tuple_fields); let mut elements = vec![tuple_fields.syntax().clone().into()]; if let Either::Left(strukt) = strukt { if let Some(w) = strukt.where_clause() { - edit.delete(w.syntax()); + editor.delete(w.syntax()); elements.extend([ make.whitespace("\n").into(), @@ -136,23 +134,23 @@ fn edit_struct_def( .and_then(|tok| tok.next_token()) .filter(|tok| tok.kind() == SyntaxKind::WHITESPACE) { - edit.delete(tok); + editor.delete(tok); } } else { elements.push(make.token(T![;]).into()); } } - edit.replace_with_many(record_fields.syntax(), elements); + editor.replace_with_many(record_fields.syntax(), elements); if let Some(tok) = record_fields .l_curly_token() .and_then(|tok| tok.prev_token()) .filter(|tok| tok.kind() == SyntaxKind::WHITESPACE) { - edit.delete(tok) + editor.delete(tok) } - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); } fn edit_struct_references( @@ -168,18 +166,18 @@ fn edit_struct_references( for (file_id, refs) in usages { let source = ctx.sema.parse(file_id); - let mut edit = builder.make_editor(source.syntax()); + let editor = builder.make_editor(source.syntax()); for r in refs { - process_struct_name_reference(ctx, r, &mut edit, &source); + process_struct_name_reference(ctx, r, &editor, &source); } - builder.add_file_edits(file_id.file_id(ctx.db()), edit); + builder.add_file_edits(file_id.file_id(ctx.db()), editor); } } fn process_struct_name_reference( ctx: &AssistContext<'_>, r: FileReference, - edit: &mut SyntaxEditor, + edit: &SyntaxEditor, source: &ast::SourceFile, ) -> Option<()> { // First check if it's the last semgnet of a path that directly belongs to a record @@ -232,7 +230,7 @@ fn process_struct_name_reference( fn record_to_tuple_struct_like( ctx: &AssistContext<'_>, source: &ast::SourceFile, - edit: &mut SyntaxEditor, + editor: &SyntaxEditor, field_list: T, fields: impl FnOnce(&T) -> I, ) -> Option<()> @@ -240,7 +238,7 @@ fn record_to_tuple_struct_like( T: AstNode, I: IntoIterator, { - let make = SyntaxFactory::without_mappings(); + let make = editor.make(); let orig = ctx.sema.original_range_opt(field_list.syntax())?; let list_range = cover_edit_range(source.syntax(), orig.range); @@ -254,13 +252,13 @@ fn record_to_tuple_struct_like( }; if l_curly.kind() == T!['{'] { - delete_whitespace(edit, l_curly.prev_token()); - delete_whitespace(edit, l_curly.next_token()); - edit.replace(l_curly, make.token(T!['('])); + delete_whitespace(editor, l_curly.prev_token()); + delete_whitespace(editor, l_curly.next_token()); + editor.replace(l_curly, make.token(T!['('])); } if r_curly.kind() == T!['}'] { - delete_whitespace(edit, r_curly.prev_token()); - edit.replace(r_curly, make.token(T![')'])); + delete_whitespace(editor, r_curly.prev_token()); + editor.replace(r_curly, make.token(T![')'])); } for name_ref in fields(&field_list) { @@ -270,14 +268,14 @@ fn record_to_tuple_struct_like( if let Some(colon) = next_non_trivia_token(name_range.end().clone()) && colon.kind() == T![:] { - edit.delete(&colon); - edit.delete_all(name_range); + editor.delete(&colon); + editor.delete_all(name_range); if let Some(next) = next_non_trivia_token(colon.clone()) && next.kind() != T!['}'] { // Avoid overlapping delete whitespace on `{ field: }` - delete_whitespace(edit, colon.next_token()); + delete_whitespace(editor, colon.next_token()); } } } @@ -289,7 +287,6 @@ fn edit_field_references( builder: &mut SourceChangeBuilder, fields: impl Iterator, ) { - let make = SyntaxFactory::without_mappings(); for (index, field) in fields.enumerate() { let field = match ctx.sema.to_def(&field) { Some(it) => it, @@ -299,13 +296,14 @@ fn edit_field_references( let usages = def.usages(&ctx.sema).all(); for (file_id, refs) in usages { let source = ctx.sema.parse(file_id); - let mut edit = builder.make_editor(source.syntax()); + let editor = builder.make_editor(source.syntax()); + let make = editor.make(); for r in refs { if let Some(name_ref) = r.name.as_name_ref() { // Only edit the field reference if it's part of a `.field` access if name_ref.syntax().parent().and_then(ast::FieldExpr::cast).is_some() { - edit.replace_all( + editor.replace_all( cover_edit_range(source.syntax(), r.range), vec![make.name_ref(&index.to_string()).syntax().clone().into()], ); @@ -313,12 +311,12 @@ fn edit_field_references( } } - builder.add_file_edits(file_id.file_id(ctx.db()), edit); + builder.add_file_edits(file_id.file_id(ctx.db()), editor); } } } -fn delete_whitespace(edit: &mut SyntaxEditor, whitespace: Option) { +fn delete_whitespace(edit: &SyntaxEditor, whitespace: Option) { let Some(whitespace) = whitespace else { return }; let NodeOrToken::Token(token) = whitespace.syntax_element() else { return }; @@ -328,7 +326,7 @@ fn delete_whitespace(edit: &mut SyntaxEditor, whitespace: Option) } fn remove_trailing_comma(w: ast::WhereClause) -> SyntaxNode { - let (mut editor, w) = SyntaxEditor::new(w.syntax().clone()); + let (editor, w) = SyntaxEditor::new(w.syntax().clone()); if let Some(last) = w.last_child_or_token() && last.kind() == T![,] { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs index 61393950767f..a17bf02b3c4f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs @@ -5,10 +5,7 @@ SyntaxKind::WHITESPACE, T, algo::previous_non_trivia_token, - ast::{ - self, HasArgList, HasLoopBody, HasName, RangeItem, edit::AstNodeEdit, make, - syntax_factory::SyntaxFactory, - }, + ast::{self, HasArgList, HasLoopBody, HasName, RangeItem, edit::AstNodeEdit, make}, syntax_editor::{Element, Position, SyntaxEditor}, }; @@ -55,13 +52,13 @@ pub(crate) fn convert_range_for_to_while(acc: &mut Assists, ctx: &AssistContext< description, for_.syntax().text_range(), |builder| { - let mut edit = builder.make_editor(for_.syntax()); - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(for_.syntax()); + let make = editor.make(); let indent = for_.indent_level(); let pat = make.ident_pat(pat.ref_token().is_some(), true, name.clone()); let let_stmt = make.let_stmt(pat.into(), None, Some(start)); - edit.insert_all( + editor.insert_all( Position::before(for_.syntax()), vec![ let_stmt.syntax().syntax_element(), @@ -86,25 +83,19 @@ pub(crate) fn convert_range_for_to_while(acc: &mut Assists, ctx: &AssistContext< elements.push(make.token(T![loop]).syntax_element()); } - edit.replace_all( + editor.replace_all( for_kw.syntax_element()..=iterable.syntax().syntax_element(), elements, ); let op = ast::BinaryOp::Assignment { op: Some(ast::ArithOp::Add) }; - process_loop_body( - body, - label, - &mut edit, - vec![ - make.whitespace(&format!("\n{}", indent + 1)).syntax_element(), - make.expr_bin(var_expr, op, step).syntax().syntax_element(), - make.token(T![;]).syntax_element(), - ], - ); - - edit.add_mappings(make.finish_with_mappings()); - builder.add_file_edits(ctx.vfs_file_id(), edit); + let incrementer = vec![ + make.whitespace(&format!("\n{}", indent + 1)).syntax_element(), + make.expr_bin(var_expr, op, step).syntax().syntax_element(), + make.token(T![;]).syntax_element(), + ]; + process_loop_body(body, label, &editor, incrementer); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } @@ -128,7 +119,7 @@ fn extract_range(iterable: &ast::Expr) -> Option<(ast::Expr, Option, fn process_loop_body( body: ast::StmtList, label: Option, - edit: &mut SyntaxEditor, + edit: &SyntaxEditor, incrementer: Vec, ) -> Option<()> { let last = previous_non_trivia_token(body.r_curly_token()?)?.syntax_element(); @@ -156,7 +147,7 @@ fn process_loop_body( let continue_label = make::lifetime("'cont"); let break_expr = make::expr_break(Some(continue_label.clone()), None); - let (mut new_edit, _) = SyntaxEditor::new(new_body.syntax().clone()); + let (new_edit, _) = SyntaxEditor::new(new_body.syntax().clone()); for continue_expr in &continues { new_edit.replace(continue_expr.syntax(), break_expr.syntax()); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index 004d09acac6e..791a6a26af38 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -130,9 +130,10 @@ fn if_expr_to_guarded_return( "Convert to guarded return", target, |edit| { - let make = SyntaxFactory::without_mappings(); + let editor = edit.make_editor(if_expr.syntax()); + let make = editor.make(); let if_indent_level = IndentLevel::from_node(if_expr.syntax()); - let early_expression = else_block.make_early_block(&ctx.sema, &make); + let early_expression = else_block.make_early_block(&ctx.sema, make); let replacement = let_chains.into_iter().map(|expr| { if let ast::Expr::LetExpr(let_expr) = &expr && let (Some(pat), Some(expr)) = (let_expr.pat(), let_expr.expr()) @@ -145,8 +146,8 @@ fn if_expr_to_guarded_return( } else { // If. let new_expr = { - let then_branch = clean_stmt_block(&early_expression, &make); - let cond = invert_boolean_expression(&make, expr); + let then_branch = clean_stmt_block(&early_expression, make); + let cond = invert_boolean_expression(make, expr); make.expr_if(cond, then_branch, None).indent(if_indent_level) }; new_expr.syntax().clone() @@ -170,7 +171,6 @@ fn if_expr_to_guarded_return( .take_while(|i| *i != end_of_then), ) .collect(); - let mut editor = edit.make_editor(if_expr.syntax()); editor.replace_with_many(if_expr.syntax(), then_statements); edit.add_file_edits(ctx.vfs_file_id(), editor); }, @@ -209,22 +209,21 @@ fn let_stmt_to_guarded_return( "Convert to guarded return", target, |edit| { + let editor = edit.make_editor(let_stmt.syntax()); + let make = editor.make(); let let_indent_level = IndentLevel::from_node(let_stmt.syntax()); - let make = SyntaxFactory::without_mappings(); let replacement = { let let_else_stmt = make.let_else_stmt( happy_pattern, let_stmt.ty(), expr.reset_indent(), - else_block.make_early_block(&ctx.sema, &make), + else_block.make_early_block(&ctx.sema, make), ); let let_else_stmt = let_else_stmt.indent(let_indent_level); let_else_stmt.syntax().clone() }; - let mut editor = edit.make_editor(let_stmt.syntax()); editor.replace(let_stmt.syntax(), replacement); - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -268,7 +267,8 @@ fn make_early_block( return block_expr.reset_indent(); } - let (mut edit, block_expr) = SyntaxEditor::with_ast_node(&block_expr.reset_indent()); + let (editor, block_expr) = SyntaxEditor::with_ast_node(&block_expr.reset_indent()); + let make = editor.make(); let last_stmt = block_expr.statements().last().map(|it| it.syntax().clone()); let tail_expr = block_expr.tail_expr().map(|it| it.syntax().clone()); @@ -277,13 +277,11 @@ fn make_early_block( }; let whitespace = last_element.prev_sibling_or_token().filter(|it| it.kind() == WHITESPACE); - let make = SyntaxFactory::without_mappings(); - if let Some(tail_expr) = block_expr.tail_expr() && !self.kind.is_unit() { - let early_expr = self.kind.make_early_expr(sema, &make, Some(tail_expr.clone())); - edit.replace(tail_expr.syntax(), early_expr.syntax()); + let early_expr = self.kind.make_early_expr(sema, make, Some(tail_expr.clone())); + editor.replace(tail_expr.syntax(), early_expr.syntax()); } else { let last_stmt = match block_expr.tail_expr() { Some(expr) => make.expr_stmt(expr).syntax().clone(), @@ -291,14 +289,14 @@ fn make_early_block( }; let whitespace = make.whitespace(&whitespace.map_or(String::new(), |it| it.to_string())); - let early_expr = self.kind.make_early_expr(sema, &make, None).syntax().clone().into(); - edit.replace_with_many( + let early_expr = self.kind.make_early_expr(sema, make, None).syntax().clone().into(); + editor.replace_with_many( last_element, vec![last_stmt.into(), whitespace.into(), early_expr], ); } - ast::BlockExpr::cast(edit.finish().new_root().clone()).unwrap() + ast::BlockExpr::cast(editor.finish().new_root().clone()).unwrap() } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index 1740cd024a89..a99425cef92a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -72,15 +72,15 @@ pub(crate) fn convert_tuple_return_type_to_struct( "Convert tuple return type to tuple struct", target, move |edit| { - let mut syntax_editor = edit.make_editor(ret_type.syntax()); - let syntax_factory = SyntaxFactory::with_mappings(); + let editor = edit.make_editor(ret_type.syntax()); + let make = editor.make(); let usages = Definition::Function(fn_def).usages(&ctx.sema).all(); let struct_name = format!("{}Result", stdx::to_camel_case(&fn_name.to_string())); let parent = fn_.syntax().ancestors().find_map(>::cast); add_tuple_struct_def( edit, - &syntax_factory, + make, ctx, &usages, parent.as_ref().map(|it| it.syntax()).unwrap_or(fn_.syntax()), @@ -89,22 +89,12 @@ pub(crate) fn convert_tuple_return_type_to_struct( &target_module, ); - syntax_editor.replace( - ret_type.syntax(), - syntax_factory.ret_type(syntax_factory.ty(&struct_name)).syntax(), - ); + editor.replace(ret_type.syntax(), make.ret_type(make.ty(&struct_name)).syntax()); if let Some(fn_body) = fn_.body() { - replace_body_return_values( - &mut syntax_editor, - &syntax_factory, - ast::Expr::BlockExpr(fn_body), - &struct_name, - ); + replace_body_return_values(&editor, ast::Expr::BlockExpr(fn_body), &struct_name); } - - syntax_editor.add_mappings(syntax_factory.finish_with_mappings()); - edit.add_file_edits(ctx.vfs_file_id(), syntax_editor); + edit.add_file_edits(ctx.vfs_file_id(), editor); replace_usages(edit, ctx, &usages, &struct_name, &target_module); }, @@ -122,35 +112,22 @@ fn replace_usages( for (file_id, references) in usages.iter() { let Some(first_ref) = references.first() else { continue }; - let mut editor = edit.make_editor(first_ref.name.syntax().as_node().unwrap()); - let syntax_factory = SyntaxFactory::with_mappings(); + let editor = edit.make_editor(first_ref.name.syntax().as_node().unwrap()); + let make = editor.make(); - let refs_with_imports = augment_references_with_imports( - &syntax_factory, - ctx, - references, - struct_name, - target_module, - ); + let refs_with_imports = + augment_references_with_imports(make, ctx, references, struct_name, target_module); refs_with_imports.into_iter().rev().for_each(|(name, import_data)| { if let Some(fn_) = name.syntax().parent().and_then(ast::Fn::cast) { cov_mark::hit!(replace_trait_impl_fns); if let Some(ret_type) = fn_.ret_type() { - editor.replace( - ret_type.syntax(), - syntax_factory.ret_type(syntax_factory.ty(struct_name)).syntax(), - ); + editor.replace(ret_type.syntax(), make.ret_type(make.ty(struct_name)).syntax()); } if let Some(fn_body) = fn_.body() { - replace_body_return_values( - &mut editor, - &syntax_factory, - ast::Expr::BlockExpr(fn_body), - struct_name, - ); + replace_body_return_values(&editor, ast::Expr::BlockExpr(fn_body), struct_name); } } else { // replace tuple patterns @@ -172,27 +149,17 @@ fn replace_usages( for tuple_pat in tuple_pats { editor.replace( tuple_pat.syntax(), - syntax_factory - .tuple_struct_pat( - syntax_factory.path_from_text(struct_name), - tuple_pat.fields(), - ) + editor + .make() + .tuple_struct_pat(make.path_from_text(struct_name), tuple_pat.fields()) .syntax(), ); } } if let Some((import_scope, path)) = import_data { - insert_use_with_editor( - &import_scope, - path, - &ctx.config.insert_use, - &mut editor, - &syntax_factory, - ); + insert_use_with_editor(&import_scope, path, &ctx.config.insert_use, &editor); } }); - - editor.add_mappings(syntax_factory.finish_with_mappings()); edit.add_file_edits(file_id.file_id(ctx.db()), editor); } } @@ -296,12 +263,8 @@ fn add_tuple_struct_def( } /// Replaces each returned tuple in `body` with the constructor of the tuple struct named `struct_name`. -fn replace_body_return_values( - syntax_editor: &mut SyntaxEditor, - syntax_factory: &SyntaxFactory, - body: ast::Expr, - struct_name: &str, -) { +fn replace_body_return_values(editor: &SyntaxEditor, body: ast::Expr, struct_name: &str) { + let make = editor.make(); let mut exprs_to_wrap = Vec::new(); let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_wrap, e); @@ -316,11 +279,11 @@ fn replace_body_return_values( for ret_expr in exprs_to_wrap { if let ast::Expr::TupleExpr(tuple_expr) = &ret_expr { - let struct_constructor = syntax_factory.expr_call( - syntax_factory.expr_path(syntax_factory.ident_path(struct_name)), - syntax_factory.arg_list(tuple_expr.fields()), + let struct_constructor = make.expr_call( + make.expr_path(make.ident_path(struct_name)), + make.arg_list(tuple_expr.fields()), ); - syntax_editor.replace(ret_expr.syntax(), struct_constructor.syntax()); + editor.replace(ret_expr.syntax(), struct_constructor.syntax()); } } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index 4ce7a9d866a9..a1b33a0558b1 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -86,24 +86,25 @@ pub(crate) fn convert_tuple_struct_to_named_struct( "Convert to named struct", target, |edit| { - let names = generate_names(tuple_fields.fields()); + let editor = edit.make_editor(syntax); + let names = generate_names(tuple_fields.fields(), editor.make()); edit_field_references(ctx, edit, tuple_fields.fields(), &names); - let mut editor = edit.make_editor(syntax); edit_struct_references(ctx, edit, strukt_def, &names); - edit_struct_def(&mut editor, &strukt_or_variant, tuple_fields, names); + edit_struct_def(&editor, &strukt_or_variant, tuple_fields, names); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) } fn edit_struct_def( - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, strukt: &Either, tuple_fields: ast::TupleFieldList, names: Vec, ) { + let make = editor.make(); let record_fields = tuple_fields.fields().zip(names).filter_map(|(f, name)| { - let (mut field_editor, field) = + let (field_editor, field) = SyntaxEditor::with_ast_node(&ast::make::record_field(f.visibility(), name, f.ty()?)); field_editor.insert_all( Position::first_child_of(field.syntax()), @@ -111,7 +112,6 @@ fn edit_struct_def( ); ast::RecordField::cast(field_editor.finish().new_root().clone()) }); - let make = SyntaxFactory::without_mappings(); let record_fields = make.record_field_list(record_fields); let tuple_fields_before = Position::before(tuple_fields.syntax()); @@ -153,10 +153,10 @@ fn edit_struct_references( for (file_id, refs) in usages { let source = ctx.sema.parse(file_id); - let mut editor = edit.make_editor(source.syntax()); + let editor = edit.make_editor(source.syntax()); for r in refs { - process_struct_name_reference(ctx, r, &mut editor, &source, &strukt_def, names); + process_struct_name_reference(ctx, r, &editor, &source, &strukt_def, names); } edit.add_file_edits(file_id.file_id(ctx.db()), editor); @@ -166,12 +166,12 @@ fn edit_struct_references( fn process_struct_name_reference( ctx: &AssistContext<'_>, r: FileReference, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, source: &ast::SourceFile, strukt_def: &Definition, names: &[ast::Name], ) -> Option<()> { - let make = SyntaxFactory::without_mappings(); + let make = editor.make(); let name_ref = r.name.as_name_ref()?; let path_segment = name_ref.syntax().parent().and_then(ast::PathSegment::cast)?; let full_path = path_segment.syntax().parent().and_then(ast::Path::cast)?.top_path(); @@ -231,10 +231,11 @@ fn process_struct_name_reference( fn process_delimiter( ctx: &AssistContext<'_>, source: &ast::SourceFile, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, list: &impl AstNode, first_insert: Vec, ) { + let make = editor.make(); let Some(range) = ctx.sema.original_range_opt(list.syntax()) else { return }; let place = cover_edit_range(source.syntax(), range.range); @@ -247,7 +248,6 @@ fn process_delimiter( syntax::NodeOrToken::Token(t) => Some(t.clone()), }; - let make = SyntaxFactory::without_mappings(); if let Some(l_paren) = l_paren && l_paren.kind() == T!['('] { @@ -284,7 +284,7 @@ fn edit_field_references( let usages = def.usages(&ctx.sema).all(); for (file_id, refs) in usages { let source = ctx.sema.parse(file_id); - let mut editor = edit.make_editor(source.syntax()); + let editor = edit.make_editor(source.syntax()); for r in refs { if let Some(name_ref) = r.name.as_name_ref() && let Some(original) = ctx.sema.original_range_opt(name_ref.syntax()) @@ -300,8 +300,10 @@ fn edit_field_references( } } -fn generate_names(fields: impl Iterator) -> Vec { - let make = SyntaxFactory::without_mappings(); +fn generate_names( + fields: impl Iterator, + make: &SyntaxFactory, +) -> Vec { fields .enumerate() .map(|(i, _)| { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs index f8215d6723d3..bbfac8f095f5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs @@ -6,7 +6,6 @@ ast::{ self, HasLoopBody, edit::{AstNodeEdit, IndentLevel}, - syntax_factory::SyntaxFactory, }, syntax_editor::{Element, Position}, }; @@ -52,18 +51,19 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) "Convert while to loop", target, |builder| { - let make = SyntaxFactory::without_mappings(); - let mut edit = builder.make_editor(while_expr.syntax()); + let editor = builder.make_editor(while_expr.syntax()); + let make = editor.make(); let while_indent_level = IndentLevel::from_node(while_expr.syntax()); - let break_block = make + let break_block = editor + .make() .block_expr( iter::once(make.expr_stmt(make.expr_break(None, None).into()).into()), None, ) .indent(IndentLevel(1)); - edit.replace_all( + editor.replace_all( while_kw.syntax_element()..=while_cond.syntax().syntax_element(), vec![make.token(T![loop]).syntax_element()], ); @@ -73,17 +73,17 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) let if_expr = make.expr_if(while_cond, then_branch, Some(break_block.into())); let stmts = iter::once(make.expr_stmt(if_expr.into()).into()); let block_expr = make.block_expr(stmts, None); - edit.replace(while_body.syntax(), block_expr.indent(while_indent_level).syntax()); + editor.replace(while_body.syntax(), block_expr.indent(while_indent_level).syntax()); } else { - let if_cond = invert_boolean_expression(&make, while_cond); + let if_cond = invert_boolean_expression(make, while_cond); let if_expr = make.expr_if(if_cond, break_block, None).indent(while_indent_level); if !while_body.syntax().text().contains_char('\n') { - edit.insert( + editor.insert( Position::after(&l_curly), make.whitespace(&format!("\n{while_indent_level}")), ); } - edit.insert_all( + editor.insert_all( Position::after(&l_curly), vec![ make.whitespace(&format!("\n{}", while_indent_level + 1)).into(), @@ -91,9 +91,7 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) ], ); }; - - edit.add_mappings(make.finish_with_mappings()); - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index ec4a83b642c0..f23957e647e4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -124,9 +124,9 @@ fn destructure_struct_binding_impl( data: &StructEditData, ) { let field_names = generate_field_names(ctx, data); - let mut editor = builder.make_editor(data.target.syntax()); - destructure_pat(ctx, &mut editor, data, &field_names); - update_usages(ctx, &mut editor, data, &field_names.into_iter().collect()); + let editor = builder.make_editor(data.target.syntax()); + destructure_pat(ctx, &editor, data, &field_names); + update_usages(ctx, &editor, data, &field_names.into_iter().collect()); builder.add_file_edits(ctx.vfs_file_id(), editor); } @@ -145,19 +145,16 @@ struct StructEditData { } impl StructEditData { - fn apply_to_destruct( - &self, - new_pat: ast::Pat, - editor: &mut SyntaxEditor, - make: &SyntaxFactory, - ) { + fn apply_to_destruct(&self, new_pat: ast::Pat, editor: &SyntaxEditor) { + let make = editor.make(); match &self.target { Target::IdentPat(pat) => { // If the binding is nested inside a record, we need to wrap the new // destructured pattern in a non-shorthand record field if self.need_record_field_name { - let new_pat = - make.record_pat_field(make.name_ref(&self.name.to_string()), new_pat); + let new_pat = editor + .make() + .record_pat_field(make.name_ref(&self.name.to_string()), new_pat); editor.replace(pat.syntax(), new_pat.syntax()) } else { editor.replace(pat.syntax(), new_pat.syntax()) @@ -275,15 +272,15 @@ fn last_usage(usages: &[FileReference]) -> Option { fn destructure_pat( _ctx: &AssistContext<'_>, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, data: &StructEditData, field_names: &[(SmolStr, SmolStr)], ) { + let make = editor.make(); let struct_path = mod_path_to_ast(&data.struct_def_path, data.edition); let is_ref = data.target.is_ref(); let is_mut = data.target.is_mut(); - let make = SyntaxFactory::with_mappings(); let new_pat = match data.kind { hir::StructKind::Tuple => { let ident_pats = field_names.iter().map(|(_, new_name)| { @@ -297,7 +294,7 @@ fn destructure_pat( // Use shorthand syntax if possible if old_name == new_name { make.record_pat_field_shorthand( - make.ident_pat(is_ref, is_mut, make.name(old_name)).into(), + editor.make().ident_pat(is_ref, is_mut, make.name(old_name)).into(), ) } else { make.record_pat_field( @@ -314,8 +311,7 @@ fn destructure_pat( hir::StructKind::Unit => make.path_pat(struct_path), }; - data.apply_to_destruct(new_pat, editor, &make); - editor.add_mappings(make.finish_with_mappings()); + data.apply_to_destruct(new_pat, editor); } fn generate_field_names(ctx: &AssistContext<'_>, data: &StructEditData) -> Vec<(SmolStr, SmolStr)> { @@ -354,18 +350,16 @@ fn new_field_name(base_name: SmolStr, names_in_scope: &FxHashSet) -> Sm fn update_usages( ctx: &AssistContext<'_>, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, data: &StructEditData, field_names: &FxHashMap, ) { let source = ctx.source_file().syntax(); - let make = SyntaxFactory::with_mappings(); let edits = data .usages .iter() - .filter_map(|r| build_usage_edit(ctx, &make, data, r, field_names)) + .filter_map(|r| build_usage_edit(ctx, editor.make(), data, r, field_names)) .collect_vec(); - editor.add_mappings(make.finish_with_mappings()); for (old, new) in edits { if let Some(range) = ctx.sema.original_range_opt(&old) { editor.replace_all(cover_edit_range(source, range.range), vec![new.into()]); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs index 05fa00f4e8c1..b0f257e0028f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs @@ -89,22 +89,17 @@ fn destructure_tuple_edit_impl( data: &TupleData, in_sub_pattern: bool, ) { - let mut syntax_editor = edit.make_editor(data.ident_pat.syntax()); - let syntax_factory = SyntaxFactory::with_mappings(); + let editor = edit.make_editor(data.ident_pat.syntax()); + let make = editor.make(); - let assignment_edit = - edit_tuple_assignment(ctx, edit, &mut syntax_editor, &syntax_factory, data, in_sub_pattern); - let current_file_usages_edit = edit_tuple_usages(data, ctx, &syntax_factory, in_sub_pattern); + let assignment_edit = edit_tuple_assignment(ctx, edit, &editor, data, in_sub_pattern); + let current_file_usages_edit = edit_tuple_usages(data, ctx, make, in_sub_pattern); - assignment_edit.apply(&mut syntax_editor, &syntax_factory); + assignment_edit.apply(&editor); if let Some(usages_edit) = current_file_usages_edit { - usages_edit - .into_iter() - .for_each(|usage_edit| usage_edit.apply(ctx, edit, &mut syntax_editor)) + usages_edit.into_iter().for_each(|usage_edit| usage_edit.apply(ctx, edit, &editor)) } - - syntax_editor.add_mappings(syntax_factory.finish_with_mappings()); - edit.add_file_edits(ctx.vfs_file_id(), syntax_editor); + edit.add_file_edits(ctx.vfs_file_id(), editor); } fn collect_data(ident_pat: IdentPat, ctx: &AssistContext<'_>) -> Option { @@ -175,11 +170,11 @@ struct TupleData { fn edit_tuple_assignment( ctx: &AssistContext<'_>, edit: &mut SourceChangeBuilder, - editor: &mut SyntaxEditor, - make: &SyntaxFactory, + editor: &SyntaxEditor, data: &TupleData, in_sub_pattern: bool, ) -> AssignmentEdit { + let make = editor.make(); let tuple_pat = { let original = &data.ident_pat; let is_ref = original.ref_token().is_some(); @@ -223,18 +218,17 @@ struct AssignmentEdit { } impl AssignmentEdit { - fn apply(self, syntax_editor: &mut SyntaxEditor, syntax_mapping: &SyntaxFactory) { + fn apply(self, editor: &SyntaxEditor) { + let make = editor.make(); // with sub_pattern: keep original tuple and add subpattern: `tup @ (_0, _1)` if self.in_sub_pattern { - self.ident_pat.set_pat(Some(self.tuple_pat.into()), syntax_editor, syntax_mapping); + self.ident_pat.set_pat(Some(self.tuple_pat.into()), editor); } else if self.is_shorthand_field { - syntax_editor.insert(Position::after(self.ident_pat.syntax()), self.tuple_pat.syntax()); - syntax_editor - .insert(Position::after(self.ident_pat.syntax()), syntax_mapping.whitespace(" ")); - syntax_editor - .insert(Position::after(self.ident_pat.syntax()), syntax_mapping.token(T![:])); + editor.insert(Position::after(self.ident_pat.syntax()), self.tuple_pat.syntax()); + editor.insert(Position::after(self.ident_pat.syntax()), make.whitespace(" ")); + editor.insert(Position::after(self.ident_pat.syntax()), make.token(T![:])); } else { - syntax_editor.replace(self.ident_pat.syntax(), self.tuple_pat.syntax()) + editor.replace(self.ident_pat.syntax(), self.tuple_pat.syntax()) } } } @@ -313,7 +307,7 @@ fn apply( self, ctx: &AssistContext<'_>, edit: &mut SourceChangeBuilder, - syntax_editor: &mut SyntaxEditor, + syntax_editor: &SyntaxEditor, ) { match self { EditTupleUsage::NoIndex(range) => { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs index 865dc862215f..399b2aa69be8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs @@ -65,19 +65,19 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op "Replace try expression with match", target, |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(try_expr.syntax()); - + let editor = builder.make_editor(try_expr.syntax()); + let make = editor.make(); let sad_pat = match try_enum { TryEnum::Option => make.path_pat(make.ident_path("None")), - TryEnum::Result => make + TryEnum::Result => editor + .make() .tuple_struct_pat( make.ident_path("Err"), iter::once(make.path_pat(make.ident_path("err"))), ) .into(), }; - let sad_expr = make.expr_return(Some(sad_expr(try_enum, &make, || { + let sad_expr = make.expr_return(Some(sad_expr(try_enum, make, || { make.expr_path(make.ident_path("err")) }))); @@ -90,12 +90,12 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let match_arm_list = make.match_arm_list([happy_arm, sad_arm]); - let expr_match = make + let expr_match = editor + .make() .expr_match(expr.clone(), match_arm_list) .indent(IndentLevel::from_node(try_expr.syntax())); editor.replace(try_expr.syntax(), expr_match.syntax()); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); @@ -109,8 +109,8 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op "Replace try expression with let else", target, |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(let_stmt.syntax()); + let editor = builder.make_editor(let_stmt.syntax()); + let make = editor.make(); let indent_level = IndentLevel::from_node(let_stmt.syntax()); let fill_expr = || crate::utils::expr_fill_default(ctx.config); @@ -121,19 +121,25 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op TryEnum::Result => make.ty_result(ty, make.ty_infer().into()).into(), }), expr, - make.block_expr( - iter::once( - make.expr_stmt( - make.expr_return(Some(sad_expr(try_enum, &make, fill_expr))).into(), - ) - .into(), - ), - None, - ) - .indent(indent_level), + editor + .make() + .block_expr( + iter::once( + editor + .make() + .expr_stmt( + editor + .make() + .expr_return(Some(sad_expr(try_enum, make, fill_expr))) + .into(), + ) + .into(), + ), + None, + ) + .indent(indent_level), ); editor.replace(let_stmt.syntax(), new_let_stmt.syntax()); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs index 79b9f5d69afc..1c8cbf5af594 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs @@ -8,7 +8,7 @@ use stdx::never; use syntax::{ AstNode, Direction, SyntaxNode, SyntaxToken, T, - ast::{self, Use, UseTree, VisibilityKind, syntax_factory::SyntaxFactory}, + ast::{self, Use, UseTree, VisibilityKind}, }; use crate::{ @@ -148,8 +148,8 @@ fn build_expanded_import( current_module: Module, reexport_public_items: bool, ) { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(use_tree.syntax()); + let editor = builder.make_editor(use_tree.syntax()); + let make = editor.make(); let (must_be_pub, visible_from) = if !reexport_public_items { (false, current_module) } else { @@ -192,7 +192,6 @@ fn build_expanded_import( } None => never!(), } - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs index a7e78dfc9c94..c75e4cede747 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs @@ -51,23 +51,25 @@ fn expand_record_rest_pattern( "Fill struct fields", rest_pat.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(rest_pat.syntax()); + let editor = builder.make_editor(rest_pat.syntax()); + let make = editor.make(); let new_fields = old_field_list.fields().chain(matched_fields.iter().map(|(f, _)| { make.record_pat_field_shorthand( - make.ident_pat( - false, - false, - make.name(&f.name(ctx.sema.db).display_no_db(edition).to_smolstr()), - ) - .into(), + editor + .make() + .ident_pat( + false, + false, + editor + .make() + .name(&f.name(ctx.sema.db).display_no_db(edition).to_smolstr()), + ) + .into(), ) })); let new_field_list = make.record_pat_field_list(new_fields, None); editor.replace(old_field_list.syntax(), new_field_list.syntax()); - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -130,8 +132,8 @@ fn expand_tuple_struct_rest_pattern( "Fill tuple struct fields", rest_pat.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(rest_pat.syntax()); + let editor = builder.make_editor(rest_pat.syntax()); + let make = editor.make(); let mut name_gen = NameGenerator::new_from_scope_locals(ctx.sema.scope(pat.syntax())); let new_pat = make.tuple_struct_pat( @@ -141,7 +143,7 @@ fn expand_tuple_struct_rest_pattern( .chain(fields[prefix_count..fields.len() - suffix_count].iter().map(|f| { gen_unnamed_pat( ctx, - &make, + make, &mut name_gen, &f.ty(ctx.db()).to_type(ctx.sema.db), f.index(), @@ -151,8 +153,6 @@ fn expand_tuple_struct_rest_pattern( ); editor.replace(pat.syntax(), new_pat.syntax()); - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -200,24 +200,21 @@ fn expand_tuple_rest_pattern( "Fill tuple fields", rest_pat.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(rest_pat.syntax()); - + let editor = builder.make_editor(rest_pat.syntax()); + let make = editor.make(); let mut name_gen = NameGenerator::new_from_scope_locals(ctx.sema.scope(pat.syntax())); let new_pat = make.tuple_pat( pat.fields() .take(prefix_count) .chain(fields[prefix_count..len - suffix_count].iter().enumerate().map( |(index, ty)| { - gen_unnamed_pat(ctx, &make, &mut name_gen, ty, prefix_count + index) + gen_unnamed_pat(ctx, make, &mut name_gen, ty, prefix_count + index) }, )) .chain(pat.fields().skip(prefix_count + 1)), ); editor.replace(pat.syntax(), new_pat.syntax()); - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -264,8 +261,8 @@ fn expand_slice_rest_pattern( "Fill slice fields", rest_pat.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(rest_pat.syntax()); + let editor = builder.make_editor(rest_pat.syntax()); + let make = editor.make(); let mut name_gen = NameGenerator::new_from_scope_locals(ctx.sema.scope(pat.syntax())); let new_pat = make.slice_pat( @@ -273,14 +270,12 @@ fn expand_slice_rest_pattern( .take(prefix_count) .chain( (prefix_count..len - suffix_count) - .map(|index| gen_unnamed_pat(ctx, &make, &mut name_gen, &ty, index)), + .map(|index| gen_unnamed_pat(ctx, make, &mut name_gen, &ty, index)), ) .chain(pat.pats().skip(prefix_count + 1)), ); editor.replace(pat.syntax(), new_pat.syntax()); - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs index 35e8baa18aca..c87ded9dc47b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs @@ -8,7 +8,7 @@ AstNode, AstToken, NodeOrToken, SyntaxKind::WHITESPACE, SyntaxToken, T, - ast::{self, TokenTree, syntax_factory::SyntaxFactory}, + ast::{self, TokenTree}, }; // Assist: extract_expressions_from_format_string @@ -57,7 +57,8 @@ pub(crate) fn extract_expressions_from_format_string( "Extract format expressions", tt.syntax().text_range(), |edit| { - let make = SyntaxFactory::without_mappings(); + let editor = edit.make_editor(tt.syntax()); + let make = editor.make(); // Extract existing arguments in macro let mut raw_tokens = tt.token_trees_and_tokens().skip(1).collect_vec(); let format_string_index = format_str_index(&raw_tokens, &fmt_string); @@ -110,7 +111,7 @@ pub(crate) fn extract_expressions_from_format_string( Arg::Expr(s) => { // insert arg let expr = ast::Expr::parse(&s, ctx.edition()).syntax_node(); - let mut expr_tt = utils::tt_from_syntax(expr, &make); + let mut expr_tt = utils::tt_from_syntax(expr, make); new_tt_bits.append(&mut expr_tt); } Arg::Placeholder => { @@ -131,7 +132,6 @@ pub(crate) fn extract_expressions_from_format_string( // Insert new args let new_tt = make.token_tree(tt_delimiter, new_tt_bits); - let mut editor = edit.make_editor(tt.syntax()); editor.replace(tt.syntax(), new_tt.syntax()); if let Some(cap) = ctx.config.snippet_cap { @@ -158,7 +158,6 @@ pub(crate) fn extract_expressions_from_format_string( editor.add_annotation(literal, annotation); } } - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index 3bbf9a0ad3a2..3272fa739fe6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -60,8 +60,8 @@ pub(crate) fn extract_struct_from_enum_variant( "Extract struct from enum variant", target, |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(variant.syntax()); + let editor = builder.make_editor(variant.syntax()); + let make = editor.make(); let edition = enum_hir.krate(ctx.db()).edition(ctx.db()); let variant_hir_name = variant_hir.name(ctx.db()); let enum_module_def = ModuleDef::from(enum_hir); @@ -87,7 +87,7 @@ pub(crate) fn extract_struct_from_enum_variant( if processed.is_empty() { continue; } - let mut file_editor = builder.make_editor(processed[0].0.syntax()); + let file_editor = builder.make_editor(processed[0].0.syntax()); processed.into_iter().for_each(|(path, node, import)| { apply_references( ctx.config.insert_use, @@ -95,11 +95,9 @@ pub(crate) fn extract_struct_from_enum_variant( node, import, edition, - &mut file_editor, - &make, + &file_editor, ) }); - file_editor.add_mappings(make.take()); builder.add_file_edits(file_id.file_id(ctx.db()), file_editor); } @@ -112,20 +110,12 @@ pub(crate) fn extract_struct_from_enum_variant( references, ); processed.into_iter().for_each(|(path, node, import)| { - apply_references( - ctx.config.insert_use, - path, - node, - import, - edition, - &mut editor, - &make, - ) + apply_references(ctx.config.insert_use, path, node, import, edition, &editor) }); } let generic_params = enum_ast.generic_param_list().and_then(|known_generics| { - extract_generic_params(&make, &known_generics, &field_list) + extract_generic_params(make, &known_generics, &field_list) }); // resolve GenericArg in field_list to actual type @@ -148,13 +138,13 @@ pub(crate) fn extract_struct_from_enum_variant( }; let (comments_for_struct, comments_to_delete) = - collect_variant_comments(&make, variant.syntax()); + collect_variant_comments(make, variant.syntax()); for element in &comments_to_delete { editor.delete(element.clone()); } let def = create_struct_def( - &make, + make, variant_name.clone(), &field_list, generic_params.clone(), @@ -173,15 +163,10 @@ pub(crate) fn extract_struct_from_enum_variant( insert_items.extend(comments_for_struct); insert_items.push(def.syntax().clone().into()); insert_items.push(make.whitespace(&format!("\n\n{indent}")).into()); - editor.insert_all_with_whitespace( - Position::before(enum_ast.syntax()), - insert_items, - &make, - ); + editor.insert_all_with_whitespace(Position::before(enum_ast.syntax()), insert_items); - update_variant(&make, &mut editor, &variant, generic_params); + update_variant(&editor, &variant, generic_params); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -340,11 +325,11 @@ fn create_struct_def( } fn update_variant( - make: &SyntaxFactory, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, variant: &ast::Variant, generics: Option, ) -> Option<()> { + let make = editor.make(); let name = variant.name()?; let generic_args = generics .filter(|generics| generics.generic_params().count() > 0) @@ -407,17 +392,11 @@ fn apply_references( node: SyntaxNode, import: Option<(ImportScope, hir::ModPath)>, edition: Edition, - editor: &mut SyntaxEditor, - make: &SyntaxFactory, + editor: &SyntaxEditor, ) { + let make = editor.make(); if let Some((scope, path)) = import { - insert_use_with_editor( - &scope, - mod_path_to_ast(&path, edition), - &insert_use_cfg, - editor, - make, - ); + insert_use_with_editor(&scope, mod_path_to_ast(&path, edition), &insert_use_cfg, editor); } // deep clone to prevent cycle let path = make.path_from_segments(iter::once(segment.clone()), false); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs index e4fdac27f47f..23573dc3388d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs @@ -2,10 +2,7 @@ use hir::HirDisplay; use ide_db::syntax_helpers::node_ext::walk_ty; use syntax::{ - ast::{ - self, AstNode, HasGenericArgs, HasGenericParams, HasName, edit::IndentLevel, - syntax_factory::SyntaxFactory, - }, + ast::{self, AstNode, HasGenericArgs, HasGenericParams, HasName, edit::IndentLevel}, syntax_editor, }; @@ -56,8 +53,8 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> "Extract type as type alias", target, |builder| { - let mut edit = builder.make_editor(node); - let make = SyntaxFactory::without_mappings(); + let editor = builder.make_editor(node); + let make = editor.make(); let resolved_ty = make.ty(&resolved_ty); @@ -82,7 +79,7 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> } else { make.path_segment(make.name_ref("Type")) }; - edit.replace(ty.syntax(), new_ty.syntax()); + editor.replace(ty.syntax(), new_ty.syntax()); // Insert new alias let ty_alias = @@ -91,11 +88,11 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> if let Some(cap) = ctx.config.snippet_cap && let Some(name) = ty_alias.name() { - edit.add_annotation(name.syntax(), builder.make_tabstop_before(cap)); + editor.add_annotation(name.syntax(), builder.make_tabstop_before(cap)); } let indent = IndentLevel::from_node(node); - edit.insert_all( + editor.insert_all( syntax_editor::Position::before(node), vec![ ty_alias.syntax().clone().into(), @@ -103,7 +100,7 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> ], ); - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index 732bab4ceca4..c5c57c76b47c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -9,7 +9,6 @@ ast::{ self, AstNode, edit::{AstNodeEdit, IndentLevel}, - syntax_factory::SyntaxFactory, }, syntax_editor::{Element, Position}, }; @@ -206,8 +205,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op to_replace.clone() }; - let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(&place); + let editor = edit.make_editor(&place); + let make = editor.make(); let pat_name = make.name(&var_name); let name_expr = make.expr_path(make.ident_path(&var_name)); @@ -292,13 +291,11 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op make.block_expr([new_stmt], Some(to_wrap.clone())) } // fixup indentation of block - .indent_with_mapping(indent_to, &make); + .indent_with_mapping(indent_to, make); editor.replace(to_wrap.syntax(), block.syntax()); } } - - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); edit.rename(); }, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs index 440f2d5f17ca..d8714dd49c2d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs @@ -78,7 +78,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) }; acc.add(AssistId::quick_fix("fix_visibility"), assist_label, target, |builder| { - let mut editor = builder.make_editor(vis_owner.syntax()); + let editor = builder.make_editor(vis_owner.syntax()); if let Some(current_visibility) = vis_owner.visibility() { editor.replace(current_visibility.syntax(), missing_visibility.syntax()); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs index 922a61bf3a85..17911150f5e7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_binexpr.rs @@ -1,6 +1,6 @@ use syntax::{ SyntaxKind, T, - ast::{self, AstNode, BinExpr, RangeItem, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, BinExpr, RangeItem}, syntax_editor::Position, }; @@ -48,14 +48,13 @@ pub(crate) fn flip_binexpr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option "Flip binary expression", op_token.text_range(), |builder| { - let mut editor = builder.make_editor(&expr.syntax().parent().unwrap()); - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(&expr.syntax().parent().unwrap()); + let make = editor.make(); if let FlipAction::FlipAndReplaceOp(binary_op) = action { editor.replace(op_token, make.token(binary_op)) }; editor.replace(lhs.syntax(), rhs.syntax()); editor.replace(rhs.syntax(), lhs.syntax()); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -133,25 +132,25 @@ pub(crate) fn flip_range_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt "Flip range expression", op.text_range(), |builder| { - let mut edit = builder.make_editor(range_expr.syntax()); + let editor = builder.make_editor(range_expr.syntax()); match (start, end) { (Some(start), Some(end)) => { - edit.replace(start.syntax(), end.syntax()); - edit.replace(end.syntax(), start.syntax()); + editor.replace(start.syntax(), end.syntax()); + editor.replace(end.syntax(), start.syntax()); } (Some(start), None) => { - edit.delete(start.syntax()); - edit.insert(Position::after(&op), start.syntax()); + editor.delete(start.syntax()); + editor.insert(Position::after(&op), start.syntax()); } (None, Some(end)) => { - edit.delete(end.syntax()); - edit.insert(Position::before(&op), end.syntax()); + editor.delete(end.syntax()); + editor.insert(Position::before(&op), end.syntax()); } (None, None) => (), } - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs index 1e95d4772349..65dc36cdca7e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs @@ -2,7 +2,6 @@ AstNode, Direction, NodeOrToken, SyntaxKind, SyntaxToken, T, algo::non_trivia_sibling, ast::{self, syntax_factory::SyntaxFactory}, - syntax_editor::SyntaxMapping, }; use crate::{AssistContext, AssistId, Assists}; @@ -42,14 +41,13 @@ pub(crate) fn flip_comma(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( let target = comma.text_range(); acc.add(AssistId::refactor_rewrite("flip_comma"), "Flip comma", target, |builder| { let parent = comma.parent().unwrap(); - let mut editor = builder.make_editor(&parent); + let editor = builder.make_editor(&parent); if let Some(parent) = ast::TokenTree::cast(parent) { // An attribute. It often contains a path followed by a // token tree (e.g. `align(2)`), so we have to be smarter. - let (new_tree, mapping) = flip_tree(parent.clone(), comma); + let new_tree = flip_tree(parent.clone(), comma, editor.make()); editor.replace(parent.syntax(), new_tree.syntax()); - editor.add_mappings(mapping); } else { editor.replace(prev.clone(), next.clone()); editor.replace(next.clone(), prev.clone()); @@ -59,7 +57,7 @@ pub(crate) fn flip_comma(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( }) } -fn flip_tree(tree: ast::TokenTree, comma: SyntaxToken) -> (ast::TokenTree, SyntaxMapping) { +fn flip_tree(tree: ast::TokenTree, comma: SyntaxToken, make: &SyntaxFactory) -> ast::TokenTree { let mut tree_iter = tree.token_trees_and_tokens(); let before: Vec<_> = tree_iter.by_ref().take_while(|it| it.as_token() != Some(&comma)).collect(); @@ -100,10 +98,7 @@ fn flip_tree(tree: ast::TokenTree, comma: SyntaxToken) -> (ast::TokenTree, Synta &after[next_end..after.len() - 1], ] .concat(); - - let make = SyntaxFactory::with_mappings(); - let new_token_tree = make.token_tree(tree.left_delimiter_token().unwrap().kind(), result); - (new_token_tree, make.finish_with_mappings()) + make.token_tree(tree.left_delimiter_token().unwrap().kind(), result) } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs index 4829f5bec206..bd56331f4128 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs @@ -32,7 +32,7 @@ pub(crate) fn flip_or_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt let target = pipe.text_range(); acc.add(AssistId::refactor_rewrite("flip_or_pattern"), "Flip patterns", target, |builder| { - let mut editor = builder.make_editor(parent.syntax()); + let editor = builder.make_editor(parent.syntax()); editor.replace(before.clone(), after.clone()); editor.replace(after, before); builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs index 9756268c7cc3..dfd280efa630 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs @@ -33,7 +33,7 @@ pub(crate) fn flip_trait_bound(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op "Flip trait bounds", target, |builder| { - let mut editor = builder.make_editor(parent.syntax()); + let editor = builder.make_editor(parent.syntax()); editor.replace(before.clone(), after.clone()); editor.replace(after, before); builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs index 7a097e1866ef..0bb90f187c68 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs @@ -73,19 +73,19 @@ pub(crate) fn generate_blanket_trait_impl( "Generate blanket trait implementation", name.syntax().text_range(), |builder| { - let mut editor = builder.make_editor(traitd.syntax()); - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(traitd.syntax()); + let make = editor.make(); let namety = make.ty_path(make.path_from_text(&name.text())); let trait_where_clause = traitd.where_clause().map(|it| it.reset_indent()); - let bounds = traitd.type_bound_list().and_then(|list| exclude_sized(&make, list)); + let bounds = traitd.type_bound_list().and_then(|list| exclude_sized(make, list)); let is_unsafe = traitd.unsafe_token().is_some(); - let thisname = this_name(&make, &traitd); + let thisname = this_name(make, &traitd); let thisty = make.ty_path(make.path_from_text(&thisname.text())); let indent = traitd.indent_level(); let gendecl = make.generic_param_list([GenericParam::TypeParam(make.type_param( thisname.clone(), - apply_sized(&make, has_sized(&traitd, &ctx.sema), bounds), + apply_sized(make, has_sized(&traitd, &ctx.sema), bounds), ))]); let trait_gen_args = @@ -107,12 +107,11 @@ pub(crate) fn generate_blanket_trait_impl( ); if let Some(trait_assoc_list) = traitd.assoc_item_list() { - let assoc_item_list = - impl_.get_or_create_assoc_item_list_with_editor(&mut editor, &make); + let assoc_item_list = impl_.get_or_create_assoc_item_list_with_editor(&editor); for item in trait_assoc_list.assoc_items() { let item = match item { ast::AssocItem::Fn(method) if method.body().is_none() => { - todo_fn(&make, &method, ctx.config).into() + todo_fn(make, &method, ctx.config).into() } ast::AssocItem::Const(_) | ast::AssocItem::TypeAlias(_) => item, _ => continue, @@ -136,8 +135,6 @@ pub(crate) fn generate_blanket_trait_impl( { builder.add_tabstop_before(cap, self_ty); } - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs index 2d92bf514622..739b63173694 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs @@ -73,12 +73,12 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext<' "Generate a Default impl from a new fn", target, move |builder| { - let make = SyntaxFactory::without_mappings(); - let default_impl = generate_default_impl(&make, &impl_, self_ty); + let editor = builder.make_editor(impl_.syntax()); + let make = editor.make(); + let default_impl = generate_default_impl(make, &impl_, self_ty); let indent = IndentLevel::from_node(impl_.syntax()); let default_impl = default_impl.indent(indent); - let mut editor = builder.make_editor(impl_.syntax()); editor.insert_all( Position::after(impl_.syntax()), vec![ diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs index 63033c7d5e39..d63ef33debec 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs @@ -4,7 +4,6 @@ ast::{ self, AstNode, HasGenericParams, HasName, HasVisibility as _, edit::{AstNodeEdit, IndentLevel}, - syntax_factory::SyntaxFactory, }, syntax_editor::Position, }; @@ -107,8 +106,10 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' format!("Generate delegate for `{field_name}.{name}()`",), target, |edit| { - let make = SyntaxFactory::without_mappings(); - let field = make + let editor = edit.make_editor(strukt.syntax()); + let make = editor.make(); + let field = editor + .make() .field_from_idents(["self", &field_name]) .expect("always be a valid expression"); // Create the function @@ -145,17 +146,19 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' // compute the `body` let arg_list = method_source .param_list() - .map(|v| convert_param_list_to_arg_list(v, &make)) + .map(|v| convert_param_list_to_arg_list(v, make)) .unwrap_or_else(|| make.arg_list([])); - let tail_expr = make.expr_method_call(field, make.name_ref(&name), arg_list).into(); + let tail_expr = + editor.make().expr_method_call(field, make.name_ref(&name), arg_list).into(); let tail_expr_finished = if is_async { make.expr_await(tail_expr).into() } else { tail_expr }; let body = make.block_expr([], Some(tail_expr_finished)); let ret_type = method_source.ret_type(); - let f = make + let f = editor + .make() .fn_( None, vis, @@ -173,12 +176,11 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' .indent(IndentLevel(1)); let item = ast::AssocItem::Fn(f.clone()); - let mut editor = edit.make_editor(strukt.syntax()); let fn_: Option = match impl_def { Some(impl_def) => match impl_def.assoc_item_list() { Some(assoc_item_list) => { let item = item.indent(IndentLevel::from_node(impl_def.syntax())); - assoc_item_list.add_items(&mut editor, vec![item.clone()]); + assoc_item_list.add_items(&editor, vec![item.clone()]); Some(item) } None => { @@ -229,7 +231,6 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' let tabstop = edit.make_tabstop_before(cap); editor.add_annotation(fn_.syntax(), tabstop); } - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, )?; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs index abe447d9d9b7..6639f10c1f36 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -494,7 +494,7 @@ fn remove_instantiated_params( } } -fn remove_useless_where_clauses(editor: &mut SyntaxEditor, delegate: &ast::Impl) { +fn remove_useless_where_clauses(editor: &SyntaxEditor, delegate: &ast::Impl) { let Some(wc) = delegate.where_clause() else { return; }; @@ -563,7 +563,7 @@ fn finalize_delegate( return Some(delegate.clone()); } - let (mut editor, delegate) = SyntaxEditor::with_ast_node(delegate); + let (editor, delegate) = SyntaxEditor::with_ast_node(delegate); // 1. Replace assoc_item_list if we have new items if let Some(items) = assoc_items @@ -577,7 +577,7 @@ fn finalize_delegate( // 2. Remove useless where clauses if remove_where_clauses { - remove_useless_where_clauses(&mut editor, &delegate); + remove_useless_where_clauses(&editor, &delegate); } ast::Impl::cast(editor.finish().new_root().clone()) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs index 5534dc1cd304..89666dc80476 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs @@ -2,7 +2,7 @@ use ide_db::{FileId, RootDatabase, famous_defs::FamousDefs}; use syntax::{ Edition, - ast::{self, AstNode, HasName, edit::AstNodeEdit, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, HasName, edit::AstNodeEdit}, syntax_editor::Position, }; @@ -138,7 +138,8 @@ fn generate_edit( trait_path: ModPath, edition: Edition, ) { - let make = SyntaxFactory::with_mappings(); + let editor = edit.make_editor(strukt.syntax()); + let make = editor.make(); let strukt_adt = ast::Adt::Struct(strukt.clone()); let trait_ty = make.ty(&trait_path.display(db, edition).to_string()); @@ -150,7 +151,8 @@ fn generate_edit( make.ty_ref(make.ty_path(make.path_from_text("Self::Target")).into(), false); let field_expr = make.expr_field(make.expr_path(make.ident_path("self")), field_name); let body = make.block_expr([], Some(make.expr_ref(field_expr.into(), false))); - let fn_ = make + let fn_ = editor + .make() .fn_( [], None, @@ -173,7 +175,8 @@ fn generate_edit( make.ty_ref(make.ty_path(make.path_from_text("Self::Target")).into(), true); let field_expr = make.expr_field(make.expr_path(make.ident_path("self")), field_name); let body = make.block_expr([], Some(make.expr_ref(field_expr.into(), true))); - let fn_ = make + let fn_ = editor + .make() .fn_( [], None, @@ -195,15 +198,12 @@ fn generate_edit( let body = make.assoc_item_list(assoc_items); let indent = strukt.indent_level(); - let impl_ = generate_trait_impl_intransitive_with_item(&make, &strukt_adt, trait_ty, body) + let impl_ = generate_trait_impl_intransitive_with_item(make, &strukt_adt, trait_ty, body) .indent(indent); - - let mut editor = edit.make_editor(strukt.syntax()); editor.insert_all( Position::after(strukt.syntax()), vec![make.whitespace(&format!("\n\n{indent}")).into(), impl_.syntax().clone().into()], ); - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(file_id, editor); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs index 7aeb5e339696..0129b1db396b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs @@ -1,7 +1,7 @@ use syntax::{ SyntaxKind::{ATTR, COMMENT, WHITESPACE}, T, - ast::{self, AstNode, HasAttrs, edit::IndentLevel, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, HasAttrs, edit::IndentLevel}, syntax_editor::{Element, Position}, }; @@ -42,17 +42,15 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt }; acc.add(AssistId::generate("generate_derive"), "Add `#[derive]`", target, |edit| { - let make = SyntaxFactory::without_mappings(); - match derive_attr { None => { + let editor = edit.make_editor(nominal.syntax()); + let make = editor.make(); let derive = make.attr_outer(make.meta_token_tree( make.ident_path("derive"), make.token_tree(T!['('], vec![]), )); - - let mut editor = edit.make_editor(nominal.syntax()); let indent = IndentLevel::from_node(nominal.syntax()); let after_attrs_and_comments = nominal .syntax() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs index 3514ebb811ee..9b4d44d8b517 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs @@ -59,12 +59,12 @@ pub(crate) fn generate_enum_variant(acc: &mut Assists, ctx: &AssistContext<'_>) let InRealFile { file_id, value: enum_node } = e.source(db)?.original_ast_node_rooted(db)?; acc.add(AssistId::generate("generate_enum_variant"), "Generate variant", target, |builder| { - let mut editor = builder.make_editor(enum_node.syntax()); - let make = SyntaxFactory::with_mappings(); - let field_list = parent.make_field_list(ctx, &make); + let editor = builder.make_editor(enum_node.syntax()); + let make = editor.make(); + let field_list = parent.make_field_list(ctx, make); let variant = make.variant(None, make.name(&name_ref.text()), field_list, None); if let Some(it) = enum_node.variant_list() { - it.add_variant(&mut editor, &variant); + it.add_variant(&editor, &variant); } builder.add_file_edits(file_id.file_id(ctx.db()), editor); }) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs index 6bcbd9b0ccc2..55e508381134 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs @@ -2,7 +2,7 @@ use ide_db::assists::{AssistId, GroupLabel}; use syntax::{ AstNode, - ast::{self, HasGenericParams, HasName, edit::IndentLevel, syntax_factory::SyntaxFactory}, + ast::{self, HasGenericParams, HasName, edit::IndentLevel}, syntax_editor, }; @@ -55,9 +55,8 @@ pub(crate) fn generate_fn_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) style.label(), func_node.syntax().text_range(), |builder| { - let mut edit = builder.make_editor(func); - let make = SyntaxFactory::without_mappings(); - + let editor = builder.make_editor(func); + let make = editor.make(); let alias_name = format!("{}Fn", stdx::to_camel_case(&name.to_string())); let mut fn_params_vec = Vec::new(); @@ -104,7 +103,7 @@ pub(crate) fn generate_fn_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ); let indent = IndentLevel::from_node(insertion_node); - edit.insert_all( + editor.insert_all( syntax_editor::Position::before(insertion_node), vec![ ty_alias.syntax().clone().into(), @@ -115,10 +114,10 @@ pub(crate) fn generate_fn_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) if let Some(cap) = ctx.config.snippet_cap && let Some(name) = ty_alias.name() { - edit.add_annotation(name.syntax(), builder.make_placeholder_snippet(cap)); + editor.add_annotation(name.syntax(), builder.make_placeholder_snippet(cap)); } - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs index 1adb3f4fe49a..76246c3e8efd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs @@ -40,19 +40,18 @@ pub(crate) fn generate_from_impl_for_enum( "Generate `From` impl for this enum variant(s)", target, |edit| { - let make = SyntaxFactory::with_mappings(); + let editor = edit.make_editor(adt.syntax()); + let make = editor.make(); let indent = adt.indent_level(); let mut elements = Vec::new(); for variant_info in variants { - let impl_ = build_from_impl(&make, &adt, variant_info).indent(indent); + let impl_ = build_from_impl(make, &adt, variant_info).indent(indent); elements.push(make.whitespace(&format!("\n\n{indent}")).into()); elements.push(impl_.syntax().clone().into()); } - let mut editor = edit.make_editor(adt.syntax()); editor.insert_all(Position::after(adt.syntax()), elements); - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(file_id, editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs index 4cd018d02d02..d9719aaaf289 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs @@ -410,35 +410,37 @@ fn parse_record_field( Some(RecordFieldInfo { field_name, field_ty, fn_name, target }) } +fn items( + ctx: &AssistContext<'_>, + info_of_record_fields: Vec, + assist_info: &AssistInfo, + make: &SyntaxFactory, +) -> Vec { + info_of_record_fields + .iter() + .map(|record_field_info| { + let method = match assist_info.assist_type { + AssistType::Set => generate_setter_from_info(assist_info, record_field_info, make), + _ => generate_getter_from_info(ctx, assist_info, record_field_info, make), + }; + let new_fn = method; + let new_fn = new_fn.indent(1.into()); + new_fn.into() + }) + .collect() +} + fn build_source_change( builder: &mut SourceChangeBuilder, ctx: &AssistContext<'_>, info_of_record_fields: Vec, assist_info: AssistInfo, ) { - let syntax_factory = SyntaxFactory::without_mappings(); - - let items: Vec = info_of_record_fields - .iter() - .map(|record_field_info| { - let method = match assist_info.assist_type { - AssistType::Set => { - generate_setter_from_info(&assist_info, record_field_info, &syntax_factory) - } - _ => { - generate_getter_from_info(ctx, &assist_info, record_field_info, &syntax_factory) - } - }; - let new_fn = method; - let new_fn = new_fn.indent(1.into()); - new_fn.into() - }) - .collect(); - if let Some(impl_def) = &assist_info.impl_def { // We have an existing impl to add to - let mut editor = builder.make_editor(impl_def.syntax()); - impl_def.assoc_item_list().unwrap().add_items(&mut editor, items.clone()); + let editor = builder.make_editor(impl_def.syntax()); + let items = items(ctx, info_of_record_fields, &assist_info, editor.make()); + impl_def.assoc_item_list().unwrap().add_items(&editor, items.clone()); if let Some(cap) = ctx.config.snippet_cap && let Some(ast::AssocItem::Fn(fn_)) = items.last() @@ -451,22 +453,26 @@ fn build_source_change( builder.add_file_edits(ctx.vfs_file_id(), editor); return; } + + let editor = builder.make_editor(assist_info.strukt.syntax()); + let make = editor.make(); + let items = items(ctx, info_of_record_fields, &assist_info, make); let ty_params = assist_info.strukt.generic_param_list(); let ty_args = ty_params.as_ref().map(|it| it.to_generic_args()); - let impl_def = syntax_factory.impl_( + let impl_def = make.impl_( None, ty_params, ty_args, - syntax_factory - .ty_path(syntax_factory.ident_path(&assist_info.strukt.name().unwrap().to_string())) + editor + .make() + .ty_path(make.ident_path(&assist_info.strukt.name().unwrap().to_string())) .into(), None, - Some(syntax_factory.assoc_item_list(items)), + Some(make.assoc_item_list(items)), ); - let mut editor = builder.make_editor(assist_info.strukt.syntax()); editor.insert_all( Position::after(assist_info.strukt.syntax()), - vec![syntax_factory.whitespace("\n\n").into(), impl_def.syntax().clone().into()], + vec![make.whitespace("\n\n").into(), impl_def.syntax().clone().into()], ); if let Some(cap) = ctx.config.snippet_cap diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs index af123eeaa0ce..e0f01b58c2c2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs @@ -1,7 +1,5 @@ use syntax::{ - ast::{ - self, AstNode, HasGenericParams, HasName, edit::AstNodeEdit, syntax_factory::SyntaxFactory, - }, + ast::{self, AstNode, HasGenericParams, HasName, edit::AstNodeEdit}, syntax_editor::{Position, SyntaxEditor}, }; @@ -13,12 +11,8 @@ }, }; -fn insert_impl( - editor: &mut SyntaxEditor, - make: &SyntaxFactory, - impl_: &ast::Impl, - nominal: &impl AstNodeEdit, -) -> ast::Impl { +fn insert_impl(editor: &SyntaxEditor, impl_: &ast::Impl, nominal: &impl AstNodeEdit) -> ast::Impl { + let make = editor.make(); let indent = nominal.indent_level(); let impl_ = impl_.indent(indent); @@ -65,13 +59,11 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio format!("Generate impl for `{name}`"), target, |edit| { - let make = SyntaxFactory::with_mappings(); - // Generate the impl - let impl_ = generate_impl_with_factory(&make, &nominal); + let editor = edit.make_editor(nominal.syntax()); + let make = editor.make(); + let impl_ = generate_impl_with_factory(make, &nominal); - let mut editor = edit.make_editor(nominal.syntax()); - - let impl_ = insert_impl(&mut editor, &make, &impl_, &nominal); + let impl_ = insert_impl(&editor, &impl_, &nominal); // Add a tabstop after the left curly brace if let Some(cap) = ctx.config.snippet_cap && let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) @@ -79,8 +71,6 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio let tabstop = edit.make_tabstop_after(cap); editor.add_annotation(l_curly, tabstop); } - - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -117,13 +107,10 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> format!("Generate trait impl for `{name}`"), target, |edit| { - let make = SyntaxFactory::with_mappings(); - // Generate the impl - let impl_ = generate_trait_impl_intransitive(&make, &nominal, make.ty_placeholder()); - - let mut editor = edit.make_editor(nominal.syntax()); - - let impl_ = insert_impl(&mut editor, &make, &impl_, &nominal); + let editor = edit.make_editor(nominal.syntax()); + let make = editor.make(); + let impl_ = generate_trait_impl_intransitive(make, &nominal, make.ty_placeholder()); + let impl_ = insert_impl(&editor, &impl_, &nominal); // Make the trait type a placeholder snippet if let Some(cap) = ctx.config.snippet_cap { if let Some(trait_) = impl_.trait_() { @@ -136,8 +123,6 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> editor.add_annotation(l_curly, tabstop); } } - - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -176,8 +161,8 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> format!("Generate `{name}` impl for type"), target, |edit| { - let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(trait_.syntax()); + let editor = edit.make_editor(trait_.syntax()); + let make = editor.make(); let holder_arg = ast::GenericArg::TypeArg(make.type_arg(make.ty_placeholder())); let missing_items = utils::filter_assoc_items( @@ -188,7 +173,9 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> ); let trait_gen_args = trait_.generic_param_list().map(|list| { - make.generic_arg_list(list.generic_params().map(|_| holder_arg.clone()), false) + editor + .make() + .generic_arg_list(list.generic_params().map(|_| holder_arg.clone()), false) }); let make_impl_ = |body| { @@ -213,7 +200,7 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> } else { let impl_ = make_impl_(None); let assoc_items = add_trait_assoc_items_to_impl( - &make, + make, &ctx.sema, ctx.config, &missing_items, @@ -225,8 +212,7 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> make_impl_(Some(assoc_item_list)) }; - let impl_ = insert_impl(&mut editor, &make, &impl_, &trait_); - editor.add_mappings(make.finish_with_mappings()); + let impl_ = insert_impl(&editor, &impl_, &trait_); if let Some(cap) = ctx.config.snippet_cap { if let Some(generics) = impl_.trait_().and_then(|it| it.generic_arg_list()) { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs index 31e49c8ce48e..acf0819222d5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs @@ -67,10 +67,9 @@ pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_> format!("Generate `{trait_new}` impl from this `{trait_name}` trait"), target, |edit| { - let (mut editor, impl_clone) = SyntaxEditor::with_ast_node(&impl_def.reset_indent()); - let factory = SyntaxFactory::without_mappings(); + let (editor, impl_clone) = SyntaxEditor::with_ast_node(&impl_def.reset_indent()); - apply_generate_mut_impl(&mut editor, &factory, &impl_clone, trait_new); + apply_generate_mut_impl(&editor, &impl_clone, trait_new); let new_root = editor.finish(); let new_root = new_root.new_root(); @@ -79,12 +78,13 @@ pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_> let new_impl = new_impl.indent(indent); - let mut editor = edit.make_editor(impl_def.syntax()); + let editor = edit.make_editor(impl_def.syntax()); + let make = editor.make(); editor.insert_all( Position::before(impl_def.syntax()), vec![ new_impl.syntax().syntax_element(), - factory.whitespace(&format!("\n\n{indent}")).syntax_element(), + make.whitespace(&format!("\n\n{indent}")).syntax_element(), ], ); @@ -98,7 +98,7 @@ pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_> ) } -fn delete_with_trivia(editor: &mut SyntaxEditor, node: &SyntaxNode) { +fn delete_with_trivia(editor: &SyntaxEditor, node: &SyntaxNode) { let mut end: SyntaxElement = node.clone().into(); if let Some(next) = node.next_sibling_or_token() @@ -112,23 +112,23 @@ fn delete_with_trivia(editor: &mut SyntaxEditor, node: &SyntaxNode) { } fn apply_generate_mut_impl( - editor: &mut SyntaxEditor, - factory: &SyntaxFactory, + editor: &SyntaxEditor, impl_def: &ast::Impl, trait_new: &str, ) -> Option<()> { + let make = editor.make(); let path = impl_def.trait_().and_then(|t| t.syntax().descendants().find_map(ast::Path::cast))?; let seg = path.segment()?; let name_ref = seg.name_ref()?; - let new_name_ref = factory.name_ref(trait_new); + let new_name_ref = make.name_ref(trait_new); editor.replace(name_ref.syntax(), new_name_ref.syntax()); if let Some((name, new_name)) = impl_def.syntax().descendants().filter_map(ast::Name::cast).find_map(process_method_name) { - let new_name_node = factory.name(new_name); + let new_name_node = make.name(new_name); editor.replace(name.syntax(), new_name_node.syntax()); } @@ -137,14 +137,14 @@ fn apply_generate_mut_impl( } if let Some(self_param) = impl_def.syntax().descendants().find_map(ast::SelfParam::cast) { - let mut_self = factory.mut_self_param(); + let mut_self = make.mut_self_param(); editor.replace(self_param.syntax(), mut_self.syntax()); } if let Some(ret_type) = impl_def.syntax().descendants().find_map(ast::RetType::cast) - && let Some(new_ty) = process_ret_type(factory, &ret_type) + && let Some(new_ty) = process_ret_type(make, &ret_type) { - let new_ret = factory.ret_type(new_ty); + let new_ret = make.ret_type(new_ty); editor.replace(ret_type.syntax(), new_ret.syntax()) } @@ -154,13 +154,14 @@ fn apply_generate_mut_impl( _ => None, }) }) { - process_ref_mut(editor, factory, &fn_); + process_ref_mut(editor, &fn_); } Some(()) } -fn process_ref_mut(editor: &mut SyntaxEditor, factory: &SyntaxFactory, fn_: &ast::Fn) { +fn process_ref_mut(editor: &SyntaxEditor, fn_: &ast::Fn) { + let make = editor.make(); let Some(expr) = fn_.body().and_then(|b| b.tail_expr()) else { return }; let ast::Expr::RefExpr(ref_expr) = expr else { return }; @@ -171,8 +172,8 @@ fn process_ref_mut(editor: &mut SyntaxEditor, factory: &SyntaxFactory, fn_: &ast let Some(amp) = ref_expr.amp_token() else { return }; - let mut_kw = factory.token(T![mut]); - let space = factory.whitespace(" "); + let mut_kw = make.token(T![mut]); + let space = make.whitespace(" "); editor.insert(Position::after(amp.clone()), space.syntax_element()); editor.insert(Position::after(amp), mut_kw.syntax_element()); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs index 301d13c09584..ea6f0186d18b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs @@ -3,10 +3,7 @@ use_trivial_constructor::use_trivial_constructor, }; use syntax::{ - ast::{ - self, AstNode, HasName, HasVisibility, StructKind, edit::AstNodeEdit, - syntax_factory::SyntaxFactory, - }, + ast::{self, AstNode, HasName, HasVisibility, StructKind, edit::AstNodeEdit}, syntax_editor::Position, }; @@ -38,11 +35,9 @@ // ``` pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let strukt = ctx.find_node_at_offset::()?; - - let make = SyntaxFactory::without_mappings(); - let field_list = match strukt.kind() { + let field_list: Vec<(String, ast::Type)> = match strukt.kind() { StructKind::Record(named) => { - named.fields().filter_map(|f| Some((f.name()?, f.ty()?))).collect::>() + named.fields().filter_map(|f| Some((f.name()?.to_string(), f.ty()?))).collect() } StructKind::Tuple(tuple) => { let mut name_generator = NameGenerator::default(); @@ -56,12 +51,12 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option ctx.db(), ctx.edition(), ) { - Some(name) => name, - None => name_generator.suggest_name(&format!("_{i}")), + Some(name) => name.to_string(), + None => name_generator.suggest_name(&format!("_{i}")).to_string(), }; - Some((make.name(name.as_str()), f.ty()?)) + Some((name, ty)) }) - .collect::>() + .collect() } StructKind::Unit => return None, }; @@ -74,7 +69,9 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let target = strukt.syntax().text_range(); acc.add(AssistId::generate("generate_new"), "Generate `new`", target, |builder| { - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(strukt.syntax()); + let make = editor.make(); + let trivial_constructors = field_list .iter() .map(|(name, ty)| { @@ -100,13 +97,13 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option edition, )?; - Some((make.name_ref(&name.text()), Some(expr))) + Some((make.name_ref(name), Some(expr))) }) .collect::>(); let params = field_list.iter().enumerate().filter_map(|(i, (name, ty))| { if trivial_constructors[i].is_none() { - Some(make.param(make.ident_pat(false, false, name.clone()).into(), ty.clone())) + Some(make.param(make.ident_pat(false, false, make.name(name)).into(), ty.clone())) } else { None } @@ -117,7 +114,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option if let Some(constructor) = trivial_constructors[i].clone() { constructor } else { - (make.name_ref(&name.text()), None) + (make.name_ref(name), None) } }); @@ -141,7 +138,8 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let ret_type = make.ret_type(make.ty_path(make.ident_path("Self")).into()); - let fn_ = make + let fn_ = editor + .make() .fn_( [], strukt.visibility(), @@ -158,8 +156,6 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option ) .indent(1.into()); - let mut editor = builder.make_editor(strukt.syntax()); - // Get the node for set annotation let contain_fn = if let Some(impl_def) = impl_def { let fn_ = fn_.indent(impl_def.indent_level()); @@ -169,7 +165,10 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option editor.insert_all( Position::after(l_curly), vec![ - make.whitespace(&format!("\n{}", impl_def.indent_level() + 1)).into(), + editor + .make() + .whitespace(&format!("\n{}", impl_def.indent_level() + 1)) + .into(), fn_.syntax().clone().into(), make.whitespace("\n").into(), ], @@ -185,7 +184,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let indent_level = strukt.indent_level(); let list = make.assoc_item_list([ast::AssocItem::Fn(fn_)]); let impl_def = - generate_impl_with_item(&make, &ast::Adt::Struct(strukt.clone()), Some(list)) + generate_impl_with_item(make, &ast::Adt::Struct(strukt.clone()), Some(list)) .indent(strukt.indent_level()); // Insert it after the adt @@ -235,8 +234,6 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option editor.add_annotation(name.syntax(), tabstop_before); } } - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs index 7746cdc068a1..7160400a969c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs @@ -80,8 +80,8 @@ pub(crate) fn generate_single_field_struct_from( "Generate single field `From`", strukt.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(strukt.syntax()); + let editor = builder.make_editor(strukt.syntax()); + let make = editor.make(); let indent = strukt.indent_level(); let ty_where_clause = strukt.where_clause(); @@ -95,10 +95,11 @@ pub(crate) fn generate_single_field_struct_from( let ty = make.ty(&strukt_name.text()); let constructor = - make_adt_constructor(names.as_deref(), constructors, &main_field_name, &make); + make_adt_constructor(names.as_deref(), constructors, &main_field_name, make); let body = make.block_expr([], Some(constructor)); - let fn_ = make + let fn_ = editor + .make() .fn_( [], None, @@ -119,7 +120,7 @@ pub(crate) fn generate_single_field_struct_from( false, false, ) - .indent_with_mapping(1.into(), &make); + .indent_with_mapping(1.into(), make); let cfg_attrs = strukt.attrs().filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))); @@ -139,13 +140,12 @@ pub(crate) fn generate_single_field_struct_from( None, ); - let (mut impl_editor, impl_root) = SyntaxEditor::with_ast_node(&impl_); - let assoc_list = - impl_root.get_or_create_assoc_item_list_with_editor(&mut impl_editor, &make); - assoc_list.add_items(&mut impl_editor, vec![fn_.into()]); + let (impl_editor, impl_root) = SyntaxEditor::with_ast_node(&impl_); + let assoc_list = impl_root.get_or_create_assoc_item_list_with_editor(&impl_editor); + assoc_list.add_items(&impl_editor, vec![fn_.into()]); let impl_ = ast::Impl::cast(impl_editor.finish().new_root().clone()) .unwrap() - .indent_with_mapping(indent, &make); + .indent_with_mapping(indent, make); editor.insert_all( Position::after(strukt.syntax()), @@ -154,8 +154,6 @@ pub(crate) fn generate_single_field_struct_from( impl_.syntax().clone().into(), ], ); - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs index 2d3d05849b0b..f5342b8b702d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs @@ -4,7 +4,6 @@ AstNode, AstToken, SyntaxKind, T, ast::{ self, HasDocComments, HasGenericParams, HasName, HasVisibility, edit::AstNodeEdit, make, - syntax_factory::SyntaxFactory, }, syntax_editor::{Position, SyntaxEditor}, }; @@ -99,18 +98,19 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_ impl_ast.syntax().text_range(), |builder| { let trait_items: ast::AssocItemList = { - let (mut trait_items_editor, trait_items) = + let (trait_items_editor, trait_items) = SyntaxEditor::with_ast_node(&impl_assoc_items); trait_items.assoc_items().for_each(|item| { - strip_body(&mut trait_items_editor, &item); - remove_items_visibility(&mut trait_items_editor, &item); + strip_body(&trait_items_editor, &item); + remove_items_visibility(&trait_items_editor, &item); }); ast::AssocItemList::cast(trait_items_editor.finish().new_root().clone()).unwrap() }; - let factory = SyntaxFactory::with_mappings(); - let trait_ast = factory.trait_( + let editor = builder.make_editor(impl_ast.syntax()); + let make = editor.make(); + let trait_ast = make.trait_( false, &trait_name(&impl_assoc_items).text(), impl_ast.generic_param_list(), @@ -119,7 +119,7 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_ ); let trait_name = trait_ast.name().expect("new trait should have a name"); - let trait_name_ref = factory.name_ref(&trait_name.to_string()); + let trait_name_ref = make.name_ref(&trait_name.to_string()); // Change `impl Foo` to `impl NewTrait for Foo` let mut elements = vec![ @@ -134,10 +134,9 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_ elements.insert(1, gen_args.syntax().clone().into()); } - let mut editor = builder.make_editor(impl_ast.syntax()); impl_assoc_items.assoc_items().for_each(|item| { - remove_items_visibility(&mut editor, &item); - remove_doc_comments(&mut editor, &item); + remove_items_visibility(&editor, &item); + remove_doc_comments(&editor, &item); }); editor.insert_all(Position::before(impl_name.syntax()), elements); @@ -157,8 +156,6 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_ editor.add_annotation(trait_name.syntax(), placeholder); editor.add_annotation(trait_name_ref.syntax(), placeholder); } - - editor.add_mappings(factory.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); @@ -179,7 +176,7 @@ fn trait_name(items: &ast::AssocItemList) -> ast::Name { } /// `E0449` Trait items always share the visibility of their trait -fn remove_items_visibility(editor: &mut SyntaxEditor, item: &ast::AssocItem) { +fn remove_items_visibility(editor: &SyntaxEditor, item: &ast::AssocItem) { if let Some(has_vis) = ast::AnyHasVisibility::cast(item.syntax().clone()) { if let Some(vis) = has_vis.visibility() && let Some(token) = vis.syntax().next_sibling_or_token() @@ -193,7 +190,7 @@ fn remove_items_visibility(editor: &mut SyntaxEditor, item: &ast::AssocItem) { } } -fn remove_doc_comments(editor: &mut SyntaxEditor, item: &ast::AssocItem) { +fn remove_doc_comments(editor: &SyntaxEditor, item: &ast::AssocItem) { for doc in item.doc_comments() { if let Some(next) = doc.syntax().next_token() && next.kind() == SyntaxKind::WHITESPACE @@ -204,7 +201,7 @@ fn remove_doc_comments(editor: &mut SyntaxEditor, item: &ast::AssocItem) { } } -fn strip_body(editor: &mut SyntaxEditor, item: &ast::AssocItem) { +fn strip_body(editor: &SyntaxEditor, item: &ast::AssocItem) { if let ast::AssocItem::Fn(f) = item && let Some(body) = f.body() { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs index f55ef4229e58..ad539071561a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -7,7 +7,7 @@ }; use syntax::{ Direction, TextRange, - ast::{self, AstNode, AstToken, HasName, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, AstToken, HasName}, syntax_editor::{Element, SyntaxEditor}, }; @@ -83,7 +83,8 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) "Inline variable", target.text_range(), move |builder| { - let mut editor = builder.make_editor(&target); + let editor = builder.make_editor(&target); + let make = editor.make(); if delete_let { editor.delete(let_stmt.syntax()); @@ -91,15 +92,13 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) && let Some(op_token) = bin_expr.op_token() { editor.delete(&op_token); - remove_whitespace(op_token, Direction::Prev, &mut editor); - remove_whitespace(let_stmt.syntax(), Direction::Prev, &mut editor); + remove_whitespace(op_token, Direction::Prev, &editor); + remove_whitespace(let_stmt.syntax(), Direction::Prev, &editor); } else { - remove_whitespace(let_stmt.syntax(), Direction::Next, &mut editor); + remove_whitespace(let_stmt.syntax(), Direction::Next, &editor); } } - let make = SyntaxFactory::with_mappings(); - for (name, should_wrap) in wrap_in_parens { let replacement = if should_wrap { make.expr_paren(initializer_expr.clone()).into() @@ -115,8 +114,6 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) editor.replace(name.syntax(), replacement.syntax()); } } - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -204,7 +201,7 @@ fn inline_usage( Some(InlineData { let_stmt, delete_let, target: ast::NameOrNameRef::NameRef(name), references }) } -fn remove_whitespace(elem: impl Element, dir: Direction, editor: &mut SyntaxEditor) { +fn remove_whitespace(elem: impl Element, dir: Direction, editor: &SyntaxEditor) { let token = match elem.syntax_element() { syntax::NodeOrToken::Node(node) => match dir { Direction::Next => node.last_token(), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs index 4b60f0ac1e3c..6d8750afdcff 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -70,7 +70,7 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) let mut inline_refs_for_file = |file_id, refs: Vec| { let source = ctx.sema.parse(file_id); - let mut editor = builder.make_editor(source.syntax()); + let editor = builder.make_editor(source.syntax()); let (path_types, path_type_uses) = split_refs_and_uses(builder, refs, |path_type| { @@ -101,7 +101,7 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) inline_refs_for_file(file_id, refs); } if !definition_deleted { - let mut editor = builder.make_editor(ast_alias.syntax()); + let editor = builder.make_editor(ast_alias.syntax()); editor.delete(ast_alias.syntax()); builder.add_file_edits(ctx.vfs_file_id(), editor) } @@ -156,7 +156,7 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> O "Inline type alias", alias_instance.syntax().text_range(), |builder| { - let mut editor = builder.make_editor(alias_instance.syntax()); + let editor = builder.make_editor(alias_instance.syntax()); let replace = replacement.replace_generic(&concrete_type); editor.replace(alias_instance.syntax(), replace); builder.add_file_edits(ctx.vfs_file_id(), editor); @@ -312,8 +312,8 @@ fn create_replacement( const_and_type_map: &ConstAndTypeMap, concrete_type: &ast::Type, ) -> SyntaxNode { - let (mut editor, updated_concrete_type) = SyntaxEditor::new(concrete_type.syntax().clone()); - + let (editor, updated_concrete_type) = SyntaxEditor::new(concrete_type.syntax().clone()); + let make = editor.make(); let mut replacements: Vec<(SyntaxNode, SyntaxNode)> = Vec::new(); let mut removals: Vec> = Vec::new(); @@ -368,7 +368,6 @@ fn create_replacement( }; let new_string = replacement_syntax.to_string(); let new = if new_string == "_" { - let make = SyntaxFactory::without_mappings(); make.wildcard_pat().syntax().clone() } else { replacement_syntax.clone() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs index 5e8ea7daff90..2cbeae1d19c2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs @@ -1,7 +1,7 @@ use ide_db::{FileId, FxHashSet}; use syntax::{ AstNode, SmolStr, T, TextRange, ToSmolStr, - ast::{self, HasGenericParams, HasName, syntax_factory::SyntaxFactory}, + ast::{self, HasGenericParams, HasName}, format_smolstr, syntax_editor::{Element, Position, SyntaxEditor}, }; @@ -97,23 +97,23 @@ fn generate_fn_def_assist( }; acc.add(AssistId::refactor(ASSIST_NAME), ASSIST_LABEL, lifetime_loc, |edit| { - let mut editor = edit.make_editor(fn_def.syntax()); - let factory = SyntaxFactory::with_mappings(); + let editor = edit.make_editor(fn_def.syntax()); + let make = editor.make(); if let Some(generic_list) = fn_def.generic_param_list() { - insert_lifetime_param(&mut editor, &factory, &generic_list, &new_lifetime_name); + insert_lifetime_param(&editor, &generic_list, &new_lifetime_name); } else { - insert_new_generic_param_list_fn(&mut editor, &factory, &fn_def, &new_lifetime_name); + insert_new_generic_param_list_fn(&editor, &fn_def, &new_lifetime_name); } - editor.replace(lifetime.syntax(), factory.lifetime(&new_lifetime_name).syntax()); + editor.replace(lifetime.syntax(), make.lifetime(&new_lifetime_name).syntax()); if let Some(pos) = loc_needing_lifetime.and_then(|l| l.to_position()) { editor.insert_all( pos, vec![ - factory.lifetime(&new_lifetime_name).syntax().clone().into(), - factory.whitespace(" ").into(), + make.lifetime(&new_lifetime_name).syntax().clone().into(), + make.whitespace(" ").into(), ], ); } @@ -123,19 +123,19 @@ fn generate_fn_def_assist( } fn insert_new_generic_param_list_fn( - editor: &mut SyntaxEditor, - factory: &SyntaxFactory, + editor: &SyntaxEditor, fn_def: &ast::Fn, lifetime_name: &str, ) -> Option<()> { + let make = editor.make(); let name = fn_def.name()?; editor.insert_all( Position::after(name.syntax()), vec![ - factory.token(T![<]).syntax_element(), - factory.lifetime(lifetime_name).syntax().syntax_element(), - factory.token(T![>]).syntax_element(), + make.token(T![<]).syntax_element(), + make.lifetime(lifetime_name).syntax().syntax_element(), + make.token(T![>]).syntax_element(), ], ); @@ -166,35 +166,35 @@ fn generate_impl_def_assist( let new_lifetime_name = generate_unique_lifetime_param_name(impl_def.generic_param_list())?; acc.add(AssistId::refactor(ASSIST_NAME), ASSIST_LABEL, lifetime_loc, |edit| { - let mut editor = edit.make_editor(impl_def.syntax()); - let factory = SyntaxFactory::without_mappings(); + let editor = edit.make_editor(impl_def.syntax()); + let make = editor.make(); if let Some(generic_list) = impl_def.generic_param_list() { - insert_lifetime_param(&mut editor, &factory, &generic_list, &new_lifetime_name); + insert_lifetime_param(&editor, &generic_list, &new_lifetime_name); } else { - insert_new_generic_param_list_imp(&mut editor, &factory, &impl_def, &new_lifetime_name); + insert_new_generic_param_list_imp(&editor, &impl_def, &new_lifetime_name); } - editor.replace(lifetime.syntax(), factory.lifetime(&new_lifetime_name).syntax()); + editor.replace(lifetime.syntax(), make.lifetime(&new_lifetime_name).syntax()); edit.add_file_edits(file_id, editor); }) } fn insert_new_generic_param_list_imp( - editor: &mut SyntaxEditor, - factory: &SyntaxFactory, + editor: &SyntaxEditor, impl_: &ast::Impl, lifetime_name: &str, ) -> Option<()> { + let make = editor.make(); let impl_kw = impl_.impl_token()?; editor.insert_all( Position::after(impl_kw), vec![ - factory.token(T![<]).syntax_element(), - factory.lifetime(lifetime_name).syntax().syntax_element(), - factory.token(T![>]).syntax_element(), + make.token(T![<]).syntax_element(), + make.lifetime(lifetime_name).syntax().syntax_element(), + make.token(T![>]).syntax_element(), ], ); @@ -202,22 +202,22 @@ fn insert_new_generic_param_list_imp( } fn insert_lifetime_param( - editor: &mut SyntaxEditor, - factory: &SyntaxFactory, + editor: &SyntaxEditor, generic_list: &ast::GenericParamList, lifetime_name: &str, ) -> Option<()> { + let make = editor.make(); let r_angle = generic_list.r_angle_token()?; let needs_comma = generic_list.generic_params().next().is_some(); let mut elements = Vec::new(); if needs_comma { - elements.push(factory.token(T![,]).syntax_element()); - elements.push(factory.whitespace(" ").syntax_element()); + elements.push(make.token(T![,]).syntax_element()); + elements.push(make.whitespace(" ").syntax_element()); } - let lifetime = factory.lifetime(lifetime_name); + let lifetime = make.lifetime(lifetime_name); elements.push(lifetime.syntax().clone().into()); editor.insert_all(Position::before(r_angle), elements); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs index db51070a6430..95f223420b0b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs @@ -1,6 +1,6 @@ use ide_db::syntax_helpers::suggest_name; use itertools::Itertools; -use syntax::ast::{self, AstNode, HasGenericParams, HasName, syntax_factory::SyntaxFactory}; +use syntax::ast::{self, AstNode, HasGenericParams, HasName}; use crate::{AssistContext, AssistId, Assists}; @@ -24,14 +24,14 @@ pub(crate) fn introduce_named_type_parameter( let fn_ = param.syntax().ancestors().nth(2).and_then(ast::Fn::cast)?; let type_bound_list = impl_trait_type.type_bound_list()?; - let make = SyntaxFactory::with_mappings(); let target = fn_.syntax().text_range(); acc.add( AssistId::refactor_rewrite("introduce_named_type_parameter"), "Replace impl trait with type parameter", target, |builder| { - let mut editor = builder.make_editor(fn_.syntax()); + let editor = builder.make_editor(fn_.syntax()); + let make = editor.make(); let existing_names = match fn_.generic_param_list() { Some(generic_param_list) => generic_param_list @@ -58,7 +58,6 @@ pub(crate) fn introduce_named_type_parameter( editor.add_annotation(type_param.syntax(), builder.make_tabstop_before(cap)); } - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs index 42bc05811fd1..1dd0833fad03 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs @@ -4,11 +4,7 @@ merge_imports::{MergeBehavior, try_merge_imports, try_merge_trees}, }; use syntax::{ - AstNode, SyntaxElement, SyntaxNode, - algo::neighbor, - ast::{self, syntax_factory::SyntaxFactory}, - match_ast, - syntax_editor::Removable, + AstNode, SyntaxElement, SyntaxNode, algo::neighbor, ast, match_ast, syntax_editor::Removable, }; use crate::{ @@ -76,17 +72,16 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio }; acc.add(AssistId::refactor_rewrite("merge_imports"), "Merge imports", target, |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(&parent_node); + let editor = builder.make_editor(&parent_node); for edit in edits { match edit { Remove(it) => { let node = it.as_ref(); if let Some(left) = node.left() { - left.remove(&mut editor); + left.remove(&editor); } else if let Some(right) = node.right() { - right.remove(&mut editor); + right.remove(&editor); } } Replace(old, new) => { @@ -94,7 +89,6 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio } } } - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs index 79b8bd5d3d48..e044068ff757 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs @@ -45,22 +45,21 @@ pub(crate) fn move_bounds_to_where_clause( "Move to where clause", target, |builder| { - let mut edit = builder.make_editor(&parent); - let make = SyntaxFactory::without_mappings(); + let editor = builder.make_editor(&parent); let new_preds: Vec = type_param_list .generic_params() - .filter_map(|param| build_predicate(param, &make)) + .filter_map(|param| build_predicate(param, editor.make())) .collect(); match_ast! { match (&parent) { - ast::Fn(it) => it.get_or_create_where_clause(&mut edit, &make, new_preds.into_iter()), - ast::Trait(it) => it.get_or_create_where_clause(&mut edit, &make, new_preds.into_iter()), - ast::Impl(it) => it.get_or_create_where_clause(&mut edit, &make, new_preds.into_iter()), - ast::Enum(it) => it.get_or_create_where_clause(&mut edit, &make, new_preds.into_iter()), - ast::Struct(it) => it.get_or_create_where_clause(&mut edit, &make, new_preds.into_iter()), - ast::TypeAlias(it) => it.get_or_create_where_clause(&mut edit, &make, new_preds.into_iter()), + ast::Fn(it) => it.get_or_create_where_clause(&editor, new_preds.into_iter()), + ast::Trait(it) => it.get_or_create_where_clause(&editor, new_preds.into_iter()), + ast::Impl(it) => it.get_or_create_where_clause(&editor, new_preds.into_iter()), + ast::Enum(it) => it.get_or_create_where_clause(&editor, new_preds.into_iter()), + ast::Struct(it) => it.get_or_create_where_clause(&editor, new_preds.into_iter()), + ast::TypeAlias(it) => it.get_or_create_where_clause(&editor, new_preds.into_iter()), _ => return, } }; @@ -72,11 +71,11 @@ pub(crate) fn move_bounds_to_where_clause( ast::GenericParam::ConstParam(_) => continue, }; if let Some(tbl) = param.type_bound_list() { - tbl.remove(&mut edit); + tbl.remove(&editor); } } - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index 80587372e516..7309cc6d06a5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs @@ -73,24 +73,24 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext<'_>) "Move guard to arm body", target, |builder| { - let mut edit = builder.make_editor(match_arm.syntax()); + let editor = builder.make_editor(match_arm.syntax()); for element in space_before_delete { if element.kind() == WHITESPACE { - edit.delete(element); + editor.delete(element); } } for rest_arm in &rest_arms { - edit.delete(rest_arm.syntax()); + editor.delete(rest_arm.syntax()); } if let Some(element) = space_after_arrow && element.kind() == WHITESPACE { - edit.replace(element, make.whitespace(" ")); + editor.replace(element, make.whitespace(" ")); } - edit.delete(guard.syntax()); - edit.replace(arm_expr.syntax(), if_expr.syntax()); - builder.add_file_edits(ctx.vfs_file_id(), edit); + editor.delete(guard.syntax()); + editor.replace(arm_expr.syntax(), if_expr.syntax()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } @@ -156,7 +156,8 @@ pub(crate) fn move_arm_cond_to_match_guard( "Move condition to match guard", replace_node.text_range(), |builder| { - let make = SyntaxFactory::without_mappings(); + let editor = builder.make_editor(match_arm.syntax()); + let make = editor.make(); let mut replace_arms = vec![]; // Dedent if if_expr is in a BlockExpr @@ -227,14 +228,12 @@ pub(crate) fn move_arm_cond_to_match_guard( } } - let mut edit = builder.make_editor(match_arm.syntax()); - let newline = make.whitespace(&format!("\n{indent_level}")); let replace_arms = replace_arms.iter().map(|it| it.syntax().syntax_element()); let replace_arms = Itertools::intersperse(replace_arms, newline.syntax_element()); - edit.replace_with_many(match_arm.syntax(), replace_arms.collect()); + editor.replace_with_many(match_arm.syntax(), replace_arms.collect()); - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs index 483c90d1032e..ed61d32eb657 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs @@ -3,7 +3,7 @@ use stdx::to_upper_snake_case; use syntax::{ AstNode, - ast::{self, HasName, syntax_factory::SyntaxFactory}, + ast::{self, HasName}, }; use crate::{ @@ -68,8 +68,8 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>) "Promote local to constant", let_stmt.syntax().text_range(), |edit| { - let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(let_stmt.syntax()); + let editor = edit.make_editor(let_stmt.syntax()); + let make = editor.make(); let name = to_upper_snake_case(&name.to_string()); let usages = Definition::Local(local).usages(&ctx.sema).all(); if let Some(usages) = usages.references.get(&ctx.file_id()) { @@ -97,7 +97,6 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>) editor.replace(let_stmt.syntax(), item.syntax()); - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs index 74ed2e14fa23..082052c9d42d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs @@ -1,10 +1,5 @@ use either::Either; -use syntax::{ - AstNode, - algo::find_node_at_range, - ast::{self, syntax_factory::SyntaxFactory}, - syntax_editor::SyntaxEditor, -}; +use syntax::{AstNode, algo::find_node_at_range, ast, syntax_editor::SyntaxEditor}; use crate::{ AssistId, @@ -75,8 +70,7 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) -> } let target = tgt.syntax().text_range(); - let (mut editor, edit_tgt) = SyntaxEditor::new(tgt.syntax().clone()); - + let (editor, edit_tgt) = SyntaxEditor::new(tgt.syntax().clone()); let assignments: Vec<_> = collector .assignments .into_iter() @@ -110,13 +104,12 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) -> "Pull assignment up", target, move |edit| { - let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(tgt.syntax()); + let editor = edit.make_editor(tgt.syntax()); + let make = editor.make(); let assign_expr = make.expr_assignment(collector.common_lhs, new_tgt.clone()); let assign_stmt = make.expr_stmt(assign_expr.into()); editor.replace(tgt.syntax(), assign_stmt.syntax()); - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs index 8b9e6570e917..d7885d50651c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs @@ -1,6 +1,6 @@ use hir::{AsAssocItem, AssocItem, AssocItemContainer, ItemInNs, ModuleDef, db::HirDatabase}; use ide_db::assists::AssistId; -use syntax::{AstNode, ast, ast::syntax_factory::SyntaxFactory}; +use syntax::{AstNode, ast}; use crate::{ assist_context::{AssistContext, Assists}, @@ -59,17 +59,8 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> format!("Qualify `{ident}` method call"), range, |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(call.syntax()); - qualify_candidate.qualify( - |_| {}, - &mut editor, - &make, - &receiver_path, - item_in_ns, - current_edition, - ); - editor.add_mappings(make.finish_with_mappings()); + let editor = builder.make_editor(call.syntax()); + qualify_candidate.qualify(|_| {}, &editor, &receiver_path, item_in_ns, current_edition); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs index c059f758c47e..e3dd77360cca 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs @@ -9,11 +9,7 @@ }; use syntax::Edition; use syntax::ast::HasGenericArgs; -use syntax::{ - AstNode, ast, - ast::{HasArgList, syntax_factory::SyntaxFactory}, - syntax_editor::SyntaxEditor, -}; +use syntax::{AstNode, ast, ast::HasArgList, syntax_editor::SyntaxEditor}; use crate::{ AssistId, GroupLabel, @@ -102,17 +98,14 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option label(ctx.db(), candidate, &import, current_edition), range, |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(&syntax_under_caret); + let editor = builder.make_editor(&syntax_under_caret); qualify_candidate.qualify( |replace_with: String| builder.replace(range, replace_with), - &mut editor, - &make, + &editor, &import.import_path, import.item_to_import, current_edition, ); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); @@ -131,8 +124,7 @@ impl QualifyCandidate<'_> { pub(crate) fn qualify( &self, mut replacer: impl FnMut(String), - editor: &mut SyntaxEditor, - make: &SyntaxFactory, + editor: &SyntaxEditor, import: &hir::ModPath, item: hir::ItemInNs, edition: Edition, @@ -151,10 +143,10 @@ pub(crate) fn qualify( replacer(format!("<{qualifier} as {import}>::{segment}")); } QualifyCandidate::TraitMethod(db, mcall_expr) => { - Self::qualify_trait_method(db, mcall_expr, editor, make, import, item); + Self::qualify_trait_method(db, mcall_expr, editor, import, item); } QualifyCandidate::ImplMethod(db, mcall_expr, hir_fn) => { - Self::qualify_fn_call(db, mcall_expr, editor, make, import, hir_fn); + Self::qualify_fn_call(db, mcall_expr, editor, import, hir_fn); } } } @@ -162,11 +154,11 @@ pub(crate) fn qualify( fn qualify_fn_call( db: &RootDatabase, mcall_expr: &ast::MethodCallExpr, - editor: &mut SyntaxEditor, - make: &SyntaxFactory, + editor: &SyntaxEditor, import: ast::Path, hir_fn: &hir::Function, ) -> Option<()> { + let make = editor.make(); let receiver = mcall_expr.receiver()?; let method_name = mcall_expr.name_ref()?; let generics = @@ -193,15 +185,14 @@ fn qualify_fn_call( fn qualify_trait_method( db: &RootDatabase, mcall_expr: &ast::MethodCallExpr, - editor: &mut SyntaxEditor, - make: &SyntaxFactory, + editor: &SyntaxEditor, import: ast::Path, item: hir::ItemInNs, ) -> Option<()> { let trait_method_name = mcall_expr.name_ref()?; let trait_ = item_as_trait(db, item)?; let method = find_trait_method(db, trait_, &trait_method_name)?; - Self::qualify_fn_call(db, mcall_expr, editor, make, import, &method) + Self::qualify_fn_call(db, mcall_expr, editor, import, &method) } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs index d6d99b8b6d9d..24e41189dac4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs @@ -164,7 +164,7 @@ fn replace_literal( ) { let token = token.syntax(); let node = token.parent().expect("no parent token"); - let mut edit = builder.make_editor(&node); + let edit = builder.make_editor(&node); let new_literal = literal(new); edit.replace(token, mut_token(new_literal)); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs index f4c354b8a21d..32fae8a5bbd4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs @@ -47,7 +47,7 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( .map(|t| t.text_range()) .reduce(|acc, range| acc.cover(range))?; acc.add(AssistId::quick_fix("remove_dbg"), "Remove dbg!()", target, |builder| { - let mut editor = builder.make_editor(ctx.source_file().syntax()); + let editor = builder.make_editor(ctx.source_file().syntax()); for (range, expr) in replacements { if let Some(expr) = expr { editor.insert(Position::before(range[0].clone()), expr.syntax()); @@ -209,7 +209,7 @@ fn replace_nested_dbgs(expanded: ast::Expr) -> ast::Expr { return replaced; } - let (mut editor, expanded) = SyntaxEditor::with_ast_node(&expanded); + let (editor, expanded) = SyntaxEditor::with_ast_node(&expanded); // We need to collect to avoid mutation during traversal. let macro_exprs: Vec<_> = expanded.syntax().descendants().filter_map(ast::MacroExpr::cast).collect(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_else_branches.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_else_branches.rs index 6a02c37015d3..0c03856417a0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_else_branches.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_else_branches.rs @@ -55,7 +55,7 @@ pub(crate) fn remove_else_branches(acc: &mut Assists, ctx: &AssistContext<'_>) - "Remove `else` branches", target, |builder| { - let mut editor = builder.make_editor(&else_token.parent().unwrap()); + let editor = builder.make_editor(&else_token.parent().unwrap()); match else_token.prev_token() { Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), _ => (), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs index b07a361adf48..2a6024339f60 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs @@ -22,7 +22,7 @@ pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( let target = mut_token.text_range(); acc.add(AssistId::refactor("remove_mut"), "Remove `mut` keyword", target, |builder| { - let mut editor = builder.make_editor(&mut_token.parent().unwrap()); + let editor = builder.make_editor(&mut_token.parent().unwrap()); match mut_token.next_token() { Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), _ => (), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs index f07da489e23a..af249c97b9c4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -1,8 +1,4 @@ -use syntax::{ - AstNode, SyntaxKind, T, - ast::{self, syntax_factory::SyntaxFactory}, - syntax_editor::Position, -}; +use syntax::{AstNode, SyntaxKind, T, ast, syntax_editor::Position}; use crate::{AssistContext, AssistId, Assists}; @@ -44,7 +40,8 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) -> "Remove redundant parentheses", target, |builder| { - let mut editor = builder.make_editor(parens.syntax()); + let editor = builder.make_editor(parens.syntax()); + let make = editor.make(); let prev_token = parens.syntax().first_token().and_then(|it| it.prev_token()); let need_to_add_ws = match prev_token { Some(it) => { @@ -54,9 +51,7 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) -> None => false, }; if need_to_add_ws { - let make = SyntaxFactory::with_mappings(); editor.insert(Position::before(parens.syntax()), make.whitespace(" ")); - editor.add_mappings(make.finish_with_mappings()); } editor.replace(parens.syntax(), expr.syntax()); builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs index 8b824c7c7f49..b91d678c9371 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs @@ -80,7 +80,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) -> "Remove unused parameter", param.syntax().text_range(), |builder| { - let mut editor = builder.make_editor(&parent); + let editor = builder.make_editor(&parent); let elements = elements_to_remove(param.syntax()); for element in elements { editor.delete(element); @@ -116,7 +116,7 @@ fn process_usages( else { continue; }; - let mut editor = builder.make_editor(&parent); + let editor = builder.make_editor(&parent); for element in element_range { editor.delete(element); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_fields.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_fields.rs index 990677d37213..facbab8019b2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_fields.rs @@ -71,14 +71,12 @@ pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti "Reorder record fields", target, |builder| { - let mut editor = builder.make_editor(&parent_node); + let editor = builder.make_editor(&parent_node); match fields { - Either::Left((sorted, field_list)) => { - replace(&mut editor, field_list.fields(), sorted) - } + Either::Left((sorted, field_list)) => replace(&editor, field_list.fields(), sorted), Either::Right((sorted, field_list)) => { - replace(&mut editor, field_list.fields(), sorted) + replace(&editor, field_list.fields(), sorted) } } @@ -88,7 +86,7 @@ pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti } fn replace( - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, fields: impl Iterator, sorted_fields: impl IntoIterator, ) { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs index 0ad5ec9d4424..df5281895abd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/reorder_impl_items.rs @@ -99,7 +99,7 @@ pub(crate) fn reorder_impl_items(acc: &mut Assists, ctx: &AssistContext<'_>) -> "Sort items by trait definition", target, |builder| { - let mut editor = builder.make_editor(&parent_node); + let editor = builder.make_editor(&parent_node); assoc_items .into_iter() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_arith_op.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_arith_op.rs index b686dc056667..5ad5efac05c2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_arith_op.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_arith_op.rs @@ -1,7 +1,7 @@ use ide_db::assists::{AssistId, GroupLabel}; use syntax::{ AstNode, - ast::{self, ArithOp, BinaryOp, syntax_factory::SyntaxFactory}, + ast::{self, ArithOp, BinaryOp}, }; use crate::assist_context::{AssistContext, Assists}; @@ -83,8 +83,8 @@ fn replace_arith(acc: &mut Assists, ctx: &AssistContext<'_>, kind: ArithKind) -> kind.label(), op_expr.text_range(), |builder| { - let mut edit = builder.make_editor(rhs.syntax()); - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(rhs.syntax()); + let make = editor.make(); let method_name = kind.method_name(op); let needs_parentheses = @@ -92,10 +92,8 @@ fn replace_arith(acc: &mut Assists, ctx: &AssistContext<'_>, kind: ArithKind) -> let receiver = if needs_parentheses { make.expr_paren(lhs).into() } else { lhs }; let arith_expr = make.expr_method_call(receiver, make.name_ref(&method_name), make.arg_list([rhs])); - edit.replace(op_expr, arith_expr.syntax()); - - edit.add_mappings(make.finish_with_mappings()); - builder.add_file_edits(ctx.vfs_file_id(), edit); + editor.replace(op_expr, arith_expr.syntax()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 5e595218f6b1..751cd42f6e8d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -4,7 +4,7 @@ use syntax::{ SyntaxKind::WHITESPACE, T, - ast::{self, AstNode, HasName, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, HasName}, syntax_editor::{Position, SyntaxEditor}, }; @@ -128,10 +128,12 @@ fn add_assist( let label = format!("Convert to manual `impl {replace_trait_path} for {annotated_name}`"); acc.add(AssistId::refactor("replace_derive_with_manual_impl"), label, target, |builder| { - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(attr.syntax()); + let make = editor.make(); let insert_after = Position::after(adt.syntax()); let impl_is_unsafe = trait_.map(|s| s.is_unsafe(ctx.db())).unwrap_or(false); let impl_def = impl_def_from_trait( + &editor, &ctx.sema, ctx.config, adt, @@ -140,9 +142,7 @@ fn add_assist( replace_trait_path, impl_is_unsafe, ); - - let mut editor = builder.make_editor(attr.syntax()); - update_attribute(&make, &mut editor, old_derives, old_tree, old_trait_path, attr); + update_attribute(&editor, old_derives, old_tree, old_trait_path, attr); let trait_path = make.ty_path(replace_trait_path.clone()).into(); @@ -152,7 +152,7 @@ fn add_assist( impl_def.assoc_item_list().and_then(|list| list.assoc_items().next()), ) } else { - (generate_trait_impl(&make, impl_is_unsafe, adt, trait_path), None) + (generate_trait_impl(make, impl_is_unsafe, adt, trait_path), None) }; if let Some(cap) = ctx.config.snippet_cap { @@ -178,12 +178,12 @@ fn add_assist( insert_after, vec![make.whitespace("\n\n").into(), impl_def.syntax().clone().into()], ); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }) } fn impl_def_from_trait( + editor: &SyntaxEditor, sema: &hir::Semantics<'_, ide_db::RootDatabase>, config: &AssistConfig, adt: &ast::Adt, @@ -192,6 +192,7 @@ fn impl_def_from_trait( trait_path: &ast::Path, impl_is_unsafe: bool, ) -> Option { + let make = editor.make(); let trait_ = trait_?; let target_scope = sema.scope(annotated_name.syntax())?; @@ -208,12 +209,11 @@ fn impl_def_from_trait( if trait_items.is_empty() { return None; } - let make = SyntaxFactory::without_mappings(); let trait_ty: ast::Type = make.ty_path(trait_path.clone()).into(); - let impl_def = generate_trait_impl(&make, impl_is_unsafe, adt, trait_ty.clone()); + let impl_def = generate_trait_impl(make, impl_is_unsafe, adt, trait_ty.clone()); let assoc_items = add_trait_assoc_items_to_impl( - &make, + make, sema, config, &trait_items, @@ -223,10 +223,10 @@ fn impl_def_from_trait( ); let assoc_item_list = if let Some((first, other)) = assoc_items.split_first() { let first_item = if let ast::AssocItem::Fn(func) = first - && let Some(body) = gen_trait_fn_body(&make, func, trait_path, adt, None) + && let Some(body) = gen_trait_fn_body(make, func, trait_path, adt, None) && let Some(func_body) = func.body() { - let (mut editor, _) = SyntaxEditor::new(first.syntax().clone()); + let (editor, _) = SyntaxEditor::new(first.syntax().clone()); editor.replace(func_body.syntax(), body.syntax()); ast::AssocItem::cast(editor.finish().new_root().clone()) } else { @@ -239,17 +239,17 @@ fn impl_def_from_trait( make.assoc_item_list_empty() }; - Some(generate_trait_impl_with_item(&make, impl_is_unsafe, adt, trait_ty, assoc_item_list)) + Some(generate_trait_impl_with_item(make, impl_is_unsafe, adt, trait_ty, assoc_item_list)) } fn update_attribute( - make: &SyntaxFactory, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, old_derives: &[ast::Path], old_tree: &ast::TokenTree, old_trait_path: &ast::Path, attr: &ast::Attr, ) { + let make = editor.make(); let new_derives = old_derives .iter() .filter(|t| t.to_string() != old_trait_path.to_string()) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index ada2fd9b217a..3e8afd893674 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -111,9 +111,10 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<' format!("Replace if{let_} with match"), available_range, move |builder| { - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(if_expr.syntax()); + let make = editor.make(); let match_expr: ast::Expr = { - let else_arm = make_else_arm(ctx, &make, else_block, &cond_bodies); + let else_arm = make_else_arm(ctx, make, else_block, &cond_bodies); let make_match_arm = |(pat, guard, body): (_, Option, ast::BlockExpr)| { // Dedent from original position, then indent for match arm @@ -139,17 +140,15 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<' if_expr.syntax().parent().is_some_and(|it| ast::IfExpr::can_cast(it.kind())); let expr = if has_preceding_if_expr { // make sure we replace the `else if let ...` with a block so we don't end up with `else expr` - let block_expr = make + let block_expr = editor + .make() .block_expr([], Some(match_expr.dedent(indent).indent(IndentLevel(1)))) .indent(indent); block_expr.into() } else { match_expr }; - - let mut editor = builder.make_editor(if_expr.syntax()); editor.replace(if_expr.syntax(), expr.syntax()); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -267,7 +266,8 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<' format!("Replace match with if{let_}"), match_expr.syntax().text_range(), move |builder| { - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(match_expr.syntax()); + let make = editor.make(); let make_block_expr = |expr: ast::Expr| { // Blocks with modifiers (unsafe, async, etc.) are parsed as BlockExpr, but are // formatted without enclosing braces. If we encounter such block exprs, @@ -292,7 +292,7 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<' _ => make.expr_let(if_let_pat, scrutinee).into(), }; let condition = if let Some(guard) = guard { - let guard = wrap_paren(guard, &make, ast::prec::ExprPrecedence::LAnd); + let guard = wrap_paren(guard, make, ast::prec::ExprPrecedence::LAnd); make.expr_bin(condition, ast::BinaryOp::LogicOp(ast::LogicOp::And), guard).into() } else { condition @@ -301,7 +301,8 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<' let else_expr = else_expr.reset_indent(); let then_block = make_block_expr(then_expr); let else_expr = if is_empty_expr(&else_expr) { None } else { Some(else_expr) }; - let if_let_expr = make + let if_let_expr = editor + .make() .expr_if( condition, then_block, @@ -309,9 +310,7 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<' ) .indent(IndentLevel::from_node(match_expr.syntax())); - let mut editor = builder.make_editor(match_expr.syntax()); editor.replace(match_expr.syntax(), if_let_expr.syntax()); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -402,21 +401,20 @@ fn let_and_guard(cond: &ast::Expr) -> (Option, Option) } else if let ast::Expr::BinExpr(bin_expr) = cond && let Some(ast::Expr::LetExpr(let_expr)) = and_bin_expr_left(bin_expr).lhs() { - let (mut edit, new_expr) = SyntaxEditor::with_ast_node(bin_expr); - + let (editor, new_expr) = SyntaxEditor::with_ast_node(bin_expr); let left_bin = and_bin_expr_left(&new_expr); if let Some(rhs) = left_bin.rhs() { - edit.replace(left_bin.syntax(), rhs.syntax()); + editor.replace(left_bin.syntax(), rhs.syntax()); } else { if let Some(next) = left_bin.syntax().next_sibling_or_token() && next.kind() == SyntaxKind::WHITESPACE { - edit.delete(next); + editor.delete(next); } - edit.delete(left_bin.syntax()); + editor.delete(left_bin.syntax()); } - let new_expr = edit.finish().new_root().clone(); + let new_expr = editor.finish().new_root().clone(); (Some(let_expr), ast::Expr::cast(new_expr)) } else { (None, Some(cond.clone())) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs index 38d8c38ef23d..802d5f72b997 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs @@ -1,6 +1,9 @@ use either::Either; use ide_db::syntax_helpers::suggest_name; -use syntax::ast::{self, AstNode, HasArgList, prec::ExprPrecedence, syntax_factory::SyntaxFactory}; +use syntax::{ + ast::{self, AstNode, HasArgList, prec::ExprPrecedence, syntax_factory::SyntaxFactory}, + syntax_editor::SyntaxEditor, +}; use crate::{ AssistContext, AssistId, Assists, @@ -41,9 +44,9 @@ pub(crate) fn replace_is_method_with_if_let_method( let method_kind = token.text().strip_suffix("_and").unwrap_or(token.text()); match method_kind { "is_some" | "is_ok" => { + let (editor, _) = SyntaxEditor::new(ctx.source_file().syntax().clone()); + let make = editor.make(); let receiver = call_expr.receiver()?; - let make = SyntaxFactory::with_mappings(); - let mut name_generator = suggest_name::NameGenerator::new_from_scope_locals( ctx.sema.scope(has_cond.syntax()), ); @@ -52,7 +55,7 @@ pub(crate) fn replace_is_method_with_if_let_method( } else { name_generator.for_variable(&receiver, &ctx.sema) }; - let (pat, predicate) = method_predicate(&call_expr, &var_name, &make); + let (pat, predicate) = method_predicate(&call_expr, &var_name, make); let (assist_id, message, text) = if method_kind == "is_some" { ("replace_is_some_with_if_let_some", "Replace `is_some` with `let Some`", "Some") @@ -65,8 +68,7 @@ pub(crate) fn replace_is_method_with_if_let_method( message, call_expr.syntax().text_range(), |edit| { - let mut editor = edit.make_editor(call_expr.syntax()); - + let make = editor.make(); let pat = make.tuple_struct_pat(make.ident_path(text), [pat]).into(); let let_expr = make.expr_let(pat, receiver); @@ -81,14 +83,12 @@ pub(crate) fn replace_is_method_with_if_let_method( let new_expr = if let Some(predicate) = predicate { let op = ast::BinaryOp::LogicOp(ast::LogicOp::And); - let predicate = wrap_paren(predicate, &make, ExprPrecedence::LAnd); + let predicate = wrap_paren(predicate, make, ExprPrecedence::LAnd); make.expr_bin(let_expr.into(), op, predicate).into() } else { ast::Expr::from(let_expr) }; editor.replace(call_expr.syntax(), new_expr.syntax()); - - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs index 6ff5f0bbd30c..d36f7f1f066a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs @@ -46,8 +46,8 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_> "Replace let with if let", target, |builder| { - let mut editor = builder.make_editor(let_stmt.syntax()); - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(let_stmt.syntax()); + let make = editor.make(); let ty = ctx.sema.type_of_expr(&init); let pat = if let_stmt.let_else().is_some() { // Do not add the wrapper type that implements `Try`, @@ -59,9 +59,10 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_> .map(|it| it.happy_case()); match happy_variant { None => original_pat, - Some(var_name) => { - make.tuple_struct_pat(make.ident_path(var_name), [original_pat]).into() - } + Some(var_name) => editor + .make() + .tuple_struct_pat(make.ident_path(var_name), [original_pat]) + .into(), } }; let init_expr = @@ -79,7 +80,6 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_> let if_stmt = make.expr_stmt(if_expr.into()); editor.replace(let_stmt.syntax(), if_stmt.syntax()); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs index 018642a04723..17ef7727eca3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs @@ -5,7 +5,6 @@ defs::Definition, search::{SearchScope, UsageSearchResult}, }; -use syntax::ast::syntax_factory::SyntaxFactory; use syntax::{ AstNode, ast::{self, HasGenericParams, HasName, HasTypeBounds, Name, NameLike, PathType}, @@ -72,8 +71,8 @@ pub(crate) fn replace_named_generic_with_impl( "Replace named generic with impl trait", target, |edit| { - let mut editor = edit.make_editor(type_param.syntax()); - let make = SyntaxFactory::without_mappings(); + let editor = edit.make_editor(type_param.syntax()); + let make = editor.make(); // remove trait from generic param list if let Some(generic_params) = fn_.generic_param_list() { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs index fd090cc081fa..eebe93f005f9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs @@ -73,8 +73,8 @@ pub(crate) fn replace_qualified_name_with_use( // Now that we've brought the name into scope, re-qualify all paths that could be // affected (that is, all paths inside the node we added the `use` to). let scope_node = scope.as_syntax_node(); - let mut editor = builder.make_editor(scope_node); - shorten_paths(&mut editor, scope_node, &original_path); + let editor = builder.make_editor(scope_node); + shorten_paths(&editor, scope_node, &original_path); builder.add_file_edits(ctx.vfs_file_id(), editor); let path = drop_generic_args(&original_path); let edition = ctx @@ -111,7 +111,7 @@ fn target_path(ctx: &AssistContext<'_>, mut original_path: ast::Path) -> Option< } fn drop_generic_args(path: &ast::Path) -> ast::Path { - let (mut editor, path) = SyntaxEditor::with_ast_node(path); + let (editor, path) = SyntaxEditor::with_ast_node(path); if let Some(segment) = path.segment() && let Some(generic_args) = segment.generic_arg_list() { @@ -122,7 +122,7 @@ fn drop_generic_args(path: &ast::Path) -> ast::Path { } /// Mutates `node` to shorten `path` in all descendants of `node`. -fn shorten_paths(editor: &mut SyntaxEditor, node: &SyntaxNode, path: &ast::Path) { +fn shorten_paths(editor: &SyntaxEditor, node: &SyntaxNode, path: &ast::Path) { for child in node.children() { match_ast! { match child { @@ -141,7 +141,7 @@ fn shorten_paths(editor: &mut SyntaxEditor, node: &SyntaxNode, path: &ast::Path) } } -fn maybe_replace_path(editor: &mut SyntaxEditor, path: ast::Path, target: ast::Path) -> Option<()> { +fn maybe_replace_path(editor: &SyntaxEditor, path: ast::Path, target: ast::Path) -> Option<()> { if !path_eq_no_generics(path.clone(), target) { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/sort_items.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/sort_items.rs index e973e70345dc..911fa9d14b59 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/sort_items.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/sort_items.rs @@ -127,7 +127,7 @@ fn add_rewrite( target: &SyntaxNode, ) -> Option<()> { self.add(AssistId::refactor_rewrite("sort_items"), label, target.text_range(), |builder| { - let mut editor = builder.make_editor(target); + let editor = builder.make_editor(target); old.into_iter() .zip(new) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs index 15143575e7d8..4d375080f50e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs @@ -2,7 +2,7 @@ use syntax::{ AstNode, SyntaxKind, SyntaxToken, T, algo::{previous_non_trivia_token, skip_trivia_token}, - ast::{self, syntax_factory::SyntaxFactory}, + ast, }; use crate::{AssistContext, Assists}; @@ -73,8 +73,8 @@ enum MacroDelims { }, token_tree.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(token_tree.syntax()); + let editor = builder.make_editor(token_tree.syntax()); + let make = editor.make(); match token { MacroDelims::LPar | MacroDelims::RPar => { @@ -100,7 +100,6 @@ enum MacroDelims { } } } - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs index accb5c28d6ed..520b106bd962 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs @@ -1,6 +1,6 @@ use syntax::{ AstNode, SyntaxKind, - ast::{self, HasAttrs, HasVisibility, edit::IndentLevel, make, syntax_factory::SyntaxFactory}, + ast::{self, HasAttrs, HasVisibility, edit::IndentLevel, make}, syntax_editor::{Element, Position, Removable}, }; @@ -41,26 +41,27 @@ pub(crate) fn unmerge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt let target = tree.syntax().text_range(); acc.add(AssistId::refactor_rewrite("unmerge_imports"), label, target, |builder| { - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(use_.syntax()); + let make = editor.make(); let new_use = make.use_( use_.attrs(), use_.visibility(), make.use_tree(path, tree.use_tree_list(), tree.rename(), tree.star_token().is_some()), ); - let mut editor = builder.make_editor(use_.syntax()); // Remove the use tree from the current use item - tree.remove(&mut editor); + tree.remove(&editor); // Insert a newline and indentation, followed by the new use item editor.insert_all( Position::after(use_.syntax()), vec![ - make.whitespace(&format!("\n{}", IndentLevel::from_node(use_.syntax()))) + editor + .make() + .whitespace(&format!("\n{}", IndentLevel::from_node(use_.syntax()))) .syntax_element(), new_use.syntax().syntax_element(), ], ); - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs index c4c03d3e35f5..65300ccefdb9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs @@ -1,6 +1,6 @@ use syntax::{ Direction, SyntaxKind, T, - ast::{self, AstNode, edit::IndentLevel, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, edit::IndentLevel}, syntax_editor::{Element, Position}, }; @@ -56,8 +56,8 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O "Unmerge match arm", pipe_token.text_range(), |edit| { - let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(&new_parent); + let editor = edit.make_editor(&new_parent); + let make = editor.make(); // It is guaranteed that `pats_after` has at least one element let new_pat = if pats_after.len() == 1 { pats_after[0].clone() @@ -101,7 +101,6 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O insert_after_old_arm.push(new_match_arm.syntax().clone().into()); 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); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs index ef395791e251..045a27295297 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs @@ -1,5 +1,5 @@ use hir::AsAssocItem; -use syntax::ast::{self, AstNode, HasArgList, prec::ExprPrecedence, syntax_factory::SyntaxFactory}; +use syntax::ast::{self, AstNode, HasArgList, prec::ExprPrecedence}; use crate::{AssistContext, AssistId, Assists}; @@ -50,8 +50,8 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) "Unqualify method call", call.syntax().text_range(), |builder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = builder.make_editor(call.syntax()); + let editor = builder.make_editor(call.syntax()); + let make = editor.make(); let new_arg_list = make.arg_list(args.args().skip(1)); let receiver = if first_arg.precedence().needs_parentheses_in(ExprPrecedence::Postfix) { @@ -67,10 +67,9 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) && let Some(trait_) = fun.container_or_implemented_trait(ctx.db()) && !scope.can_use_trait_methods(trait_) { - add_import(qualifier, ctx, &make, &mut editor); + add_import(qualifier, ctx, &editor); } - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -79,8 +78,7 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) fn add_import( qualifier: ast::Path, ctx: &AssistContext<'_>, - make: &SyntaxFactory, - editor: &mut syntax::syntax_editor::SyntaxEditor, + editor: &syntax::syntax_editor::SyntaxEditor, ) { if let Some(path_segment) = qualifier.segment() { // for `` @@ -112,7 +110,6 @@ fn add_import( import, &ctx.config.insert_use, editor, - make, ); } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs index 5593ca3eb88f..23bbe2143719 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs @@ -72,18 +72,18 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let replacement = replacement.stmt_list()?; acc.add(AssistId::refactor_rewrite("unwrap_block"), "Unwrap block", target, |builder| { - let mut edit = builder.make_editor(block.syntax()); + let editor = builder.make_editor(block.syntax()); let replacement = replacement.dedent(from_indent).indent(into_indent); let container = prefer_container.unwrap_or(container); - edit.replace_with_many(&container, extract_statements(replacement)); - delete_else_before(container, &mut edit); + editor.replace_with_many(&container, extract_statements(replacement)); + delete_else_before(container, &editor); - builder.add_file_edits(ctx.vfs_file_id(), edit); + builder.add_file_edits(ctx.vfs_file_id(), editor); }) } -fn delete_else_before(container: SyntaxNode, edit: &mut SyntaxEditor) { +fn delete_else_before(container: SyntaxNode, edit: &SyntaxEditor) { let Some(else_token) = container .siblings_with_tokens(syntax::Direction::Prev) .skip(1) @@ -103,7 +103,7 @@ fn delete_else_before(container: SyntaxNode, edit: &mut SyntaxEditor) { fn wrap_let(assign: &ast::LetStmt, replacement: ast::BlockExpr) -> ast::BlockExpr { let try_wrap_assign = || { let initializer = assign.initializer()?.syntax().syntax_element(); - let (mut edit, replacement) = SyntaxEditor::with_ast_node(&replacement); + let (editor, replacement) = SyntaxEditor::with_ast_node(&replacement); let tail_expr = replacement.tail_expr()?; let before = assign.syntax().children_with_tokens().take_while(|it| *it != initializer).collect(); @@ -114,9 +114,9 @@ fn wrap_let(assign: &ast::LetStmt, replacement: ast::BlockExpr) -> ast::BlockExp .skip(1) .collect(); - edit.insert_all(Position::before(tail_expr.syntax()), before); - edit.insert_all(Position::after(tail_expr.syntax()), after); - ast::BlockExpr::cast(edit.finish().new_root().clone()) + editor.insert_all(Position::before(tail_expr.syntax()), before); + editor.insert_all(Position::after(tail_expr.syntax()), after); + ast::BlockExpr::cast(editor.finish().new_root().clone()) }; try_wrap_assign().unwrap_or(replacement) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs index eea6c85e8df0..1fe9ea4eb875 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_return_type.rs @@ -5,7 +5,7 @@ }; use syntax::{ AstNode, NodeOrToken, SyntaxKind, - ast::{self, HasArgList, HasGenericArgs, syntax_factory::SyntaxFactory}, + ast::{self, HasArgList, HasGenericArgs}, match_ast, }; @@ -66,8 +66,8 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> let happy_type = extract_wrapped_type(type_ref)?; acc.add(kind.assist_id(), kind.label(), type_ref.syntax().text_range(), |builder| { - let mut editor = builder.make_editor(&parent); - let make = SyntaxFactory::with_mappings(); + let editor = builder.make_editor(&parent); + let make = editor.make(); let mut exprs_to_unwrap = Vec::new(); let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_unwrap, e); @@ -168,7 +168,6 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> editor.add_annotation(final_placeholder.syntax(), builder.make_tabstop_after(cap)); } - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_type_to_generic_arg.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_type_to_generic_arg.rs index 7b5adc1858b4..935ae1890544 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_type_to_generic_arg.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_type_to_generic_arg.rs @@ -46,7 +46,7 @@ pub(crate) fn unwrap_type_to_generic_arg(acc: &mut Assists, ctx: &AssistContext< format!("Unwrap type to type argument {generic_arg}"), path_type.syntax().text_range(), |builder| { - let mut editor = builder.make_editor(path_type.syntax()); + let editor = builder.make_editor(path_type.syntax()); editor.replace(path_type.syntax(), generic_arg.syntax()); builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs index 0f089c9b66eb..81aa068aedea 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs @@ -77,9 +77,9 @@ pub(crate) fn wrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op kind.label(), type_ref.syntax().text_range(), |builder| { - let mut editor = builder.make_editor(&parent); - let make = SyntaxFactory::with_mappings(); - let alias = wrapper_alias(ctx, &make, core_wrapper, type_ref, &ty, kind.symbol()); + let editor = builder.make_editor(&parent); + let make = editor.make(); + let alias = wrapper_alias(ctx, make, core_wrapper, type_ref, &ty, kind.symbol()); let (ast_new_return_ty, semantic_new_return_ty) = alias.unwrap_or_else(|| { let (ast_ty, ty_constructor) = match kind { WrapperKind::Option => { @@ -156,8 +156,6 @@ pub(crate) fn wrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op ); } } - - editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs index 3b8988db7aae..f40769e0d791 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs @@ -2,7 +2,7 @@ use itertools::Itertools; use syntax::{ NodeOrToken, SyntaxToken, T, TextRange, algo, - ast::{self, AstNode, edit::AstNodeEdit, make, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, edit::AstNodeEdit, make}, }; use crate::{AssistContext, AssistId, Assists}; @@ -192,8 +192,8 @@ fn wrap_derive( } } let handle_source_change = |edit: &mut SourceChangeBuilder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(attr.syntax()); + let editor = edit.make_editor(attr.syntax()); + let make = editor.make(); let new_derive = make.attr_outer( make.meta_token_tree(make.ident_path("derive"), make.token_tree(T!['('], new_derive)), ); @@ -221,8 +221,6 @@ fn wrap_derive( let tabstop = edit.make_placeholder_snippet(snippet_cap); editor.add_annotation(cfg_predicate.syntax(), tabstop); } - - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }; @@ -239,8 +237,8 @@ fn wrap_cfg_attrs(acc: &mut Assists, ctx: &AssistContext<'_>, attrs: Vec, attrs: Vec { - let (mut fn_editor, fn_) = SyntaxEditor::with_ast_node(&fn_); + let (fn_editor, fn_) = SyntaxEditor::with_ast_node(&fn_); let fill_expr: ast::Expr = match config.expr_fill_default { ExprFillDefaultMode::Todo | ExprFillDefaultMode::Default => make.expr_todo(), ExprFillDefaultMode::Underscore => make.expr_underscore().into(), }; let new_body = make.block_expr(None::, Some(fill_expr)); - fn_.replace_or_insert_body(&mut fn_editor, new_body); + fn_.replace_or_insert_body(&fn_editor, new_body); let new_fn_ = fn_editor.finish().new_root().clone(); ast::AssocItem::cast(new_fn_) } ast::AssocItem::TypeAlias(type_alias) => { - let (mut type_alias_editor, type_alias) = SyntaxEditor::with_ast_node(&type_alias); + let (type_alias_editor, type_alias) = SyntaxEditor::with_ast_node(&type_alias); if let Some(type_bound_list) = type_alias.type_bound_list() { - type_bound_list.remove(&mut type_alias_editor); + type_bound_list.remove(&type_alias_editor); }; let type_alias = type_alias_editor.finish().new_root().clone(); ast::AssocItem::cast(type_alias) @@ -346,10 +346,10 @@ fn invert_special_case(make: &SyntaxFactory, expr: &ast::Expr) -> Option, - make: &SyntaxFactory, ) { + let make = editor.make(); let mut attrs = attrs.into_iter().peekable(); if attrs.peek().is_none() { return; @@ -357,12 +357,10 @@ pub(crate) fn insert_attributes( let elem = before.syntax_element(); let indent = IndentLevel::from_element(&elem); let whitespace = format!("\n{indent}"); - edit.insert_all( - syntax::syntax_editor::Position::before(elem), - attrs - .flat_map(|attr| [attr.syntax().clone().into(), make.whitespace(&whitespace).into()]) - .collect(), - ); + let elements: Vec = attrs + .flat_map(|attr| [attr.syntax().clone().into(), make.whitespace(&whitespace).into()]) + .collect(); + editor.insert_all(syntax::syntax_editor::Position::before(elem), elements); } pub(crate) fn next_prev() -> impl Iterator { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs index 9318c3e13272..fe30a4dc5cc9 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs @@ -9,7 +9,7 @@ Direction, NodeOrToken, SyntaxKind, SyntaxNode, algo, ast::{ self, AstNode, HasAttrs, HasModuleItem, HasVisibility, PathSegmentKind, - edit_in_place::Removable, make, syntax_factory::SyntaxFactory, + edit_in_place::Removable, make, }, syntax_editor::{Position, SyntaxEditor}, ted, @@ -175,10 +175,9 @@ pub fn insert_use_with_editor( scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig, - syntax_editor: &mut SyntaxEditor, - syntax_factory: &SyntaxFactory, + syntax_editor: &SyntaxEditor, ) { - insert_use_with_alias_option_with_editor(scope, path, cfg, None, syntax_editor, syntax_factory); + insert_use_with_alias_option_with_editor(scope, path, cfg, None, syntax_editor); } pub fn insert_use_as_alias( @@ -269,9 +268,9 @@ fn insert_use_with_alias_option_with_editor( path: ast::Path, cfg: &InsertUseConfig, alias: Option, - syntax_editor: &mut SyntaxEditor, - syntax_factory: &SyntaxFactory, + syntax_editor: &SyntaxEditor, ) { + let make = syntax_editor.make(); let _p = tracing::info_span!("insert_use_with_alias_option").entered(); let mut mb = match cfg.granularity { ImportGranularity::Crate => Some(MergeBehavior::Crate), @@ -301,7 +300,7 @@ fn insert_use_with_alias_option_with_editor( }; } - let use_tree = syntax_factory.use_tree(path, None, alias, false); + let use_tree = make.use_tree(path, None, alias, false); if mb == Some(MergeBehavior::One) && use_tree.path().is_some() { use_tree.wrap_in_tree_list(); } @@ -324,7 +323,7 @@ fn insert_use_with_alias_option_with_editor( } // either we weren't allowed to merge or there is no import that fits the merge conditions // so look for the place we have to insert to - insert_use_with_editor_(scope, use_item, cfg.group, syntax_editor, syntax_factory); + insert_use_with_editor_(scope, use_item, cfg.group, syntax_editor); } pub fn ast_to_remove_for_path_in_use_stmt(path: &ast::Path) -> Option> { @@ -604,9 +603,9 @@ fn insert_use_with_editor_( scope: &ImportScope, use_item: ast::Use, group_imports: bool, - syntax_editor: &mut SyntaxEditor, - syntax_factory: &SyntaxFactory, + syntax_editor: &SyntaxEditor, ) { + let make = syntax_editor.make(); let scope_syntax = scope.as_syntax_node(); let insert_use_tree = use_item.use_tree().expect("`use_item` should have a use tree for `insert_path`"); @@ -656,7 +655,7 @@ fn insert_use_with_editor_( cov_mark::hit!(insert_group_new_group); syntax_editor.insert(Position::before(&node), use_item.syntax()); if let Some(node) = algo::non_trivia_sibling(node.into(), Direction::Prev) { - syntax_editor.insert(Position::after(node), syntax_factory.whitespace("\n")); + syntax_editor.insert(Position::after(node), make.whitespace("\n")); } return; } @@ -664,7 +663,7 @@ fn insert_use_with_editor_( if let Some(node) = last { cov_mark::hit!(insert_group_no_group); syntax_editor.insert(Position::after(&node), use_item.syntax()); - syntax_editor.insert(Position::after(node), syntax_factory.whitespace("\n")); + syntax_editor.insert(Position::after(node), make.whitespace("\n")); return; } } else { @@ -703,24 +702,18 @@ fn insert_use_with_editor_( { cov_mark::hit!(insert_empty_inner_attr); syntax_editor.insert(Position::after(&last_inner_element), use_item.syntax()); - syntax_editor.insert(Position::after(last_inner_element), syntax_factory.whitespace("\n")); + syntax_editor.insert(Position::after(last_inner_element), make.whitespace("\n")); } else { match l_curly { Some(b) => { cov_mark::hit!(insert_empty_module); - syntax_editor.insert(Position::after(&b), syntax_factory.whitespace("\n")); - syntax_editor.insert_with_whitespace( - Position::after(&b), - use_item.syntax(), - syntax_factory, - ); + syntax_editor.insert(Position::after(&b), make.whitespace("\n")); + syntax_editor.insert_with_whitespace(Position::after(&b), use_item.syntax()); } None => { cov_mark::hit!(insert_empty_file); - syntax_editor.insert( - Position::first_child_of(scope_syntax), - syntax_factory.whitespace("\n\n"), - ); + syntax_editor + .insert(Position::first_child_of(scope_syntax), make.whitespace("\n\n")); syntax_editor.insert(Position::first_child_of(scope_syntax), use_item.syntax()); } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index 407276a2defc..2d4a6b8b5b1b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -278,7 +278,7 @@ fn apply(&self, item: &SyntaxNode) -> SyntaxNode { // `transform_path` may update a node's parent and that would break the // tree traversal. Thus all paths in the tree are collected into a vec // so that such operation is safe. - let (mut editor, item) = SyntaxEditor::new(self.transform_path(item)); + let (editor, item) = SyntaxEditor::new(self.transform_path(item)); preorder_rev(&item).filter_map(ast::Lifetime::cast).for_each(|lifetime| { if let Some(subst) = self.lifetime_substs.get(&lifetime.syntax().text().to_string()) { editor.replace(lifetime.syntax(), subst.clone().syntax()); @@ -329,22 +329,22 @@ fn find_child_paths_and_ident_pats( result } - let (mut editor, root_path) = SyntaxEditor::new(path.clone()); + let (editor, root_path) = SyntaxEditor::new(path.clone()); let result = find_child_paths_and_ident_pats(&root_path); for sub_path in result { let new = self.transform_path(sub_path.syntax()); editor.replace(sub_path.syntax(), new); } - let (mut editor, update_sub_item) = SyntaxEditor::new(editor.finish().new_root().clone()); + let (editor, update_sub_item) = SyntaxEditor::new(editor.finish().new_root().clone()); let item = find_child_paths_and_ident_pats(&update_sub_item); for sub_path in item { - self.transform_path_or_ident_pat(&mut editor, &sub_path); + self.transform_path_or_ident_pat(&editor, &sub_path); } editor.finish().new_root().clone() } fn transform_path_or_ident_pat( &self, - editor: &mut SyntaxEditor, + editor: &SyntaxEditor, item: &Either, ) -> Option<()> { match item { @@ -353,7 +353,7 @@ fn transform_path_or_ident_pat( } } - fn transform_path_(&self, editor: &mut SyntaxEditor, path: &ast::Path) -> Option<()> { + fn transform_path_(&self, editor: &SyntaxEditor, path: &ast::Path) -> Option<()> { if path.qualifier().is_some() { return None; } @@ -448,7 +448,7 @@ fn transform_path_(&self, editor: &mut SyntaxEditor, path: &ast::Path) -> Option }; let found_path = self.target_module.find_path(self.source_scope.db, def, cfg)?; let res = mod_path_to_ast(&found_path, self.target_edition); - let (mut res_editor, res) = SyntaxEditor::with_ast_node(&res); + let (res_editor, res) = SyntaxEditor::with_ast_node(&res); if let Some(args) = path.segment().and_then(|it| it.generic_arg_list()) && let Some(segment) = res.segment() { @@ -522,11 +522,7 @@ fn transform_path_(&self, editor: &mut SyntaxEditor, path: &ast::Path) -> Option Some(()) } - fn transform_ident_pat( - &self, - editor: &mut SyntaxEditor, - ident_pat: &ast::IdentPat, - ) -> Option<()> { + fn transform_ident_pat(&self, editor: &SyntaxEditor, ident_pat: &ast::IdentPat) -> Option<()> { let name = ident_pat.name()?; let temp_path = make::path_from_text(&name.text()); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs index ff0e6a254b6a..f0dd9dd75ebc 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -10,7 +10,6 @@ ast::{ self, BlockExpr, Expr, ExprStmt, HasArgList, edit::{AstNodeEdit, IndentLevel}, - syntax_factory::SyntaxFactory, }, }; @@ -235,7 +234,7 @@ fn remove_unnecessary_wrapper( let file_id = expr_ptr.file_id.original_file(db); let mut builder = SourceChangeBuilder::new(file_id.file_id(ctx.sema.db)); - let mut editor; + let editor; match inner_arg { // We're returning `()` Expr::TupleExpr(tup) if tup.fields().next().is_none() => { @@ -245,7 +244,7 @@ fn remove_unnecessary_wrapper( .and_then(Either::::cast)?; editor = builder.make_editor(parent.syntax()); - let make = SyntaxFactory::with_mappings(); + let make = editor.make(); match parent { Either::Left(ret_expr) => { @@ -261,8 +260,6 @@ fn remove_unnecessary_wrapper( editor.replace(stmt_list.syntax().parent()?, new_block.syntax()); } } - - editor.add_mappings(make.finish_with_mappings()); } _ => { editor = builder.make_editor(call_expr.syntax()); diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs index 567bd0902564..b20aa90d06f2 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs @@ -108,7 +108,7 @@ pub(super) fn increase_indent(self, node: &SyntaxNode) { } pub(super) fn clone_increase_indent(self, node: &SyntaxNode) -> SyntaxNode { - let (mut editor, node) = SyntaxEditor::new(node.clone()); + let (editor, node) = SyntaxEditor::new(node.clone()); let tokens = node .preorder_with_tokens() .filter_map(|event| match event { @@ -142,7 +142,7 @@ pub(super) fn decrease_indent(self, node: &SyntaxNode) { } pub(super) fn clone_decrease_indent(self, node: &SyntaxNode) -> SyntaxNode { - let (mut editor, node) = SyntaxEditor::new(node.clone()); + let (editor, node) = SyntaxEditor::new(node.clone()); let tokens = node .preorder_with_tokens() .filter_map(|event| match event { @@ -198,12 +198,8 @@ fn reset_indent(&self) -> Self { impl AstNodeEdit for N {} impl ast::IdentPat { - pub fn set_pat( - &self, - pat: Option, - syntax_editor: &mut SyntaxEditor, - syntax_factory: &SyntaxFactory, - ) -> ast::IdentPat { + pub fn set_pat(&self, pat: Option, editor: &SyntaxEditor) -> ast::IdentPat { + let make = editor.make(); match pat { None => { if let Some(at_token) = self.at_token() { @@ -213,7 +209,7 @@ pub fn set_pat( .pat() .map(|it| it.syntax().clone().into()) .unwrap_or_else(|| at_token.into()); - syntax_editor.delete_all(start..=end); + editor.delete_all(start..=end); // Remove any trailing ws if let Some(last) = @@ -226,28 +222,28 @@ pub fn set_pat( Some(pat) => { if let Some(old_pat) = self.pat() { // Replace existing pattern - syntax_editor.replace(old_pat.syntax(), pat.syntax()) + editor.replace(old_pat.syntax(), pat.syntax()) } else if let Some(at_token) = self.at_token() { // Have an `@` token but not a pattern yet - syntax_editor.insert(Position::after(at_token), pat.syntax()); + editor.insert(Position::after(at_token), pat.syntax()); } else { // Don't have an `@`, should have a name let name = self.name().unwrap(); let elements = vec![ - syntax_factory.whitespace(" ").into(), - syntax_factory.token(T![@]).into(), - syntax_factory.whitespace(" ").into(), + make.whitespace(" ").into(), + make.token(T![@]).into(), + make.whitespace(" ").into(), pat.syntax().clone().into(), ]; if self.syntax().parent().is_none() { - let (mut local, local_self) = SyntaxEditor::with_ast_node(self); + let (local, local_self) = SyntaxEditor::with_ast_node(self); let local_name = local_self.name().unwrap(); local.insert_all(Position::after(local_name.syntax()), elements); let edit = local.finish(); return ast::IdentPat::cast(edit.new_root().clone()).unwrap(); } else { - syntax_editor.insert_all(Position::after(name.syntax()), elements); + editor.insert_all(Position::after(name.syntax()), elements); } } } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs index f3ae7544cc37..9369a4e700cb 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs @@ -12,6 +12,7 @@ use crate::syntax_editor::SyntaxMapping; +#[derive(Debug)] pub struct SyntaxFactory { // Stored in a refcell so that the factory methods can be &self mappings: Option>, @@ -19,7 +20,7 @@ pub struct SyntaxFactory { impl SyntaxFactory { /// Creates a new [`SyntaxFactory`], generating mappings between input nodes and generated nodes. - pub fn with_mappings() -> Self { + pub(crate) fn with_mappings() -> Self { Self { mappings: Some(RefCell::new(SyntaxMapping::default())) } } @@ -28,13 +29,8 @@ pub fn without_mappings() -> Self { Self { mappings: None } } - /// Gets all of the tracked syntax mappings, if any. - pub fn finish_with_mappings(self) -> SyntaxMapping { - self.mappings.unwrap_or_default().into_inner() - } - /// Take all of the tracked syntax mappings, leaving `SyntaxMapping::default()` in its place, if any. - pub fn take(&self) -> SyntaxMapping { + pub(crate) fn take(&self) -> SyntaxMapping { self.mappings.as_ref().map(|mappings| mappings.take()).unwrap_or_default() } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index ad67abfbed7a..421d13f0dc01 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -96,7 +96,9 @@ pub fn type_bound_list( if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input, ast.bounds().map(|b| b.syntax().clone())); + for (input_node, output_bound) in input.into_iter().zip(ast.bounds()) { + builder.map_node(input_node, output_bound.syntax().clone()); + } builder.finish(&mut mapping); } @@ -209,7 +211,7 @@ pub fn ty_fn_ptr>( } builder.map_children( params_input, - ast.param_list().unwrap().params().map(|p| p.syntax().clone()), + ast.syntax().children().filter(|c| ast::Param::can_cast(c.kind())), ); if let Some(ret_type) = ret_type { builder @@ -242,13 +244,17 @@ pub fn where_pred( builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); } } + builder.finish(&mut mapping); + if let Some(type_bound_list) = ast.type_bound_list() { - builder.map_children( + let mut bounds_builder = + SyntaxMappingBuilder::new(type_bound_list.syntax().clone()); + bounds_builder.map_children( bounds_input, type_bound_list.bounds().map(|b| b.syntax().clone()), ); + bounds_builder.finish(&mut mapping); } - builder.finish(&mut mapping); } ast @@ -484,11 +490,13 @@ pub fn generic_ty_path_segment( if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); builder.map_node(name_ref.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); - builder.map_children( - input, - ast.generic_arg_list().unwrap().generic_args().map(|a| a.syntax().clone()), - ); builder.finish(&mut mapping); + + let generic_arg_list = ast.generic_arg_list().unwrap(); + let mut arg_builder = SyntaxMappingBuilder::new(generic_arg_list.syntax().clone()); + arg_builder + .map_children(input, generic_arg_list.generic_args().map(|a| a.syntax().clone())); + arg_builder.finish(&mut mapping); } ast @@ -629,9 +637,16 @@ pub fn path_from_segments( let ast = make::path_from_segments(segments, is_abs).clone_for_update(); if let Some(mut mapping) = self.mappings() { - let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input, ast.segments().map(|it| it.syntax().clone())); - builder.finish(&mut mapping); + let mut current_path = Some(ast.clone()); + for input_segment in input.iter().rev() { + let Some(path) = current_path else { break }; + if let Some(segment) = path.segment() { + let mut builder = SyntaxMappingBuilder::new(path.syntax().clone()); + builder.map_node(input_segment.clone(), segment.syntax().clone()); + builder.finish(&mut mapping); + } + current_path = path.qualifier(); + } } ast diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs index 8e4dc75d2219..b2bd10b354e9 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs @@ -5,6 +5,7 @@ //! [`SyntaxEditor`]: https://github.com/dotnet/roslyn/blob/43b0b05cc4f492fd5de00f6f6717409091df8daa/src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs use std::{ + cell::RefCell, fmt, iter, num::NonZeroU32, ops::RangeInclusive, @@ -29,9 +30,9 @@ #[derive(Debug)] pub struct SyntaxEditor { root: SyntaxNode, - changes: Vec, - mappings: SyntaxMapping, - annotations: Vec<(SyntaxElement, SyntaxAnnotation)>, + changes: RefCell>, + annotations: RefCell>, + make: SyntaxFactory, } impl SyntaxEditor { @@ -50,9 +51,9 @@ pub fn new(root: SyntaxNode) -> (Self, SyntaxNode) { let editor = Self { root: root.clone(), - changes: Vec::new(), - mappings: SyntaxMapping::default(), - annotations: Vec::new(), + changes: RefCell::new(Vec::new()), + annotations: RefCell::new(Vec::new()), + make: SyntaxFactory::with_mappings(), }; (editor, root) @@ -68,20 +69,21 @@ pub fn with_ast_node(root: &T) -> (Self, T) (editor, T::cast(root).unwrap()) } - pub fn add_annotation(&mut self, element: impl Element, annotation: SyntaxAnnotation) { - self.annotations.push((element.syntax_element(), annotation)) + pub fn make(&self) -> &SyntaxFactory { + &self.make } - pub fn add_annotation_all( - &mut self, - elements: Vec, - annotation: SyntaxAnnotation, - ) { + pub fn add_annotation(&self, element: impl Element, annotation: SyntaxAnnotation) { + self.annotations.borrow_mut().push((element.syntax_element(), annotation)) + } + + pub fn add_annotation_all(&self, elements: Vec, annotation: SyntaxAnnotation) { self.annotations + .borrow_mut() .extend(elements.into_iter().map(|e| e.syntax_element()).zip(iter::repeat(annotation))); } - pub fn merge(&mut self, mut other: SyntaxEditor) { + pub fn merge(&self, other: SyntaxEditor) { debug_assert!( self.root == other.root || other.root.ancestors().any(|node| node == self.root), "{:?} is not in the same tree as {:?}", @@ -89,102 +91,92 @@ pub fn merge(&mut self, mut other: SyntaxEditor) { self.root ); - self.changes.append(&mut other.changes); - self.mappings.merge(other.mappings); - self.annotations.append(&mut other.annotations); + self.changes.borrow_mut().append(&mut other.changes.into_inner()); + if let Some(mut m) = self.make.mappings() { + m.merge(other.make.take()); + } + self.annotations.borrow_mut().append(&mut other.annotations.into_inner()); } - pub fn insert(&mut self, position: Position, element: impl Element) { + pub fn insert(&self, position: Position, element: impl Element) { debug_assert!(is_ancestor_or_self(&position.parent(), &self.root)); - self.changes.push(Change::Insert(position, element.syntax_element())) + self.changes.borrow_mut().push(Change::Insert(position, element.syntax_element())) } - pub fn insert_all(&mut self, position: Position, elements: Vec) { + pub fn insert_all(&self, position: Position, elements: Vec) { debug_assert!(is_ancestor_or_self(&position.parent(), &self.root)); - self.changes.push(Change::InsertAll(position, elements)) + self.changes.borrow_mut().push(Change::InsertAll(position, elements)) } - pub fn insert_with_whitespace( - &mut self, - position: Position, - element: impl Element, - factory: &SyntaxFactory, - ) { - self.insert_all_with_whitespace(position, vec![element.syntax_element()], factory) + pub fn insert_with_whitespace(&self, position: Position, element: impl Element) { + self.insert_all_with_whitespace(position, vec![element.syntax_element()]) } - pub fn insert_all_with_whitespace( - &mut self, - position: Position, - mut elements: Vec, - factory: &SyntaxFactory, - ) { + pub fn insert_all_with_whitespace(&self, position: Position, mut elements: Vec) { if let Some(first) = elements.first() - && let Some(ws) = ws_before(&position, first, factory) + && let Some(ws) = ws_before(&position, first, &self.make) { elements.insert(0, ws.into()); } if let Some(last) = elements.last() - && let Some(ws) = ws_after(&position, last, factory) + && let Some(ws) = ws_after(&position, last, &self.make) { elements.push(ws.into()); } self.insert_all(position, elements) } - pub fn delete(&mut self, element: impl Element) { + pub fn delete(&self, element: impl Element) { let element = element.syntax_element(); debug_assert!(is_ancestor_or_self_of_element(&element, &self.root)); debug_assert!( !matches!(&element, SyntaxElement::Node(node) if node == &self.root), "should not delete root node" ); - self.changes.push(Change::Replace(element.syntax_element(), None)); + self.changes.borrow_mut().push(Change::Replace(element.syntax_element(), None)); } - pub fn delete_all(&mut self, range: RangeInclusive) { + pub fn delete_all(&self, range: RangeInclusive) { if range.start() == range.end() { self.delete(range.start()); return; } debug_assert!(is_ancestor_or_self_of_element(range.start(), &self.root)); - self.changes.push(Change::ReplaceAll(range, Vec::new())) + self.changes.borrow_mut().push(Change::ReplaceAll(range, Vec::new())) } - pub fn replace(&mut self, old: impl Element, new: impl Element) { + pub fn replace(&self, old: impl Element, new: impl Element) { let old = old.syntax_element(); debug_assert!(is_ancestor_or_self_of_element(&old, &self.root)); - self.changes.push(Change::Replace(old.syntax_element(), Some(new.syntax_element()))); + self.changes + .borrow_mut() + .push(Change::Replace(old.syntax_element(), Some(new.syntax_element()))); } - pub fn replace_with_many(&mut self, old: impl Element, new: Vec) { + pub fn replace_with_many(&self, old: impl Element, new: Vec) { let old = old.syntax_element(); debug_assert!(is_ancestor_or_self_of_element(&old, &self.root)); debug_assert!( !(matches!(&old, SyntaxElement::Node(node) if node == &self.root) && new.len() > 1), "cannot replace root node with many elements" ); - self.changes.push(Change::ReplaceWithMany(old.syntax_element(), new)); + self.changes.borrow_mut().push(Change::ReplaceWithMany(old.syntax_element(), new)); } - pub fn replace_all(&mut self, range: RangeInclusive, new: Vec) { + pub fn replace_all(&self, range: RangeInclusive, new: Vec) { if range.start() == range.end() { self.replace_with_many(range.start(), new); return; } debug_assert!(is_ancestor_or_self_of_element(range.start(), &self.root)); - self.changes.push(Change::ReplaceAll(range, new)) + self.changes.borrow_mut().push(Change::ReplaceAll(range, new)) } pub fn finish(self) -> SyntaxEdit { edit_algo::apply_edits(self) } - - pub fn add_mappings(&mut self, other: SyntaxMapping) { - self.mappings.merge(other); - } } /// Represents a completed [`SyntaxEditor`] operation. @@ -538,7 +530,7 @@ mod tests { use crate::{ AstNode, - ast::{self, make, syntax_factory::SyntaxFactory}, + ast::{self, make}, }; use super::*; @@ -559,13 +551,12 @@ fn basic_usage() { .into(), ); - let (mut editor, root) = SyntaxEditor::with_ast_node(&root); + let (editor, root) = SyntaxEditor::with_ast_node(&root); + let make = editor.make(); let to_wrap = root.syntax().descendants().find_map(ast::TupleExpr::cast).unwrap(); let to_replace = root.syntax().descendants().find_map(ast::BinExpr::cast).unwrap(); - let make = SyntaxFactory::with_mappings(); - let name = make::name("var_name"); let name_ref = make::name_ref("var_name").clone_for_update(); @@ -574,7 +565,8 @@ fn basic_usage() { editor.add_annotation(name_ref.syntax(), placeholder_snippet); let new_block = make.block_expr( - [make + [editor + .make() .let_stmt( make.ident_pat(false, false, name.clone()).into(), None, @@ -586,7 +578,6 @@ fn basic_usage() { editor.replace(to_replace.syntax(), name_ref.syntax()); editor.replace(to_wrap.syntax(), new_block.syntax()); - editor.add_mappings(make.finish_with_mappings()); let edit = editor.finish(); @@ -618,9 +609,9 @@ fn test_insert_independent() { None, ); - let (mut editor, root) = SyntaxEditor::with_ast_node(&root); + let (editor, root) = SyntaxEditor::with_ast_node(&root); + let make = editor.make(); let second_let = root.syntax().descendants().find_map(ast::LetStmt::cast).unwrap(); - let make = SyntaxFactory::without_mappings(); editor.insert( Position::first_child_of(root.stmt_list().unwrap().syntax()), @@ -669,14 +660,13 @@ fn test_insert_dependent() { ), ); - let (mut editor, root) = SyntaxEditor::with_ast_node(&root); + let (editor, root) = SyntaxEditor::with_ast_node(&root); + let make = editor.make(); let inner_block = root.syntax().descendants().flat_map(ast::BlockExpr::cast).nth(1).unwrap(); let second_let = root.syntax().descendants().find_map(ast::LetStmt::cast).unwrap(); - let make = SyntaxFactory::with_mappings(); - let new_block_expr = make.block_expr([], Some(ast::Expr::BlockExpr(inner_block.clone()))); let first_let = make.let_stmt( @@ -697,7 +687,6 @@ fn test_insert_dependent() { ); editor.insert(Position::after(second_let.syntax()), third_let.syntax()); editor.replace(inner_block.syntax(), new_block_expr.syntax()); - editor.add_mappings(make.finish_with_mappings()); let edit = editor.finish(); @@ -724,10 +713,10 @@ fn test_replace_root_with_dependent() { None, ); - let (mut editor, root) = SyntaxEditor::with_ast_node(&root); + let (editor, root) = SyntaxEditor::with_ast_node(&root); + let make = editor.make(); let inner_block = root; - let make = SyntaxFactory::with_mappings(); let new_block_expr = make.block_expr([], Some(ast::Expr::BlockExpr(inner_block.clone()))); @@ -742,7 +731,6 @@ fn test_replace_root_with_dependent() { first_let.syntax(), ); editor.replace(inner_block.syntax(), new_block_expr.syntax()); - editor.add_mappings(make.finish_with_mappings()); let edit = editor.finish(); @@ -772,7 +760,7 @@ fn test_replace_token_in_parent() { false, ); - let (mut editor, parent_fn) = SyntaxEditor::with_ast_node(&parent_fn); + let (editor, parent_fn) = SyntaxEditor::with_ast_node(&parent_fn); if let Some(ret_ty) = parent_fn.ret_type() { editor.delete(ret_ty.syntax().clone()); @@ -799,7 +787,7 @@ fn test_more_times_replace_node_to_mutable_token() { let arg_list = make::arg_list([make::expr_literal("1").into(), make::expr_literal("2").into()]); - let (mut editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list); + let (editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list); let target_expr = make::token(parser::SyntaxKind::UNDERSCORE); @@ -818,7 +806,7 @@ fn test_more_times_replace_node_to_mutable() { let arg_list = make::arg_list([make::expr_literal("1").into(), make::expr_literal("2").into()]); - let (mut editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list); + let (editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list); let target_expr = make::expr_literal("3").clone_for_update(); @@ -837,7 +825,7 @@ fn test_more_times_insert_node_to_mutable() { let arg_list = make::arg_list([make::expr_literal("1").into(), make::expr_literal("2").into()]); - let (mut editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list); + let (editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list); let target_expr = make::ext::expr_unit().clone_for_update(); diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs index 78e7083f97e4..27ea03ec09e7 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs @@ -35,7 +35,10 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { // - changed nodes become part of the changed node set (useful for the formatter to only change those parts) // - Propagate annotations - let SyntaxEditor { root, mut changes, mappings, annotations } = editor; + let SyntaxEditor { root, changes, annotations, make } = editor; + let mut changes = changes.into_inner(); + let annotations = annotations.into_inner(); + let mappings = make.take(); let mut node_depths = FxHashMap::::default(); let mut get_node_depth = |node: SyntaxNode| { diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs index d741adb6e344..300d0f02ea77 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs @@ -3,10 +3,7 @@ use crate::{ AstToken, Direction, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, T, algo::neighbor, - ast::{ - self, AstNode, Fn, GenericParam, HasGenericParams, HasName, edit::IndentLevel, make, - syntax_factory::SyntaxFactory, - }, + ast::{self, AstNode, Fn, GenericParam, HasGenericParams, HasName, edit::IndentLevel, make}, syntax_editor::{Position, SyntaxEditor}, }; @@ -15,10 +12,10 @@ pub trait GetOrCreateWhereClause: ast::HasGenericParams { fn get_or_create_where_clause( &self, - editor: &mut SyntaxEditor, - make: &SyntaxFactory, + editor: &SyntaxEditor, new_preds: impl Iterator, ) { + let make = editor.make(); let existing = self.where_clause(); let all_preds: Vec<_> = existing.iter().flat_map(|wc| wc.predicates()).chain(new_preds).collect(); @@ -113,7 +110,7 @@ fn where_clause_position(&self) -> Option { impl SyntaxEditor { /// Adds a new generic param to the function using `SyntaxEditor` - pub fn add_generic_param(&mut self, function: &Fn, new_param: GenericParam) { + pub fn add_generic_param(&self, function: &Fn, new_param: GenericParam) { match function.generic_param_list() { Some(generic_param_list) => match generic_param_list.generic_params().last() { Some(last_param) => { @@ -177,8 +174,8 @@ pub fn add_generic_param(&mut self, function: &Fn, new_param: GenericParam) { } } -fn get_or_insert_comma_after(editor: &mut SyntaxEditor, syntax: &SyntaxNode) -> SyntaxToken { - let make = SyntaxFactory::without_mappings(); +fn get_or_insert_comma_after(editor: &SyntaxEditor, syntax: &SyntaxNode) -> SyntaxToken { + let make = editor.make(); match syntax .siblings_with_tokens(Direction::Next) .filter_map(|it| it.into_token()) @@ -198,7 +195,7 @@ impl ast::AssocItemList { /// /// Attention! This function does align the first line of `item` with respect to `self`, /// but it does _not_ change indentation of other lines (if any). - pub fn add_items(&self, editor: &mut SyntaxEditor, items: Vec) { + pub fn add_items(&self, editor: &SyntaxEditor, items: Vec) { let (indent, position, whitespace) = match self.assoc_items().last() { Some(last_item) => ( IndentLevel::from_node(last_item.syntax()), @@ -232,9 +229,9 @@ pub fn add_items(&self, editor: &mut SyntaxEditor, items: Vec) { impl ast::Impl { pub fn get_or_create_assoc_item_list_with_editor( &self, - editor: &mut SyntaxEditor, - make: &SyntaxFactory, + editor: &SyntaxEditor, ) -> ast::AssocItemList { + let make = editor.make(); if let Some(list) = self.assoc_item_list() { list } else { @@ -249,8 +246,8 @@ pub fn get_or_create_assoc_item_list_with_editor( } impl ast::VariantList { - pub fn add_variant(&self, editor: &mut SyntaxEditor, variant: &ast::Variant) { - let make = SyntaxFactory::without_mappings(); + pub fn add_variant(&self, editor: &SyntaxEditor, variant: &ast::Variant) { + let make = editor.make(); let (indent, position) = match self.variants().last() { Some(last_item) => ( IndentLevel::from_node(last_item.syntax()), @@ -274,7 +271,7 @@ pub fn add_variant(&self, editor: &mut SyntaxEditor, variant: &ast::Variant) { } impl ast::Fn { - pub fn replace_or_insert_body(&self, editor: &mut SyntaxEditor, body: ast::BlockExpr) { + pub fn replace_or_insert_body(&self, editor: &SyntaxEditor, body: ast::BlockExpr) { if let Some(old_body) = self.body() { editor.replace(old_body.syntax(), body.syntax()); } else { @@ -290,8 +287,8 @@ pub fn replace_or_insert_body(&self, editor: &mut SyntaxEditor, body: ast::Block } } -fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) -> Option<()> { - let make = SyntaxFactory::without_mappings(); +fn normalize_ws_between_braces(editor: &SyntaxEditor, node: &SyntaxNode) -> Option<()> { + let make = editor.make(); let l = node .children_with_tokens() .filter_map(|it| it.into_token()) @@ -318,11 +315,11 @@ fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) -> } pub trait Removable: AstNode { - fn remove(&self, editor: &mut SyntaxEditor); + fn remove(&self, editor: &SyntaxEditor); } impl Removable for ast::TypeBoundList { - fn remove(&self, editor: &mut SyntaxEditor) { + fn remove(&self, editor: &SyntaxEditor) { match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) { Some(colon) => editor.delete_all(colon..=self.syntax().clone().into()), None => editor.delete(self.syntax()), @@ -331,9 +328,8 @@ fn remove(&self, editor: &mut SyntaxEditor) { } impl Removable for ast::Use { - fn remove(&self, editor: &mut SyntaxEditor) { - let make = SyntaxFactory::without_mappings(); - + fn remove(&self, editor: &SyntaxEditor) { + let make = editor.make(); let next_ws = self .syntax() .next_sibling_or_token() @@ -355,7 +351,7 @@ fn remove(&self, editor: &mut SyntaxEditor) { } impl Removable for ast::UseTree { - fn remove(&self, editor: &mut SyntaxEditor) { + fn remove(&self, editor: &SyntaxEditor) { for dir in [Direction::Next, Direction::Prev] { if let Some(next_use_tree) = neighbor(self, dir) { let separators = self @@ -379,7 +375,7 @@ mod tests { use stdx::trim_indent; use test_utils::assert_eq_text; - use crate::SourceFile; + use crate::{SourceFile, ast::syntax_factory::SyntaxFactory}; use super::*; @@ -492,9 +488,9 @@ enum Foo { } fn check_add_variant(before: &str, expected: &str, variant: ast::Variant) { - let (mut editor, enum_) = SyntaxEditor::with_ast_node(&ast_from_text::(before)); + let (editor, enum_) = SyntaxEditor::with_ast_node(&ast_from_text::(before)); if let Some(it) = enum_.variant_list() { - it.add_variant(&mut editor, &variant) + it.add_variant(&editor, &variant) } let edit = editor.finish(); let after = edit.new_root.to_string();