Unnamed repository; edit this file 'description' to name the repository.
internal: address review feedback for inline_call SyntaxEditor migration
| -rw-r--r-- | crates/ide-assists/src/handlers/inline_call.rs | 62 | ||||
| -rw-r--r-- | crates/ide-assists/src/handlers/inline_type_alias.rs | 10 | ||||
| -rw-r--r-- | crates/ide-db/src/imports/insert_use.rs | 11 |
3 files changed, 37 insertions, 46 deletions
diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs index f4ba213e33..60ab364795 100644 --- a/crates/ide-assists/src/handlers/inline_call.rs +++ b/crates/ide-assists/src/handlers/inline_call.rs @@ -10,9 +10,9 @@ use ide_db::{ EditionedFileId, RootDatabase, base_db::Crate, defs::Definition, + imports::insert_use::remove_use_tree_if_simple, path_transform::PathTransform, search::{FileReference, FileReferenceNode, SearchScope}, - source_change::SourceChangeBuilder, syntax_helpers::{node_ext::expr_as_name_ref, prettify_macro_expansion}, }; use itertools::{Itertools, izip}; @@ -22,6 +22,7 @@ use syntax::{ self, HasArgList, HasGenericArgs, Pat, PathExpr, edit::{AstNodeEdit, IndentLevel}, make, + syntax_factory::SyntaxFactory, }, syntax_editor::SyntaxEditor, }; @@ -108,25 +109,11 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> let mut remove_def = true; let mut inline_refs_for_file = |file_id: EditionedFileId, refs: Vec<FileReference>| { - use syntax::syntax_editor::Removable; - let file_id = file_id.file_id(ctx.db()); builder.edit_file(file_id); let call_krate = ctx.sema.file_to_module_def(file_id).map(|it| it.krate(ctx.db())); let count = refs.len(); - // Split refs into call-site name refs and use-tree paths - let (name_refs, use_trees): (Vec<ast::NameRef>, Vec<ast::UseTree>) = refs - .into_iter() - .filter_map(|file_ref| match file_ref.name { - FileReferenceNode::NameRef(name_ref) => Some(name_ref), - _ => None, - }) - .partition_map(|name_ref| { - match name_ref.syntax().ancestors().find_map(ast::UseTree::cast) { - Some(use_tree) => Either::Right(use_tree), - None => Either::Left(name_ref), - } - }); + let (name_refs, use_trees) = split_refs_and_uses(refs, Some); let call_infos: Vec<_> = name_refs .into_iter() .filter_map(|it| CallInfo::from_name_ref(it, call_krate?.into())) @@ -134,8 +121,12 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> // directly inlining into macros may cause errors. .filter(|call_info| !ctx.sema.hir_file_for(call_info.node.syntax()).is_macro()) .collect(); - if let Some(first) = call_infos.first() { - let mut editor = builder.make_editor(first.node.syntax()); + let anchor = call_infos + .first() + .map(|ci| ci.node.syntax().clone()) + .or_else(|| use_trees.first().map(|ut| ut.syntax().clone())); + if let Some(anchor) = anchor { + let mut editor = builder.make_editor(&anchor); let replaced = call_infos .into_iter() .map(|call_info| { @@ -148,16 +139,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> if replaced + use_trees.len() == count { // we replaced all usages in this file, so we can remove the imports for use_tree in &use_trees { - if use_tree.use_tree_list().is_some() || use_tree.star_token().is_some() - { - continue; - } - if let Some(use_) = use_tree.syntax().parent().and_then(ast::Use::cast) - { - use_.remove(&mut editor); - } else { - use_tree.remove(&mut editor); - } + remove_use_tree_if_simple(use_tree, &mut editor); } } else { remove_def = false; @@ -184,17 +166,16 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> } pub(super) fn split_refs_and_uses<T: ast::AstNode>( - builder: &mut SourceChangeBuilder, iter: impl IntoIterator<Item = FileReference>, mut map_ref: impl FnMut(ast::NameRef) -> Option<T>, -) -> (Vec<T>, Vec<ast::Path>) { +) -> (Vec<T>, Vec<ast::UseTree>) { iter.into_iter() .filter_map(|file_ref| match file_ref.name { FileReferenceNode::NameRef(name_ref) => Some(name_ref), _ => None, }) .filter_map(|name_ref| match name_ref.syntax().ancestors().find_map(ast::UseTree::cast) { - Some(use_tree) => builder.make_mut(use_tree).path().map(Either::Right), + Some(use_tree) => Some(Either::Right(use_tree)), None => map_ref(name_ref).map(Either::Left), }) .partition_map(|either| either) @@ -443,7 +424,7 @@ fn inline( .filter(|tok| tok.kind() == SyntaxKind::SELF_TYPE_KW) .collect(); for self_tok in self_tokens { - let mut replace_with = t.clone_subtree().syntax().clone_subtree(); + let mut replace_with = t.syntax().clone_subtree(); if !is_in_type_path(&self_tok) && let Some(ty) = ast::Type::cast(replace_with.clone()) && let Some(generic_arg_list) = ty.generic_arg_list() @@ -550,7 +531,6 @@ fn inline( for usage in &self_token_usages { let this_token = make::name_ref("this") .syntax() - .clone_subtree() .first_token() .expect("NameRef should have had a token."); editor.replace(usage.clone(), this_token); @@ -565,13 +545,14 @@ fn inline( if let Some(field) = path_expr_as_record_field(usage) { cov_mark::hit!(inline_call_inline_direct_field); let field_name = field.field_name().unwrap(); - let new_field = make::record_expr_field( - make::name_ref(&field_name.text()), + let factory = SyntaxFactory::without_mappings(); + let new_field = factory.record_expr_field( + factory.name_ref(&field_name.text()), Some(replacement.clone()), ); editor.replace(field.syntax(), new_field.syntax()); } else { - editor.replace(usage.syntax(), replacement.syntax().clone_subtree()); + editor.replace(usage.syntax(), replacement.syntax()); } }; @@ -629,6 +610,7 @@ fn inline( body = new_body; } + let factory = SyntaxFactory::without_mappings(); let is_async_fn = function.is_async(sema.db); if is_async_fn { cov_mark::hit!(inline_call_async_fn); @@ -638,12 +620,12 @@ fn inline( if !let_stmts.is_empty() { cov_mark::hit!(inline_call_async_fn_with_let_stmts); body = body.indent(IndentLevel(1)); - body = make::block_expr(let_stmts, Some(body.into())); + body = factory.block_expr(let_stmts, Some(body.into())); } } else if !let_stmts.is_empty() { // Prepend let statements to the body's existing statements let stmts: Vec<ast::Stmt> = let_stmts.into_iter().chain(body.statements()).collect(); - body = make::block_expr(stmts, body.tail_expr()); + body = factory.block_expr(stmts, body.tail_expr()); } let original_indentation = match node { @@ -655,7 +637,7 @@ fn inline( let no_stmts = body.statements().next().is_none(); match body.tail_expr() { Some(expr) if matches!(expr, ast::Expr::ClosureExpr(_)) && no_stmts => { - make::expr_paren(expr).into() + factory.expr_paren(expr).into() } Some(expr) if !is_async_fn && no_stmts => expr, _ => match node @@ -665,7 +647,7 @@ fn inline( .and_then(|bin_expr| bin_expr.lhs()) { Some(lhs) if lhs.syntax() == node.syntax() => { - make::expr_paren(ast::Expr::BlockExpr(body)).into() + factory.expr_paren(ast::Expr::BlockExpr(body)).into() } _ => ast::Expr::BlockExpr(body), }, diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs index 6d8750afdc..9d3c334a51 100644 --- a/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -5,7 +5,8 @@ use hir::{HasSource, PathResolution}; use ide_db::FxHashMap; use ide_db::{ - defs::Definition, imports::insert_use::ast_to_remove_for_path_in_use_stmt, + defs::Definition, + imports::insert_use::remove_use_tree_if_simple, search::FileReference, }; use itertools::Itertools; @@ -73,13 +74,12 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) let editor = builder.make_editor(source.syntax()); let (path_types, path_type_uses) = - split_refs_and_uses(builder, refs, |path_type| { + split_refs_and_uses(refs, |path_type| { path_type.syntax().ancestors().nth(3).and_then(ast::PathType::cast) }); path_type_uses .iter() - .flat_map(ast_to_remove_for_path_in_use_stmt) - .for_each(|x| editor.delete(x.syntax())); + .for_each(|use_tree| remove_use_tree_if_simple(use_tree, &mut editor)); for (target, replacement) in path_types.into_iter().filter_map(|path_type| { let replacement = @@ -1094,7 +1094,6 @@ fn f() -> Vec<&str> { } //- /foo.rs - fn foo() { let _: Vec<i8> = Vec::new(); } @@ -1123,7 +1122,6 @@ mod foo; //- /foo.rs - fn foo() { let _: i32 = 0; } diff --git a/crates/ide-db/src/imports/insert_use.rs b/crates/ide-db/src/imports/insert_use.rs index fe30a4dc5c..4c4a01a157 100644 --- a/crates/ide-db/src/imports/insert_use.rs +++ b/crates/ide-db/src/imports/insert_use.rs @@ -347,6 +347,17 @@ pub fn remove_path_if_in_use_stmt(path: &ast::Path) { } } +pub fn remove_use_tree_if_simple(use_tree: &ast::UseTree, editor: &mut SyntaxEditor) { + if use_tree.use_tree_list().is_some() || use_tree.star_token().is_some() { + return; + } + if let Some(use_) = use_tree.syntax().parent().and_then(ast::Use::cast) { + syntax::syntax_editor::Removable::remove(&use_, editor); + } else { + syntax::syntax_editor::Removable::remove(use_tree, editor); + } +} + #[derive(Eq, PartialEq, PartialOrd, Ord)] enum ImportGroup { // the order here defines the order of new group inserts |