Skip to content

Commit

Permalink
skip some redundant items
Browse files Browse the repository at this point in the history
  • Loading branch information
wfraser committed Nov 27, 2023
1 parent 7cd8336 commit 72b28d7
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
60 changes: 59 additions & 1 deletion src/browser_rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ impl RustdocBrowser {
Struct(_) => "struct",
StructField(f) => return format!("{}: {}", name, type_label(f)),
Enum(_) => "enum",
Variant(_) => "variant",
Variant(v) => {
if let Some(ty) = self.single_element_tuple_variant(v, id) {
// Include the name of the wrapped type in the label.
// list_items() will skip the redundant type later.
return format!("variant {name}({})", type_label(ty));
}
"variant"
}
Function(_) => "fn", // TODO: include signature?
Trait(_) => "trait",
TraitAlias(_) => "trait alias",
Expand Down Expand Up @@ -65,6 +72,25 @@ impl RustdocBrowser {
};
format!("{prefix} {name}")
}

fn single_element_tuple_variant<'a>(
&'a self,
v: &'a rustdoc_types::Variant,
id: ItemId<'a>,
) -> Option<&'a rustdoc_types::Type> {
if let rustdoc_types::VariantKind::Tuple(t) = &v.kind {
if let Some(Some(inner_id)) = t.first() {
if let Some((_id, Item::Item(item))) =
self.analysis.get_item(id.crate_sibling(inner_id))
{
if let rustdoc_types::ItemEnum::StructField(ty) = &item.inner {
return Some(ty);
}
}
}
}
None
}
}

impl<'a> Browser for &'a RustdocBrowser {
Expand All @@ -85,6 +111,29 @@ impl<'a> Browser for &'a RustdocBrowser {
}

fn list_items(&self, parent_id: &ItemId<'a>) -> Vec<(String, (ItemId<'a>, Item<'a>))> {
// If true, skip showing this element's children and show the children of the first child
// instead. Basically, skip one level of nesting. Use when the item is redundant.
let mut use_first_child = false;
if let Some((_, Item::Item(parent))) = self.analysis.get_item(parent_id.clone()) {
match &parent.inner {
rustdoc_types::ItemEnum::Variant(v)
if self
.single_element_tuple_variant(v, parent_id.clone())
.is_some() =>
{
// Single-element tuple variant. The only child is a StructField for field "0".
// This adds nothing because the type name is already in the Variant's label.
use_first_child = true;
}
rustdoc_types::ItemEnum::StructField(_) => {
// StructField's only child is the type, which adds nothing, as the type name is
// already in the StructField's label.
use_first_child = true;
}
_ => (),
}
}

let mut items = self
.analysis
.items(parent_id)
Expand All @@ -107,6 +156,15 @@ impl<'a> Browser for &'a RustdocBrowser {
.collect::<Vec<_>>();
sort_by_label(&mut items);

if use_first_child && !items.is_empty() {
assert_eq!(
items.len(),
1,
"use_first_child on non-singleton children list: {items:#?}"
);
return self.list_items(&items[0].1 .0);
}

items
}

Expand Down
7 changes: 4 additions & 3 deletions tests/browser_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn list_items() {
x_e_items.labels(),
&[
"variant StructVariant",
"variant TupleVariant",
"variant TupleVariant(S)",
"variant UnitVariant",
]
);
Expand Down Expand Up @@ -159,9 +159,10 @@ fn list_items() {
let x_e_unit_items = BROWSER.list_items(&x_e_unit.0);
assert_eq!(x_e_unit_items.labels(), &[] as &[&str]);

let x_e_tuple = x_e_items.by_label("variant TupleVariant");
let x_e_tuple = x_e_items.by_label("variant TupleVariant(S)");
let x_e_tuple_items = BROWSER.list_items(&x_e_tuple.0);
assert_eq!(x_e_tuple_items.labels(), &["0: S"] as &[&str]);
// Skip the struct field and the struct, go straight to its items:
assert_eq!(x_e_tuple_items.labels(), x_s_items.labels());

let x_e_struct = x_e_items.by_label("variant StructVariant");
let x_e_struct_items = BROWSER.list_items(&x_e_struct.0);
Expand Down

0 comments on commit 72b28d7

Please sign in to comment.