Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #17993 - ChayimFriedman2:convert-to-tuple-attrs, r=Veykril
Consider field attributes when converting from tuple to named struct and the opposite Fixes #17983. I tried to use the `SourceChangeBuilder::make_mut()` API, but it duplicated the attribute...
bors 2024-08-29
parent 5350c65 · parent 1fc6cbc · commit d5a424f
-rw-r--r--crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs31
-rw-r--r--crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs29
2 files changed, 49 insertions, 11 deletions
diff --git a/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
index 3705597927..8d4ff84084 100644
--- a/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
+++ b/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
@@ -2,8 +2,8 @@ use either::Either;
use ide_db::{defs::Definition, search::FileReference};
use itertools::Itertools;
use syntax::{
- ast::{self, AstNode, HasGenericParams, HasVisibility},
- match_ast, SyntaxKind,
+ ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility},
+ match_ast, ted, SyntaxKind,
};
use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
@@ -87,9 +87,14 @@ fn edit_struct_def(
) {
// Note that we don't need to consider macro files in this function because this is
// currently not triggered for struct definitions inside macro calls.
- let tuple_fields = record_fields
- .fields()
- .filter_map(|f| Some(ast::make::tuple_field(f.visibility(), f.ty()?)));
+ let tuple_fields = record_fields.fields().filter_map(|f| {
+ let field = ast::make::tuple_field(f.visibility(), f.ty()?).clone_for_update();
+ ted::insert_all(
+ ted::Position::first_child_of(field.syntax()),
+ f.attrs().map(|attr| attr.syntax().clone_subtree().clone_for_update().into()).collect(),
+ );
+ Some(field)
+ });
let tuple_fields = ast::make::tuple_field_list(tuple_fields);
let record_fields_text_range = record_fields.syntax().text_range();
@@ -978,4 +983,20 @@ impl HasAssoc for Struct {
"#,
);
}
+
+ #[test]
+ fn fields_with_attrs() {
+ check_assist(
+ convert_named_struct_to_tuple_struct,
+ r#"
+pub struct $0Foo {
+ #[my_custom_attr]
+ value: u32,
+}
+"#,
+ r#"
+pub struct Foo(#[my_custom_attr] u32);
+"#,
+ );
+ }
}
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 c72bd411d6..f01b4ea0fd 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
@@ -1,8 +1,8 @@
use either::Either;
use ide_db::defs::{Definition, NameRefClass};
use syntax::{
- ast::{self, AstNode, HasGenericParams, HasVisibility},
- match_ast, SyntaxKind, SyntaxNode,
+ ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility},
+ match_ast, ted, SyntaxKind, SyntaxNode,
};
use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
@@ -83,10 +83,14 @@ fn edit_struct_def(
tuple_fields: ast::TupleFieldList,
names: Vec<ast::Name>,
) {
- let record_fields = tuple_fields
- .fields()
- .zip(names)
- .filter_map(|(f, name)| Some(ast::make::record_field(f.visibility(), name, f.ty()?)));
+ let record_fields = tuple_fields.fields().zip(names).filter_map(|(f, name)| {
+ let field = ast::make::record_field(f.visibility(), name, f.ty()?).clone_for_update();
+ ted::insert_all(
+ ted::Position::first_child_of(field.syntax()),
+ f.attrs().map(|attr| attr.syntax().clone_subtree().clone_for_update().into()).collect(),
+ );
+ Some(field)
+ });
let record_fields = ast::make::record_field_list(record_fields);
let tuple_fields_text_range = tuple_fields.syntax().text_range();
@@ -907,4 +911,17 @@ where
"#,
);
}
+
+ #[test]
+ fn fields_with_attrs() {
+ check_assist(
+ convert_tuple_struct_to_named_struct,
+ r#"
+pub struct $0Foo(#[my_custom_attr] u32);
+"#,
+ r#"
+pub struct Foo { #[my_custom_attr] field1: u32 }
+"#,
+ );
+ }
}