From 43576989a1a577e3680bf1c3327810ce1b5a5b8b Mon Sep 17 00:00:00 2001 From: roife Date: Sat, 20 Apr 2024 01:06:04 +0800 Subject: [PATCH] Add hovering limitations support for variants --- crates/hir/src/display.rs | 37 ++++----- crates/ide/src/hover.rs | 2 +- crates/ide/src/hover/render.rs | 9 ++- crates/ide/src/hover/tests.rs | 122 +++++++++++++++++++++++++---- crates/ide/src/static_index.rs | 2 +- crates/rust-analyzer/src/config.rs | 6 +- docs/user/generated_config.adoc | 4 +- editors/code/package.json | 4 +- 8 files changed, 138 insertions(+), 48 deletions(-) diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 42fafd4ee806..1c3eac1590d5 100644 --- a/crates/hir/src/display.rs +++ b/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(&self.fields(f.db), has_where_clause, limit, f)?; + display_fields(&self.fields(f.db), has_where_clause, limit, false, f)?; } } StructKind::Unit => _ = write_where_clause(def_id, f)?, @@ -225,7 +225,7 @@ impl HirDisplay for Union { let has_where_clause = write_where_clause(def_id, f)?; if let Some(limit) = f.entity_limit { - display_fields(&self.fields(f.db), has_where_clause, limit, f)?; + display_fields(&self.fields(f.db), has_where_clause, limit, false, f)?; } Ok(()) } @@ -235,10 +235,12 @@ fn display_fields( fields: &[Field], has_where_clause: bool, limit: usize, + in_line: bool, f: &mut HirFormatter<'_>, ) -> Result<(), HirDisplayError> { let count = fields.len().min(limit); - f.write_char(if !has_where_clause { ' ' } else { '\n' })?; + let (indent, separator) = if in_line { ("", ' ') } else { (" ", '\n') }; + f.write_char(if !has_where_clause { ' ' } else { separator })?; if count == 0 { if fields.is_empty() { f.write_str("{}")?; @@ -246,15 +248,19 @@ fn display_fields( f.write_str("{ /* … */ }")?; } } else { - f.write_str("{\n")?; + f.write_char('{')?; + f.write_char(separator)?; for field in &fields[..count] { - f.write_str(" ")?; + f.write_str(indent)?; field.hir_fmt(f)?; - f.write_str(",\n")?; + f.write_char(',')?; + f.write_char(separator)?; } if fields.len() > count { - f.write_str(" /* … */\n")?; + f.write_str(indent)?; + f.write_str("/* … */")?; + f.write_char(separator)?; } f.write_str("}")?; } @@ -345,21 +351,10 @@ impl HirDisplay for Variant { } f.write_char(')')?; } - VariantData::Record(fields) => { - f.write_str(" {")?; - let mut first = true; - for (_, field) in fields.iter() { - if first { - first = false; - f.write_char(' ')?; - } else { - f.write_str(", ")?; - } - // Enum variant fields must be pub. - write!(f, "{}: ", field.name.display(f.db.upcast()))?; - field.type_ref.hir_fmt(f)?; + VariantData::Record(_) => { + if let Some(limit) = f.entity_limit { + display_fields(&self.fields(f.db), false, limit, true, f)?; } - f.write_str(" }")?; } } Ok(()) diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 6958ae16230a..cd76ee4d7bdd 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -33,7 +33,7 @@ pub struct HoverConfig { pub keywords: bool, pub format: HoverDocFormat, pub max_trait_assoc_items_count: Option, - pub max_struct_or_union_fields_count: Option, + pub max_fields_count: Option, pub max_enum_variants_count: Option, } diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index 1044a3f4c11b..0809ea81d757 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -411,7 +411,10 @@ pub(super) fn definition( trait_.display_limited(db, config.max_trait_assoc_items_count).to_string() } Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => { - adt.display_limited(db, config.max_struct_or_union_fields_count).to_string() + adt.display_limited(db, config.max_fields_count).to_string() + } + Definition::Variant(variant) => { + variant.display_limited(db, config.max_fields_count).to_string() } Definition::Adt(adt @ Adt::Enum(_)) => { adt.display_limited(db, config.max_enum_variants_count).to_string() @@ -419,9 +422,7 @@ pub(super) fn definition( 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_struct_or_union_fields_count).to_string() - } + Some(adt) => adt.display_limited(db, config.max_fields_count).to_string(), None => self_ty.display(db).to_string(), } } diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index f17a0fa2cd92..ff3258b4dbbc 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -18,7 +18,7 @@ const HOVER_BASE_CONFIG: HoverConfig = HoverConfig { format: HoverDocFormat::Markdown, keywords: true, max_trait_assoc_items_count: None, - max_struct_or_union_fields_count: Some(5), + max_fields_count: Some(5), max_enum_variants_count: Some(5), }; @@ -52,7 +52,7 @@ fn check(ra_fixture: &str, expect: Expect) { } #[track_caller] -fn check_hover_struct_or_union_fields_limit( +fn check_hover_fields_limit( fields_count: impl Into>, ra_fixture: &str, expect: Expect, @@ -62,7 +62,7 @@ fn check_hover_struct_or_union_fields_limit( .hover( &HoverConfig { links_in_hover: true, - max_struct_or_union_fields_count: fields_count.into(), + max_fields_count: fields_count.into(), ..HOVER_BASE_CONFIG }, FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) }, @@ -939,7 +939,7 @@ struct Foo$0 where u32: Copy { field: u32 } #[test] fn hover_record_struct_limit() { - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( 3, r#" struct Foo$0 { a: u32, b: i32, c: i32 } @@ -961,7 +961,7 @@ fn hover_record_struct_limit() { ``` "#]], ); - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( 3, r#" struct Foo$0 { a: u32 } @@ -981,7 +981,7 @@ fn hover_record_struct_limit() { ``` "#]], ); - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( 3, r#" struct Foo$0 { a: u32, b: i32, c: i32, d: u32 } @@ -1004,7 +1004,7 @@ fn hover_record_struct_limit() { ``` "#]], ); - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( None, r#" struct Foo$0 { a: u32, b: i32, c: i32 } @@ -1022,7 +1022,7 @@ fn hover_record_struct_limit() { ``` "#]], ); - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( 0, r#" struct Foo$0 { a: u32, b: i32, c: i32 } @@ -1042,6 +1042,100 @@ fn hover_record_struct_limit() { ) } +#[test] +fn hover_record_variant_limit() { + check_hover_fields_limit( + 3, + r#" + enum Foo { A$0 { a: u32, b: i32, c: i32 } } + "#, + expect![[r#" + *A* + + ```rust + test::Foo + ``` + + ```rust + // size = 12 (0xC), align = 4 + A { a: u32, b: i32, c: i32, } + ``` + "#]], + ); + check_hover_fields_limit( + 3, + r#" + enum Foo { A$0 { a: u32 } } + "#, + expect![[r#" + *A* + + ```rust + test::Foo + ``` + + ```rust + // size = 4, align = 4 + A { a: u32, } + ``` + "#]], + ); + check_hover_fields_limit( + 3, + r#" + enum Foo { A$0 { a: u32, b: i32, c: i32, d: u32 } } + "#, + expect![[r#" + *A* + + ```rust + test::Foo + ``` + + ```rust + // size = 16 (0x10), align = 4 + A { a: u32, b: i32, c: i32, /* … */ } + ``` + "#]], + ); + check_hover_fields_limit( + None, + r#" + enum Foo { A$0 { a: u32, b: i32, c: i32 } } + "#, + expect![[r#" + *A* + + ```rust + test::Foo + ``` + + ```rust + // size = 12 (0xC), align = 4 + A + ``` + "#]], + ); + check_hover_fields_limit( + 0, + r#" + enum Foo { A$0 { a: u32, b: i32, c: i32 } } + "#, + expect![[r#" + *A* + + ```rust + test::Foo + ``` + + ```rust + // size = 12 (0xC), align = 4 + A { /* … */ } + ``` + "#]], + ); +} + #[test] fn hover_enum_limit() { check_hover_enum_variants_limit( @@ -1152,7 +1246,7 @@ fn hover_enum_limit() { #[test] fn hover_union_limit() { - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( 5, r#"union Foo$0 { a: u32, b: i32 }"#, expect![[r#" @@ -1171,7 +1265,7 @@ fn hover_union_limit() { ``` "#]], ); - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( 1, r#"union Foo$0 { a: u32, b: i32 }"#, expect![[r#" @@ -1190,7 +1284,7 @@ fn hover_union_limit() { ``` "#]], ); - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( 0, r#"union Foo$0 { a: u32, b: i32 }"#, expect![[r#" @@ -1206,7 +1300,7 @@ fn hover_union_limit() { ``` "#]], ); - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( None, r#"union Foo$0 { a: u32, b: i32 }"#, expect![[r#" @@ -1691,7 +1785,7 @@ impl Thing { ``` "#]], ); - check_hover_struct_or_union_fields_limit( + check_hover_fields_limit( None, r#" struct Thing { x: u32 } @@ -6832,7 +6926,7 @@ enum Enum { ```rust // size = 4, align = 4 - RecordV { field: u32 } + RecordV { field: u32, } ``` "#]], ); diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs index c5623062af4c..df625f740480 100644 --- a/crates/ide/src/static_index.rs +++ b/crates/ide/src/static_index.rs @@ -167,7 +167,7 @@ impl StaticIndex<'_> { keywords: true, format: crate::HoverDocFormat::Markdown, max_trait_assoc_items_count: None, - max_struct_or_union_fields_count: Some(5), + max_fields_count: Some(5), max_enum_variants_count: Some(5), }; let tokens = tokens.filter(|token| { diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 910ee70ca8c9..52c09fb3945b 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -314,8 +314,8 @@ config_data! { /// 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 fields of a struct, variant or union to display when hovering on. Show none if empty. + hover_show_fields: Option = Some(5), /// How many associated items of a trait to display when hovering a trait. hover_show_traitAssocItems: Option = None, @@ -1114,7 +1114,7 @@ impl Config { }, keywords: self.hover_documentation_keywords_enable().to_owned(), max_trait_assoc_items_count: self.hover_show_traitAssocItems().to_owned(), - max_struct_or_union_fields_count: self.hover_show_structOrUnionFields().to_owned(), + max_fields_count: self.hover_show_fields().to_owned(), max_enum_variants_count: self.hover_show_enumVariants().to_owned(), } } diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc index acc10cdb8fb8..ebacc5b7016e 100644 --- a/docs/user/generated_config.adoc +++ b/docs/user/generated_config.adoc @@ -538,10 +538,10 @@ How to render the size information in a memory layout hover. -- 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`):: +[[rust-analyzer.hover.show.fields]]rust-analyzer.hover.show.fields (default: `5`):: + -- -How many fields of a struct or union to display when hovering on. Show none if empty. +How many fields of a struct, variant 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/editors/code/package.json b/editors/code/package.json index ffbceb8ad4fa..aed0d9f898f9 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -1161,8 +1161,8 @@ ], "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.", + "rust-analyzer.hover.show.fields": { + "markdownDescription": "How many fields of a struct, variant or union to display when hovering on. Show none if empty.", "default": 5, "type": [ "null",