diff --git a/crates/ide_assists/src/utils.rs b/crates/ide_assists/src/utils.rs index edbc6dd609..c5540fa842 100644 --- a/crates/ide_assists/src/utils.rs +++ b/crates/ide_assists/src/utils.rs @@ -130,7 +130,8 @@ pub fn add_trait_assoc_items_to_impl( let items = items.into_iter().map(|assoc_item| { let assoc_item = assoc_item.clone_for_update(); transform.apply(assoc_item.syntax()); - edit::remove_attrs_and_docs(&assoc_item).clone_subtree().clone_for_update() + edit::remove_attrs_and_docs(&assoc_item); + assoc_item }); let res = impl_.clone_for_update(); diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs index 75b02583bf..aa110b0899 100644 --- a/crates/ide_completion/src/completions/trait_impl.rs +++ b/crates/ide_completion/src/completions/trait_impl.rs @@ -194,10 +194,10 @@ fn get_transformed_assoc_item( ); transform.apply(assoc_item.syntax()); - Some(match assoc_item { - ast::AssocItem::Fn(func) => ast::AssocItem::Fn(edit::remove_attrs_and_docs(&func)), - _ => assoc_item, - }) + if let ast::AssocItem::Fn(func) = &assoc_item { + edit::remove_attrs_and_docs(func) + } + Some(assoc_item) } fn add_type_alias_impl( @@ -253,7 +253,7 @@ fn add_const_impl( } fn make_const_compl_syntax(const_: &ast::Const) -> String { - let const_ = edit::remove_attrs_and_docs(const_); + edit::remove_attrs_and_docs(const_); let const_start = const_.syntax().text_range().start(); let const_end = const_.syntax().text_range().end(); diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 91ab01ca4e..904a38471e 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs @@ -1,6 +1,6 @@ //! Collection of assorted algorithms for syntax trees. -use std::{hash::BuildHasherDefault, ops::RangeInclusive}; +use std::hash::BuildHasherDefault; use indexmap::IndexMap; use itertools::Itertools; @@ -295,41 +295,6 @@ fn _insert_children( with_children(parent, new_children) } -/// Replaces all nodes in `to_delete` with nodes from `to_insert` -/// -/// This is a type-unsafe low-level editing API, if you need to use it, -/// prefer to create a type-safe abstraction on top of it instead. -pub fn replace_children( - parent: &SyntaxNode, - to_delete: RangeInclusive, - to_insert: impl IntoIterator, -) -> SyntaxNode { - let mut to_insert = to_insert.into_iter(); - _replace_children(parent, to_delete, &mut to_insert) -} - -fn _replace_children( - parent: &SyntaxNode, - to_delete: RangeInclusive, - to_insert: &mut dyn Iterator, -) -> SyntaxNode { - let start = position_of_child(parent, to_delete.start().clone()); - let end = position_of_child(parent, to_delete.end().clone()); - let parent_green = parent.green(); - let mut old_children = parent_green.children().map(|it| match it { - NodeOrToken::Token(it) => NodeOrToken::Token(it.to_owned()), - NodeOrToken::Node(it) => NodeOrToken::Node(it.to_owned()), - }); - - let before = old_children.by_ref().take(start).collect::>(); - let new_children = before - .into_iter() - .chain(to_insert.map(to_green_element)) - .chain(old_children.skip(end + 1 - start)) - .collect::>(); - with_children(parent, new_children) -} - fn with_children( parent: &SyntaxNode, new_children: Vec>, diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index af440426a6..01d6add36d 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs @@ -48,22 +48,26 @@ impl ast::UseTree { } } -#[must_use] -pub fn remove_attrs_and_docs(node: &N) -> N { - N::cast(remove_attrs_and_docs_inner(node.syntax().clone())).unwrap() +pub fn remove_attrs_and_docs(node: &N) { + remove_attrs_and_docs_inner(node.syntax()) } -fn remove_attrs_and_docs_inner(mut node: SyntaxNode) -> SyntaxNode { - while let Some(start) = - node.children_with_tokens().find(|it| it.kind() == ATTR || it.kind() == COMMENT) - { - let end = match &start.next_sibling_or_token() { - Some(el) if el.kind() == WHITESPACE => el.clone(), - Some(_) | None => start.clone(), - }; - node = algo::replace_children(&node, start..=end, &mut iter::empty()); +fn remove_attrs_and_docs_inner(node: &SyntaxNode) { + let mut remove_next_ws = false; + for child in node.children_with_tokens() { + match child.kind() { + ATTR | COMMENT => { + remove_next_ws = true; + child.detach(); + continue; + } + WHITESPACE if remove_next_ws => { + child.detach(); + } + _ => (), + } + remove_next_ws = false; } - node } #[derive(Debug, Clone, Copy)]