diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 8e39cfc49c16..34b1a5895ea3 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -385,12 +385,7 @@ impl ArmsEdit { } syntax::NodeOrToken::Token(tok) => tok.prev_token(), }; - if let Some(prev) = prev - && prev.kind() == SyntaxKind::WHITESPACE - { - editor.delete(prev); - } - + editor.delete_whitespace(prev); editor.delete_all(range); } } diff --git a/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index eb74e9107581..1f6ae91c3a4f 100644 --- a/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -330,9 +330,7 @@ fn delete_rest_pat( let following = next_non_trivia_token(place.end().clone()).filter(|t| t.kind() == T![,]); let preceding = previous_non_trivia_token(place.start().clone()).filter(|t| t.kind() == T![,]); if let Some(comma) = following.or(preceding) { - if let Some(ws) = comma.next_token().filter(|t| t.kind() == SyntaxKind::WHITESPACE) { - editor.delete(ws); - } + editor.delete_whitespace(comma.next_token()); editor.delete(comma); } Some(()) 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 5e6e74bc9442..232a6b628e55 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 @@ -347,13 +347,7 @@ fn update_variant( editor.replace(variant.field_list()?.syntax(), field_list.syntax()); // remove any ws after the name - if let Some(ws) = name - .syntax() - .siblings_with_tokens(syntax::Direction::Next) - .find_map(|tok| tok.into_token().filter(|tok| tok.kind() == WHITESPACE)) - { - editor.delete(ws); - } + editor.delete_whitespace(name.syntax().next_sibling_or_token()); Some(()) } diff --git a/crates/ide-assists/src/handlers/generate_trait_from_impl.rs b/crates/ide-assists/src/handlers/generate_trait_from_impl.rs index 12afd9ae6aff..ea6de7729e18 100644 --- a/crates/ide-assists/src/handlers/generate_trait_from_impl.rs +++ b/crates/ide-assists/src/handlers/generate_trait_from_impl.rs @@ -1,7 +1,7 @@ use crate::assist_context::{AssistContext, Assists}; use ide_db::{assists::AssistId, defs::Definition, search::SearchScope}; use syntax::{ - AstNode, AstToken, SyntaxKind, T, + AstNode, AstToken, T, ast::{ self, HasDocComments, HasGenericParams, HasName, HasVisibility, edit::AstNodeEdit, syntax_factory::SyntaxFactory, @@ -211,26 +211,17 @@ fn trait_name(items: &ast::AssocItemList, make: &SyntaxFactory) -> ast::Name { /// `E0449` Trait items always share the visibility of their trait 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() - && token.kind() == SyntaxKind::WHITESPACE - { - editor.delete(token); - } - if let Some(vis) = has_vis.visibility() { - editor.delete(vis.syntax()); - } + if let Some(has_vis) = ast::AnyHasVisibility::cast(item.syntax().clone()) + && let Some(vis) = has_vis.visibility() + { + editor.delete_whitespace(vis.syntax().next_sibling_or_token()); + editor.delete(vis.syntax()); } } 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 - { - editor.delete(next); - } + editor.delete_whitespace(doc.syntax().next_token()); editor.delete(doc.syntax()); } } @@ -242,11 +233,7 @@ fn strip_body(editor: &SyntaxEditor, item: &ast::AssocItem) { { // In contrast to function bodies, we want to see no ws before a semicolon. // So let's remove them if we see any. - if let Some(prev) = body.syntax().prev_sibling_or_token() - && prev.kind() == SyntaxKind::WHITESPACE - { - editor.delete(prev); - } + editor.delete_whitespace(body.syntax().prev_sibling_or_token()); editor.replace(body.syntax(), make.token(T![;])); }; diff --git a/crates/ide-assists/src/handlers/remove_else_branches.rs b/crates/ide-assists/src/handlers/remove_else_branches.rs index a40d691e4cc3..5c4e56d33a40 100644 --- a/crates/ide-assists/src/handlers/remove_else_branches.rs +++ b/crates/ide-assists/src/handlers/remove_else_branches.rs @@ -1,4 +1,4 @@ -use syntax::{AstNode, SyntaxKind, T, TextRange, ast}; +use syntax::{AstNode, T, TextRange, ast}; use crate::{AssistContext, AssistId, Assists}; @@ -56,14 +56,8 @@ pub(crate) fn remove_else_branches(acc: &mut Assists, ctx: &AssistContext<'_, '_ target, |builder| { let editor = builder.make_editor(&else_token.parent().unwrap()); - match else_token.prev_token() { - Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), - _ => (), - } - match else_token.next_token() { - Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), - _ => (), - } + editor.delete_whitespace(else_token.prev_token()); + editor.delete_whitespace(else_token.next_token()); editor.delete(else_token); editor.delete(else_branches); builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/crates/ide-assists/src/handlers/remove_mut.rs b/crates/ide-assists/src/handlers/remove_mut.rs index db379809c5c8..f25c6bec1b51 100644 --- a/crates/ide-assists/src/handlers/remove_mut.rs +++ b/crates/ide-assists/src/handlers/remove_mut.rs @@ -1,4 +1,4 @@ -use syntax::{SyntaxKind, T}; +use syntax::T; use crate::{AssistContext, AssistId, Assists}; @@ -23,10 +23,7 @@ pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Opti let target = mut_token.text_range(); acc.add(AssistId::refactor("remove_mut"), "Remove `mut` keyword", target, |builder| { let editor = builder.make_editor(&mut_token.parent().unwrap()); - match mut_token.next_token() { - Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), - _ => (), - } + editor.delete_whitespace(mut_token.next_token()); editor.delete(mut_token); builder.add_file_edits(ctx.vfs_file_id(), editor); }) diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 4e85b30b5818..8bb2a6a70c2d 100644 --- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -4,9 +4,7 @@ use ide_db::{ }; use itertools::Itertools; use syntax::{ - Edition, - SyntaxKind::WHITESPACE, - T, + Edition, T, ast::{self, AstNode, HasName, syntax_factory::SyntaxFactory}, syntax_editor::{Position, SyntaxEditor}, }; @@ -299,13 +297,7 @@ fn update_attribute( editor.replace(old_tree.syntax(), new_tree.syntax()); } else { // Remove the attr and any trailing whitespace - - if let Some(line_break) = - attr.syntax().next_sibling_or_token().filter(|t| t.kind() == WHITESPACE) - { - editor.delete(line_break) - } - + editor.delete_whitespace(attr.syntax().next_sibling_or_token()); editor.delete(attr.syntax()) } } diff --git a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index 50d6f6d62cb3..33ed96894546 100644 --- a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -422,11 +422,7 @@ fn let_and_guard( if let Some(rhs) = left_bin.rhs() { editor.replace(left_bin.syntax(), rhs.syntax()); } else { - if let Some(next) = left_bin.syntax().next_sibling_or_token() - && next.kind() == SyntaxKind::WHITESPACE - { - editor.delete(next); - } + editor.delete_whitespace(left_bin.syntax().next_sibling_or_token()); editor.delete(left_bin.syntax()); } diff --git a/crates/ide-assists/src/handlers/unwrap_branch.rs b/crates/ide-assists/src/handlers/unwrap_branch.rs index bc296b05d485..fa175de0df7d 100644 --- a/crates/ide-assists/src/handlers/unwrap_branch.rs +++ b/crates/ide-assists/src/handlers/unwrap_branch.rs @@ -158,9 +158,8 @@ fn delete_else_before(container: SyntaxNode, editor: &SyntaxEditor) { else { return; }; - itertools::chain(else_token.prev_token(), else_token.next_token()) - .filter(|it| it.kind() == SyntaxKind::WHITESPACE) - .for_each(|it| editor.delete(it)); + editor.delete_whitespace(else_token.prev_token()); + editor.delete_whitespace(else_token.next_token()); let indent = IndentLevel::from_node(&container); let newline = make.whitespace(&format!("\n{indent}")); editor.replace(else_token, newline); diff --git a/crates/ide-assists/src/handlers/unwrap_return_type.rs b/crates/ide-assists/src/handlers/unwrap_return_type.rs index e53b73bad664..9c2a1f22f95a 100644 --- a/crates/ide-assists/src/handlers/unwrap_return_type.rs +++ b/crates/ide-assists/src/handlers/unwrap_return_type.rs @@ -4,7 +4,7 @@ use ide_db::{ syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ - AstNode, NodeOrToken, SyntaxKind, + AstNode, ast::{self, HasArgList, HasGenericArgs}, match_ast, }; @@ -82,12 +82,7 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_, '_>) let is_unit_type = is_unit_type(&happy_type); if is_unit_type { - if let Some(NodeOrToken::Token(token)) = ret_type.syntax().next_sibling_or_token() - && token.kind() == SyntaxKind::WHITESPACE - { - editor.delete(token); - } - + editor.delete_whitespace(ret_type.syntax().next_sibling_or_token()); editor.delete(ret_type.syntax()); } else { editor.replace(type_ref.syntax(), happy_type.syntax()); @@ -118,13 +113,8 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_, '_>) ); match tail_parent { Some(Either::Left(_expr)) => { - if let Some(ws) = tail_expr - .syntax() - .prev_sibling_or_token() - .filter(|e| e.kind() == SyntaxKind::WHITESPACE) - { - editor.delete(ws); - } + editor + .delete_whitespace(tail_expr.syntax().prev_sibling_or_token()); editor.delete(tail_expr.syntax()); } Some(Either::Right(stmt_list)) => { diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index a705bca63fbc..c15dc00e860b 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -330,7 +330,10 @@ fn get_transformed_fn( ); } } - editor.delete(fn_.async_token()?); + if let Some(async_token) = fn_.async_token() { + editor.delete_whitespace(async_token.next_token()); + editor.delete(&async_token); + } } AsyncSugaring::Resugar => { let ty = fn_.ret_type()?.ty()?; @@ -1727,7 +1730,7 @@ trait DesugaredAsyncTrait { } impl DesugaredAsyncTrait for () { - fn foo(&self) -> impl Future { + fn foo(&self) -> impl Future { $0 } } diff --git a/crates/syntax/src/syntax_editor.rs b/crates/syntax/src/syntax_editor.rs index 7d15195c6f1f..bd38ee5d6ac7 100644 --- a/crates/syntax/src/syntax_editor.rs +++ b/crates/syntax/src/syntax_editor.rs @@ -126,6 +126,14 @@ impl SyntaxEditor { self.insert_all(position, elements) } + pub fn delete_whitespace(&self, element: Option) { + let Some(element) = element.map(Element::syntax_element) else { return }; + + if element.kind() == SyntaxKind::WHITESPACE { + self.delete(element); + } + } + pub fn delete(&self, element: impl Element) { let element = element.syntax_element(); debug_assert!(is_ancestor_or_self_of_element(&element, &self.root));