Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs82
1 files changed, 30 insertions, 52 deletions
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 dfb5652126..3738718b3c 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
@@ -101,21 +101,21 @@ pub(crate) fn extract_struct_from_enum_variant(
});
}
- let indent = enum_ast.indent_level();
let generic_params = enum_ast
.generic_param_list()
.and_then(|known_generics| extract_generic_params(&known_generics, &field_list));
let generics = generic_params.as_ref().map(|generics| generics.clone_for_update());
- let def =
- create_struct_def(variant_name.clone(), &variant, &field_list, generics, &enum_ast);
+ let def = create_struct_def(variant_name.clone(), &field_list, generics, &enum_ast);
+
+ let enum_ast = variant.parent_enum();
+ let indent = enum_ast.indent_level();
def.reindent_to(indent);
- let start_offset = &variant.parent_enum().syntax().clone();
- ted::insert_all_raw(
- ted::Position::before(start_offset),
+ ted::insert_all(
+ ted::Position::before(enum_ast.syntax()),
vec![
def.syntax().clone().into(),
- make::tokens::whitespace(&format!("\n\n{}", indent)).into(),
+ make::tokens::whitespace(&format!("\n\n{indent}")).into(),
],
);
@@ -227,8 +227,7 @@ fn tag_generics_in_variant(ty: &ast::Type, generics: &mut [(ast::GenericParam, b
}
fn create_struct_def(
- variant_name: ast::Name,
- variant: &ast::Variant,
+ name: ast::Name,
field_list: &Either<ast::RecordFieldList, ast::TupleFieldList>,
generics: Option<ast::GenericParamList>,
enum_: &ast::Enum,
@@ -269,37 +268,9 @@ fn create_struct_def(
field_list.into()
}
};
-
field_list.reindent_to(IndentLevel::single());
- let strukt = make::struct_(enum_vis, variant_name, generics, field_list).clone_for_update();
-
- // FIXME: Consider making this an actual function somewhere (like in `AttrsOwnerEdit`) after some deliberation
- let attrs_and_docs = |node: &SyntaxNode| {
- let mut select_next_ws = false;
- node.children_with_tokens().filter(move |child| {
- let accept = match child.kind() {
- ATTR | COMMENT => {
- select_next_ws = true;
- return true;
- }
- WHITESPACE if select_next_ws => true,
- _ => false,
- };
- select_next_ws = false;
-
- accept
- })
- };
-
- // copy attributes & comments from variant
- let variant_attrs = attrs_and_docs(variant.syntax())
- .map(|tok| match tok.kind() {
- WHITESPACE => make::tokens::single_newline().into(),
- _ => tok,
- })
- .collect();
- ted::insert_all(ted::Position::first_child_of(strukt.syntax()), variant_attrs);
+ let strukt = make::struct_(enum_vis, name, generics, field_list).clone_for_update();
// copy attributes from enum
ted::insert_all(
@@ -346,13 +317,20 @@ fn update_variant(variant: &ast::Variant, generics: Option<ast::GenericParamList
})
.unwrap_or_else(|| make::ty(&name.text()));
+ // change from a record to a tuple field list
let tuple_field = make::tuple_field(None, ty);
- let replacement = make::variant(
- name,
- Some(ast::FieldList::TupleFieldList(make::tuple_field_list(iter::once(tuple_field)))),
- )
- .clone_for_update();
- ted::replace(variant.syntax(), replacement.syntax());
+ let field_list = make::tuple_field_list(iter::once(tuple_field)).clone_for_update();
+ ted::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))
+ {
+ ted::remove(SyntaxElement::Token(ws));
+ }
+
Some(())
}
@@ -628,15 +606,15 @@ enum A {
}
}"#,
r#"
-/* comment */
-// other
-/// comment
-#[attr]
struct One{
a: u32
}
enum A {
+ /* comment */
+ // other
+ /// comment
+ #[attr]
One(One)
}"#,
);
@@ -655,13 +633,13 @@ enum A {
$0One(u32, u32)
}"#,
r#"
-/* comment */
-// other
-/// comment
-#[attr]
struct One(u32, u32);
enum A {
+ /* comment */
+ // other
+ /// comment
+ #[attr]
One(One)
}"#,
);