Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #16766 - roife:fix-issue-15198, r=Veykril
fix: keep attributes in assist 'generate_delegate_trait'
fix #15198.
This PR address the issue that `impl` generated by `generate_delegate_trait` doesn't keep attributes.
| -rw-r--r-- | crates/ide-assists/src/handlers/generate_delegate_trait.rs | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/crates/ide-assists/src/handlers/generate_delegate_trait.rs index e0bcd78c99..748acb46ef 100644 --- a/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -16,7 +16,8 @@ use syntax::{ ast::{ self, edit::{self, AstNodeEdit}, - make, AssocItem, GenericArgList, GenericParamList, HasGenericParams, HasName, + edit_in_place::AttrsOwnerEdit, + make, AssocItem, GenericArgList, GenericParamList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, HasVisibility as astHasVisibility, Path, WherePred, }, ted::{self, Position}, @@ -619,7 +620,8 @@ fn process_assoc_item( qual_path_ty: ast::Path, base_name: &str, ) -> Option<ast::AssocItem> { - match item { + let attrs = item.attrs(); + let assoc = match item { AssocItem::Const(c) => const_assoc_item(c, qual_path_ty), AssocItem::Fn(f) => func_assoc_item(f, qual_path_ty, base_name), AssocItem::MacroCall(_) => { @@ -628,7 +630,18 @@ fn process_assoc_item( None } AssocItem::TypeAlias(ta) => ty_assoc_item(ta, qual_path_ty), + }; + if let Some(assoc) = &assoc { + attrs.for_each(|attr| { + assoc.add_attr(attr.clone()); + // fix indentations + if let Some(tok) = attr.syntax().next_sibling_or_token() { + let pos = Position::after(tok); + ted::insert(pos, make::tokens::whitespace(" ")); + } + }) } + assoc } fn const_assoc_item(item: syntax::ast::Const, qual_path_ty: ast::Path) -> Option<AssocItem> { @@ -1703,4 +1716,65 @@ impl some_module::SomeTrait for B { }"#, ) } + + #[test] + fn test_fn_with_attrs() { + check_assist( + generate_delegate_trait, + r#" +struct A; + +trait T { + #[cfg(test)] + fn f(&self, a: u32); + #[cfg(not(test))] + fn f(&self, a: bool); +} + +impl T for A { + #[cfg(test)] + fn f(&self, a: u32) {} + #[cfg(not(test))] + fn f(&self, a: bool) {} +} + +struct B { + a$0: A, +} +"#, + r#" +struct A; + +trait T { + #[cfg(test)] + fn f(&self, a: u32); + #[cfg(not(test))] + fn f(&self, a: bool); +} + +impl T for A { + #[cfg(test)] + fn f(&self, a: u32) {} + #[cfg(not(test))] + fn f(&self, a: bool) {} +} + +struct B { + a: A, +} + +impl T for B { + #[cfg(test)] + fn f(&self, a: u32) { + <A as T>::f(&self.a, a) + } + + #[cfg(not(test))] + fn f(&self, a: bool) { + <A as T>::f(&self.a, a) + } +} +"#, + ); + } } |