From fa20a5064be85349d2d05abcd66f5662d3aecb0c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 20 Apr 2021 02:05:22 +0200 Subject: Remove SyntaxRewriter usage in insert_use in favor of ted --- crates/ide_assists/src/handlers/auto_import.rs | 8 +- .../handlers/extract_struct_from_enum_variant.rs | 85 ++++++++++++---------- .../handlers/replace_qualified_name_with_use.rs | 28 +++---- 3 files changed, 62 insertions(+), 59 deletions(-) (limited to 'crates/ide_assists/src') diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs index 49aa70f74..6db2d2edd 100644 --- a/crates/ide_assists/src/handlers/auto_import.rs +++ b/crates/ide_assists/src/handlers/auto_import.rs @@ -101,9 +101,11 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> format!("Import `{}`", import.import_path), range, |builder| { - let rewriter = - insert_use(&scope, mod_path_to_ast(&import.import_path), ctx.config.insert_use); - builder.rewrite(rewriter); + let scope = match scope.clone() { + ImportScope::File(it) => ImportScope::File(builder.make_ast_mut(it)), + ImportScope::Module(it) => ImportScope::Module(builder.make_ast_mut(it)), + }; + insert_use(&scope, mod_path_to_ast(&import.import_path), ctx.config.insert_use); }, ); } diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs index a8d6355bd..26e1c66ab 100644 --- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs @@ -13,9 +13,9 @@ use ide_db::{ }; use rustc_hash::FxHashSet; use syntax::{ - algo::{find_node_at_offset, SyntaxRewriter}, - ast::{self, edit::IndentLevel, make, AstNode, NameOwner, VisibilityOwner}, - SourceFile, SyntaxElement, SyntaxNode, T, + algo::find_node_at_offset, + ast::{self, make, AstNode, NameOwner, VisibilityOwner}, + ted, SourceFile, SyntaxElement, SyntaxNode, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -62,14 +62,17 @@ pub(crate) fn extract_struct_from_enum_variant( let mut visited_modules_set = FxHashSet::default(); let current_module = enum_hir.module(ctx.db()); visited_modules_set.insert(current_module); - let mut def_rewriter = None; + let mut def_file_references = None; for (file_id, references) in usages { - let mut rewriter = SyntaxRewriter::default(); - let source_file = ctx.sema.parse(file_id); + if file_id == ctx.frange.file_id { + def_file_references = Some(references); + continue; + } + builder.edit_file(file_id); + let source_file = builder.make_ast_mut(ctx.sema.parse(file_id)); for reference in references { update_reference( ctx, - &mut rewriter, reference, &source_file, &enum_module_def, @@ -77,25 +80,27 @@ pub(crate) fn extract_struct_from_enum_variant( &mut visited_modules_set, ); } - if file_id == ctx.frange.file_id { - def_rewriter = Some(rewriter); - continue; - } - builder.edit_file(file_id); - builder.rewrite(rewriter); } - let mut rewriter = def_rewriter.unwrap_or_default(); - update_variant(&mut rewriter, &variant); + builder.edit_file(ctx.frange.file_id); + let variant = builder.make_ast_mut(variant.clone()); + let source_file = builder.make_ast_mut(ctx.sema.parse(ctx.frange.file_id)); + for reference in def_file_references.into_iter().flatten() { + update_reference( + ctx, + reference, + &source_file, + &enum_module_def, + &variant_hir_name, + &mut visited_modules_set, + ); + } extract_struct_def( - &mut rewriter, - &enum_ast, variant_name.clone(), &field_list, &variant.parent_enum().syntax().clone().into(), enum_ast.visibility(), ); - builder.edit_file(ctx.frange.file_id); - builder.rewrite(rewriter); + update_variant(&variant); }, ) } @@ -138,7 +143,6 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Va fn insert_import( ctx: &AssistContext, - rewriter: &mut SyntaxRewriter, scope_node: &SyntaxNode, module: &Module, enum_module_def: &ModuleDef, @@ -151,14 +155,12 @@ fn insert_import( mod_path.pop_segment(); mod_path.push_segment(variant_hir_name.clone()); let scope = ImportScope::find_insert_use_container(scope_node, &ctx.sema)?; - *rewriter += insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use); + insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use); } Some(()) } fn extract_struct_def( - rewriter: &mut SyntaxRewriter, - enum_: &ast::Enum, variant_name: ast::Name, field_list: &Either, start_offset: &SyntaxElement, @@ -180,33 +182,34 @@ fn extract_struct_def( .into(), }; - rewriter.insert_before( - start_offset, - make::struct_(visibility, variant_name, None, field_list).syntax(), + ted::insert_raw( + ted::Position::before(start_offset), + make::struct_(visibility, variant_name, None, field_list).clone_for_update().syntax(), ); - rewriter.insert_before(start_offset, &make::tokens::blank_line()); + ted::insert_raw(ted::Position::before(start_offset), &make::tokens::blank_line()); - if let indent_level @ 1..=usize::MAX = IndentLevel::from_node(enum_.syntax()).0 as usize { - rewriter - .insert_before(start_offset, &make::tokens::whitespace(&" ".repeat(4 * indent_level))); - } + // if let indent_level @ 1..=usize::MAX = IndentLevel::from_node(enum_.syntax()).0 as usize { + // ted::insert(ted::Position::before(start_offset), &make::tokens::blank_line()); + // rewriter + // .insert_before(start_offset, &make::tokens::whitespace(&" ".repeat(4 * indent_level))); + // } Some(()) } -fn update_variant(rewriter: &mut SyntaxRewriter, variant: &ast::Variant) -> Option<()> { +fn update_variant(variant: &ast::Variant) -> Option<()> { let name = variant.name()?; let tuple_field = make::tuple_field(None, make::ty(&name.text())); let replacement = make::variant( name, Some(ast::FieldList::TupleFieldList(make::tuple_field_list(iter::once(tuple_field)))), - ); - rewriter.replace(variant.syntax(), replacement.syntax()); + ) + .clone_for_update(); + ted::replace(variant.syntax(), replacement.syntax()); Some(()) } fn update_reference( ctx: &AssistContext, - rewriter: &mut SyntaxRewriter, reference: FileReference, source_file: &SourceFile, enum_module_def: &ModuleDef, @@ -230,14 +233,16 @@ fn update_reference( let module = ctx.sema.scope(&expr).module()?; if !visited_modules_set.contains(&module) { - if insert_import(ctx, rewriter, &expr, &module, enum_module_def, variant_hir_name).is_some() - { + if insert_import(ctx, &expr, &module, enum_module_def, variant_hir_name).is_some() { visited_modules_set.insert(module); } } - rewriter.insert_after(segment.syntax(), &make::token(T!['('])); - rewriter.insert_after(segment.syntax(), segment.syntax()); - rewriter.insert_after(&expr, &make::token(T![')'])); + ted::insert_raw( + ted::Position::before(segment.syntax()), + make::path_from_text(&format!("{}", segment)).clone_for_update().syntax(), + ); + ted::insert_raw(ted::Position::before(segment.syntax()), make::token(T!['('])); + ted::insert_raw(ted::Position::after(&expr), make::token(T![')'])); Some(()) } diff --git a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs index 36d2e0331..2f2306fcc 100644 --- a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs @@ -1,5 +1,5 @@ use ide_db::helpers::insert_use::{insert_use, ImportScope}; -use syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SyntaxNode}; +use syntax::{ast, match_ast, ted, AstNode, SyntaxNode}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -40,18 +40,17 @@ pub(crate) fn replace_qualified_name_with_use( |builder| { // 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 mut rewriter = SyntaxRewriter::default(); - shorten_paths(&mut rewriter, syntax.clone(), &path); + let syntax = builder.make_mut(syntax.clone()); if let Some(ref import_scope) = ImportScope::from(syntax.clone()) { - rewriter += insert_use(import_scope, path, ctx.config.insert_use); - builder.rewrite(rewriter); + insert_use(import_scope, path.clone(), ctx.config.insert_use); } + shorten_paths(syntax.clone(), &path.clone_for_update()); }, ) } /// Adds replacements to `re` that shorten `path` in all descendants of `node`. -fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: &ast::Path) { +fn shorten_paths(node: SyntaxNode, path: &ast::Path) { for child in node.children() { match_ast! { match child { @@ -62,32 +61,28 @@ fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: ast::Module(_it) => continue, ast::Path(p) => { - match maybe_replace_path(rewriter, p.clone(), path.clone()) { + match maybe_replace_path(p.clone(), path.clone()) { Some(()) => {}, - None => shorten_paths(rewriter, p.syntax().clone(), path), + None => shorten_paths(p.syntax().clone(), path), } }, - _ => shorten_paths(rewriter, child, path), + _ => shorten_paths(child, path), } } } } -fn maybe_replace_path( - rewriter: &mut SyntaxRewriter<'static>, - path: ast::Path, - target: ast::Path, -) -> Option<()> { +fn maybe_replace_path(path: ast::Path, target: ast::Path) -> Option<()> { if !path_eq(path.clone(), target) { return None; } // Shorten `path`, leaving only its last segment. if let Some(parent) = path.qualifier() { - rewriter.delete(parent.syntax()); + ted::remove(parent.syntax()); } if let Some(double_colon) = path.coloncolon_token() { - rewriter.delete(&double_colon); + ted::remove(&double_colon); } Some(()) @@ -150,6 +145,7 @@ Debug ", ); } + #[test] fn test_replace_add_use_no_anchor_with_item_below() { check_assist( -- cgit v1.2.3