Skip to content

Commit

Permalink
Auto merge of #17021 - roife:add-hover-limits-for-adts, r=Veykril
Browse files Browse the repository at this point in the history
Support hovering limits for adts

Fix #17009

1. Currently, r-a supports limiting the number of struct fields displayed when hovering. This PR extends it to support enum variants and union fields. Since the display of these three (ADTs) is similar, this PR extends 'hover_show_structFields' to 'hover_show_adtFieldsOrVariants'.
2. This PR also resolved the problem that the layout of ADT was not restricted by display limitations when hovering on the Self type.
3. Additionally, this PR changes the default value of display limitations to `10` (instead of the original `null`), which helps users discover this feature.
  • Loading branch information
bors committed Apr 25, 2024
2 parents c88d5dc + aa1f134 commit 65eda41
Show file tree
Hide file tree
Showing 8 changed files with 563 additions and 97 deletions.
150 changes: 95 additions & 55 deletions crates/hir/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,28 +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 {
let fields = self.fields(f.db);
let count = fields.len().min(limit);
f.write_char(if !has_where_clause { ' ' } else { '\n' })?;
if count == 0 {
if fields.is_empty() {
f.write_str("{}")?;
} else {
f.write_str("{ /* … */ }")?;
}
} else {
f.write_str(" {\n")?;
for field in &fields[..count] {
f.write_str(" ")?;
field.hir_fmt(f)?;
f.write_str(",\n")?;
}

if fields.len() > count {
f.write_str(" /* … */\n")?;
}
f.write_str("}")?;
}
display_fields(&self.fields(f.db), has_where_clause, limit, false, f)?;
}
}
StructKind::Unit => _ = write_where_clause(def_id, f)?,
Expand All @@ -226,18 +205,10 @@ impl HirDisplay for Enum {
write!(f, "{}", self.name(f.db).display(f.db.upcast()))?;
let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id));
write_generic_params(def_id, f)?;
let has_where_clause = write_where_clause(def_id, f)?;

let variants = self.variants(f.db);
if !variants.is_empty() {
f.write_char(if !has_where_clause { ' ' } else { '\n' })?;
f.write_str("{\n")?;
for variant in variants {
f.write_str(" ")?;
variant.hir_fmt(f)?;
f.write_str(",\n")?;
}
f.write_str("}")?;
let has_where_clause = write_where_clause(def_id, f)?;
if let Some(limit) = f.entity_limit {
display_variants(&self.variants(f.db), has_where_clause, limit, f)?;
}

Ok(())
Expand All @@ -251,22 +222,102 @@ impl HirDisplay for Union {
write!(f, "{}", self.name(f.db).display(f.db.upcast()))?;
let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id));
write_generic_params(def_id, f)?;

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, false, f)?;
}
Ok(())
}
}

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);
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("{}")?;
} else {
f.write_str("{ /* … */ }")?;
}
} else {
f.write_char('{')?;

let fields = self.fields(f.db);
if !fields.is_empty() {
f.write_char(if !has_where_clause { ' ' } else { '\n' })?;
f.write_str("{\n")?;
for field in self.fields(f.db) {
f.write_str(" ")?;
f.write_char(separator)?;
for field in &fields[..count] {
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(indent)?;
f.write_str("/* … */")?;
f.write_char(separator)?;
}
f.write_str("}")?;
}

Ok(())
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("}")?;
}

Ok(())
}

impl HirDisplay for Field {
Expand Down Expand Up @@ -304,21 +355,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(())
Expand Down
3 changes: 2 additions & 1 deletion crates/ide/src/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ pub struct HoverConfig {
pub keywords: bool,
pub format: HoverDocFormat,
pub max_trait_assoc_items_count: Option<usize>,
pub max_struct_field_count: Option<usize>,
pub max_fields_count: Option<usize>,
pub max_enum_variants_count: Option<usize>,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
Expand Down
17 changes: 15 additions & 2 deletions crates/ide/src/hover/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,21 @@ pub(super) fn definition(
Definition::Trait(trait_) => {
trait_.display_limited(db, config.max_trait_assoc_items_count).to_string()
}
Definition::Adt(Adt::Struct(struct_)) => {
struct_.display_limited(db, config.max_struct_field_count).to_string()
Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => {
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()
}
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_fields_count).to_string(),
None => self_ty.display(db).to_string(),
}
}
Definition::Macro(it) => {
let mut label = it.display(db).to_string();
Expand Down
Loading

0 comments on commit 65eda41

Please sign in to comment.