From c1a4ba55d7f17379fbbde480550174d7fe0ff04a Mon Sep 17 00:00:00 2001 From: roife Date: Fri, 19 Apr 2024 21:31:54 +0800 Subject: [PATCH] fix: add a separate setting for enum variants --- .../rust-analyzer/crates/hir/src/display.rs | 66 ++++++++-- .../rust-analyzer/crates/ide/src/hover.rs | 3 +- .../crates/ide/src/hover/render.rs | 9 +- .../crates/ide/src/hover/tests.rs | 123 +++++++++++++----- .../crates/ide/src/static_index.rs | 3 +- .../crates/rust-analyzer/src/config.rs | 9 +- .../docs/user/generated_config.adoc | 9 +- .../rust-analyzer/editors/code/package.json | 13 +- 8 files changed, 183 insertions(+), 52 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index ec57708a084..42fafd4ee80 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs @@ -188,7 +188,7 @@ impl HirDisplay for Struct { StructKind::Record => { let has_where_clause = write_where_clause(def_id, f)?; if let Some(limit) = f.entity_limit { - display_fields_or_variants(&self.fields(f.db), has_where_clause, limit, f)?; + display_fields(&self.fields(f.db), has_where_clause, limit, f)?; } } StructKind::Unit => _ = write_where_clause(def_id, f)?, @@ -208,7 +208,7 @@ impl HirDisplay for Enum { let has_where_clause = write_where_clause(def_id, f)?; if let Some(limit) = f.entity_limit { - display_fields_or_variants(&self.variants(f.db), has_where_clause, limit, f)?; + display_variants(&self.variants(f.db), has_where_clause, limit, f)?; } Ok(()) @@ -225,35 +225,83 @@ impl HirDisplay for Union { let has_where_clause = write_where_clause(def_id, f)?; if let Some(limit) = f.entity_limit { - display_fields_or_variants(&self.fields(f.db), has_where_clause, limit, f)?; + display_fields(&self.fields(f.db), has_where_clause, limit, f)?; } Ok(()) } } -fn display_fields_or_variants( - fields_or_variants: &[T], +fn display_fields( + fields: &[Field], has_where_clause: bool, limit: usize, f: &mut HirFormatter<'_>, ) -> Result<(), HirDisplayError> { - let count = fields_or_variants.len().min(limit); + let count = fields.len().min(limit); f.write_char(if !has_where_clause { ' ' } else { '\n' })?; if count == 0 { - if fields_or_variants.is_empty() { + if fields.is_empty() { f.write_str("{}")?; } else { f.write_str("{ /* … */ }")?; } } else { f.write_str("{\n")?; - for field in &fields_or_variants[..count] { + for field in &fields[..count] { f.write_str(" ")?; field.hir_fmt(f)?; f.write_str(",\n")?; } - if fields_or_variants.len() > count { + if fields.len() > count { + f.write_str(" /* … */\n")?; + } + f.write_str("}")?; + } + + Ok(()) +} + +fn display_variants( + variants: &[Variant], + has_where_clause: bool, + limit: usize, + f: &mut HirFormatter<'_>, +) -> Result<(), HirDisplayError> { + let count = variants.len().min(limit); + f.write_char(if !has_where_clause { ' ' } else { '\n' })?; + if count == 0 { + if variants.is_empty() { + f.write_str("{}")?; + } else { + f.write_str("{ /* … */ }")?; + } + } else { + f.write_str("{\n")?; + for variant in &variants[..count] { + f.write_str(" ")?; + write!(f, "{}", variant.name(f.db).display(f.db.upcast()))?; + match variant.kind(f.db) { + StructKind::Tuple => { + if variant.fields(f.db).is_empty() { + f.write_str("()")?; + } else { + f.write_str("( /* … */ )")?; + } + } + StructKind::Record => { + if variant.fields(f.db).is_empty() { + f.write_str(" {}")?; + } else { + f.write_str(" { /* … */ }")?; + } + } + StructKind::Unit => {} + } + f.write_str(",\n")?; + } + + if variants.len() > count { f.write_str(" /* … */\n")?; } f.write_str("}")?; diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index 2a2be6e4e0c..6958ae16230 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -33,7 +33,8 @@ pub struct HoverConfig { pub keywords: bool, pub format: HoverDocFormat, pub max_trait_assoc_items_count: Option, - pub max_adt_fields_or_variants_count: Option, + pub max_struct_or_union_fields_count: Option, + pub max_enum_variants_count: Option, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index e0a9907a413..1044a3f4c11 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -410,14 +410,17 @@ pub(super) fn definition( Definition::Trait(trait_) => { trait_.display_limited(db, config.max_trait_assoc_items_count).to_string() } - Definition::Adt(adt) => { - adt.display_limited(db, config.max_adt_fields_or_variants_count).to_string() + Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => { + adt.display_limited(db, config.max_struct_or_union_fields_count).to_string() + } + Definition::Adt(adt @ Adt::Enum(_)) => { + adt.display_limited(db, config.max_enum_variants_count).to_string() } Definition::SelfType(impl_def) => { let self_ty = &impl_def.self_ty(db); match self_ty.as_adt() { Some(adt) => { - adt.display_limited(db, config.max_adt_fields_or_variants_count).to_string() + adt.display_limited(db, config.max_struct_or_union_fields_count).to_string() } None => self_ty.display(db).to_string(), } diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 326c248b7a2..f17a0fa2cd9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -18,7 +18,8 @@ const HOVER_BASE_CONFIG: HoverConfig = HoverConfig { format: HoverDocFormat::Markdown, keywords: true, max_trait_assoc_items_count: None, - max_adt_fields_or_variants_count: Some(5), + max_struct_or_union_fields_count: Some(5), + max_enum_variants_count: Some(5), }; fn check_hover_no_result(ra_fixture: &str) { @@ -51,8 +52,8 @@ fn check(ra_fixture: &str, expect: Expect) { } #[track_caller] -fn check_hover_adt_fields_or_variants_limit( - count: Option, +fn check_hover_struct_or_union_fields_limit( + fields_count: impl Into>, ra_fixture: &str, expect: Expect, ) { @@ -61,7 +62,33 @@ fn check_hover_adt_fields_or_variants_limit( .hover( &HoverConfig { links_in_hover: true, - max_adt_fields_or_variants_count: count, + max_struct_or_union_fields_count: fields_count.into(), + ..HOVER_BASE_CONFIG + }, + FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) }, + ) + .unwrap() + .unwrap(); + + let content = analysis.db.file_text(position.file_id); + let hovered_element = &content[hover.range]; + + let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); + expect.assert_eq(&actual) +} + +#[track_caller] +fn check_hover_enum_variants_limit( + variants_count: impl Into>, + ra_fixture: &str, + expect: Expect, +) { + let (analysis, position) = fixture::position(ra_fixture); + let hover = analysis + .hover( + &HoverConfig { + links_in_hover: true, + max_enum_variants_count: variants_count.into(), ..HOVER_BASE_CONFIG }, FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) }, @@ -912,8 +939,8 @@ struct Foo$0 where u32: Copy { field: u32 } #[test] fn hover_record_struct_limit() { - check_hover_adt_fields_or_variants_limit( - Some(3), + check_hover_struct_or_union_fields_limit( + 3, r#" struct Foo$0 { a: u32, b: i32, c: i32 } "#, @@ -934,8 +961,8 @@ fn hover_record_struct_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( - Some(3), + check_hover_struct_or_union_fields_limit( + 3, r#" struct Foo$0 { a: u32 } "#, @@ -954,8 +981,8 @@ fn hover_record_struct_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( - Some(3), + check_hover_struct_or_union_fields_limit( + 3, r#" struct Foo$0 { a: u32, b: i32, c: i32, d: u32 } "#, @@ -977,7 +1004,7 @@ fn hover_record_struct_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( + check_hover_struct_or_union_fields_limit( None, r#" struct Foo$0 { a: u32, b: i32, c: i32 } @@ -995,8 +1022,8 @@ fn hover_record_struct_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( - Some(0), + check_hover_struct_or_union_fields_limit( + 0, r#" struct Foo$0 { a: u32, b: i32, c: i32 } "#, @@ -1017,8 +1044,8 @@ fn hover_record_struct_limit() { #[test] fn hover_enum_limit() { - check_hover_adt_fields_or_variants_limit( - Some(5), + check_hover_enum_variants_limit( + 5, r#"enum Foo$0 { A, B }"#, expect![[r#" *Foo* @@ -1036,8 +1063,8 @@ fn hover_enum_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( - Some(1), + check_hover_enum_variants_limit( + 1, r#"enum Foo$0 { A, B }"#, expect![[r#" *Foo* @@ -1055,8 +1082,8 @@ fn hover_enum_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( - Some(0), + check_hover_enum_variants_limit( + 0, r#"enum Foo$0 { A, B }"#, expect![[r#" *Foo* @@ -1071,7 +1098,7 @@ fn hover_enum_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( + check_hover_enum_variants_limit( None, r#"enum Foo$0 { A, B }"#, expect![[r#" @@ -1087,12 +1114,46 @@ fn hover_enum_limit() { ``` "#]], ); + check_hover_enum_variants_limit( + 7, + r#"enum Enum$0 { + Variant {}, + Variant2 { field: i32 }, + Variant3 { field: i32, field2: i32 }, + Variant4(), + Variant5(i32), + Variant6(i32, i32), + Variant7, + Variant8, + }"#, + expect![[r#" + *Enum* + + ```rust + test + ``` + + ```rust + // size = 12 (0xC), align = 4, niches = 4294967288 + enum Enum { + Variant {}, + Variant2 { /* … */ }, + Variant3 { /* … */ }, + Variant4(), + Variant5( /* … */ ), + Variant6( /* … */ ), + Variant7, + /* … */ + } + ``` + "#]], + ); } #[test] fn hover_union_limit() { - check_hover_adt_fields_or_variants_limit( - Some(5), + check_hover_struct_or_union_fields_limit( + 5, r#"union Foo$0 { a: u32, b: i32 }"#, expect![[r#" *Foo* @@ -1110,8 +1171,8 @@ fn hover_union_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( - Some(1), + check_hover_struct_or_union_fields_limit( + 1, r#"union Foo$0 { a: u32, b: i32 }"#, expect![[r#" *Foo* @@ -1129,8 +1190,8 @@ fn hover_union_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( - Some(0), + check_hover_struct_or_union_fields_limit( + 0, r#"union Foo$0 { a: u32, b: i32 }"#, expect![[r#" *Foo* @@ -1145,7 +1206,7 @@ fn hover_union_limit() { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( + check_hover_struct_or_union_fields_limit( None, r#"union Foo$0 { a: u32, b: i32 }"#, expect![[r#" @@ -1630,12 +1691,12 @@ impl Thing { ``` "#]], ); - check_hover_adt_fields_or_variants_limit( + check_hover_struct_or_union_fields_limit( None, r#" struct Thing { x: u32 } impl Thing { - fn new() -> Self { Self$0 { x: 0 } } + fn new() -> Self$0 { Self { x: 0 } } } "#, expect![[r#" @@ -2599,8 +2660,8 @@ fn test_hover_layout_of_enum() { ```rust // size = 16 (0x10), align = 8, niches = 254 enum Foo { - Variant1(u8, u16), - Variant2(i32, u8, i64), + Variant1( /* … */ ), + Variant2( /* … */ ), } ``` "#]], diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 1378ab2ab0f..c5623062af4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -167,7 +167,8 @@ impl StaticIndex<'_> { keywords: true, format: crate::HoverDocFormat::Markdown, max_trait_assoc_items_count: None, - max_adt_fields_or_variants_count: Some(5), + max_struct_or_union_fields_count: Some(5), + max_enum_variants_count: Some(5), }; let tokens = tokens.filter(|token| { matches!( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 10bc19b9887..910ee70ca8c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -312,8 +312,10 @@ config_data! { /// How to render the size information in a memory layout hover. hover_memoryLayout_size: Option = Some(MemoryLayoutHoverRenderKindDef::Both), - /// How many fields or variants of an ADT (struct, enum or union) to display when hovering on. Show none if empty. - hover_show_adtFieldsOrVariants: Option = Some(5), + /// How many variants of an enum to display when hovering on. Show none if empty. + hover_show_enumVariants: Option = Some(5), + /// How many fields of a struct or union to display when hovering on. Show none if empty. + hover_show_structOrUnionFields: Option = Some(5), /// How many associated items of a trait to display when hovering a trait. hover_show_traitAssocItems: Option = None, @@ -1112,7 +1114,8 @@ impl Config { }, keywords: self.hover_documentation_keywords_enable().to_owned(), max_trait_assoc_items_count: self.hover_show_traitAssocItems().to_owned(), - max_adt_fields_or_variants_count: self.hover_show_adtFieldsOrVariants().to_owned(), + max_struct_or_union_fields_count: self.hover_show_structOrUnionFields().to_owned(), + max_enum_variants_count: self.hover_show_enumVariants().to_owned(), } } diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc index d275b51abc3..acc10cdb8fb 100644 --- a/src/tools/rust-analyzer/docs/user/generated_config.adoc +++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc @@ -533,10 +533,15 @@ How to render the offset information in a memory layout hover. -- How to render the size information in a memory layout hover. -- -[[rust-analyzer.hover.show.adtFieldsOrVariants]]rust-analyzer.hover.show.adtFieldsOrVariants (default: `5`):: +[[rust-analyzer.hover.show.enumVariants]]rust-analyzer.hover.show.enumVariants (default: `5`):: + -- -How many fields or variants of an ADT (struct, enum or union) to display when hovering on. Show none if empty. +How many variants of an enum to display when hovering on. Show none if empty. +-- +[[rust-analyzer.hover.show.structOrUnionFields]]rust-analyzer.hover.show.structOrUnionFields (default: `5`):: ++ +-- +How many fields of a struct or union to display when hovering on. Show none if empty. -- [[rust-analyzer.hover.show.traitAssocItems]]rust-analyzer.hover.show.traitAssocItems (default: `null`):: + diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 88a382f1fb8..ffbceb8ad4f 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -1152,8 +1152,17 @@ } ] }, - "rust-analyzer.hover.show.adtFieldsOrVariants": { - "markdownDescription": "How many fields or variants of an ADT (struct, enum or union) to display when hovering on. Show none if empty.", + "rust-analyzer.hover.show.enumVariants": { + "markdownDescription": "How many variants of an enum to display when hovering on. Show none if empty.", + "default": 5, + "type": [ + "null", + "integer" + ], + "minimum": 0 + }, + "rust-analyzer.hover.show.structOrUnionFields": { + "markdownDescription": "How many fields of a struct or union to display when hovering on. Show none if empty.", "default": 5, "type": [ "null",