Prevent impl blocks containing only private items to be documented by default
This commit is contained in:
parent
5af97e8b0b
commit
dd816a9c2e
3 changed files with 54 additions and 17 deletions
|
@ -17,6 +17,7 @@ pub(crate) const STRIP_HIDDEN: Pass = Pass {
|
||||||
/// Strip items marked `#[doc(hidden)]`
|
/// Strip items marked `#[doc(hidden)]`
|
||||||
pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
|
pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
|
||||||
let mut retained = ItemIdSet::default();
|
let mut retained = ItemIdSet::default();
|
||||||
|
let is_json_output = cx.output_format.is_json() && !cx.show_coverage;
|
||||||
|
|
||||||
// strip all #[doc(hidden)] items
|
// strip all #[doc(hidden)] items
|
||||||
let krate = {
|
let krate = {
|
||||||
|
@ -25,7 +26,12 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
|
||||||
};
|
};
|
||||||
|
|
||||||
// strip all impls referencing stripped items
|
// strip all impls referencing stripped items
|
||||||
let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache };
|
let mut stripper = ImplStripper {
|
||||||
|
retained: &retained,
|
||||||
|
cache: &cx.cache,
|
||||||
|
is_json_output,
|
||||||
|
document_private: cx.render_options.document_private,
|
||||||
|
};
|
||||||
stripper.fold_crate(krate)
|
stripper.fold_crate(krate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub(crate) const STRIP_PRIVATE: Pass = Pass {
|
||||||
pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
|
pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
|
||||||
// This stripper collects all *retained* nodes.
|
// This stripper collects all *retained* nodes.
|
||||||
let mut retained = ItemIdSet::default();
|
let mut retained = ItemIdSet::default();
|
||||||
|
let is_json_output = cx.output_format.is_json() && !cx.show_coverage;
|
||||||
|
|
||||||
// strip all private items
|
// strip all private items
|
||||||
{
|
{
|
||||||
|
@ -24,12 +25,17 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
|
||||||
retained: &mut retained,
|
retained: &mut retained,
|
||||||
access_levels: &cx.cache.access_levels,
|
access_levels: &cx.cache.access_levels,
|
||||||
update_retained: true,
|
update_retained: true,
|
||||||
is_json_output: cx.output_format.is_json() && !cx.show_coverage,
|
is_json_output,
|
||||||
};
|
};
|
||||||
krate = ImportStripper.fold_crate(stripper.fold_crate(krate));
|
krate = ImportStripper.fold_crate(stripper.fold_crate(krate));
|
||||||
}
|
}
|
||||||
|
|
||||||
// strip all impls referencing private items
|
// strip all impls referencing private items
|
||||||
let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache };
|
let mut stripper = ImplStripper {
|
||||||
|
retained: &retained,
|
||||||
|
cache: &cx.cache,
|
||||||
|
is_json_output,
|
||||||
|
document_private: cx.render_options.document_private,
|
||||||
|
};
|
||||||
stripper.fold_crate(krate)
|
stripper.fold_crate(krate)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,17 +14,19 @@ pub(crate) struct Stripper<'a> {
|
||||||
pub(crate) is_json_output: bool,
|
pub(crate) is_json_output: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Stripper<'a> {
|
// We need to handle this differently for the JSON output because some non exported items could
|
||||||
// We need to handle this differently for the JSON output because some non exported items could
|
// be used in public API. And so, we need these items as well. `is_exported` only checks if they
|
||||||
// be used in public API. And so, we need these items as well. `is_exported` only checks if they
|
// are in the public API, which is not enough.
|
||||||
// are in the public API, which is not enough.
|
#[inline]
|
||||||
#[inline]
|
fn is_item_reachable(
|
||||||
fn is_item_reachable(&self, item_id: ItemId) -> bool {
|
is_json_output: bool,
|
||||||
if self.is_json_output {
|
access_levels: &AccessLevels<DefId>,
|
||||||
self.access_levels.is_reachable(item_id.expect_def_id())
|
item_id: ItemId,
|
||||||
} else {
|
) -> bool {
|
||||||
self.access_levels.is_exported(item_id.expect_def_id())
|
if is_json_output {
|
||||||
}
|
access_levels.is_reachable(item_id.expect_def_id())
|
||||||
|
} else {
|
||||||
|
access_levels.is_exported(item_id.expect_def_id())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +63,9 @@ impl<'a> DocFolder for Stripper<'a> {
|
||||||
| clean::MacroItem(..)
|
| clean::MacroItem(..)
|
||||||
| clean::ForeignTypeItem => {
|
| clean::ForeignTypeItem => {
|
||||||
let item_id = i.item_id;
|
let item_id = i.item_id;
|
||||||
if item_id.is_local() && !self.is_item_reachable(item_id) {
|
if item_id.is_local()
|
||||||
|
&& !is_item_reachable(self.is_json_output, self.access_levels, item_id)
|
||||||
|
{
|
||||||
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
|
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -133,6 +137,8 @@ impl<'a> DocFolder for Stripper<'a> {
|
||||||
pub(crate) struct ImplStripper<'a> {
|
pub(crate) struct ImplStripper<'a> {
|
||||||
pub(crate) retained: &'a ItemIdSet,
|
pub(crate) retained: &'a ItemIdSet,
|
||||||
pub(crate) cache: &'a Cache,
|
pub(crate) cache: &'a Cache,
|
||||||
|
pub(crate) is_json_output: bool,
|
||||||
|
pub(crate) document_private: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DocFolder for ImplStripper<'a> {
|
impl<'a> DocFolder for ImplStripper<'a> {
|
||||||
|
@ -140,8 +146,27 @@ impl<'a> DocFolder for ImplStripper<'a> {
|
||||||
if let clean::ImplItem(ref imp) = *i.kind {
|
if let clean::ImplItem(ref imp) = *i.kind {
|
||||||
// Impl blocks can be skipped if they are: empty; not a trait impl; and have no
|
// Impl blocks can be skipped if they are: empty; not a trait impl; and have no
|
||||||
// documentation.
|
// documentation.
|
||||||
if imp.trait_.is_none() && imp.items.is_empty() && i.doc_value().is_none() {
|
//
|
||||||
return None;
|
// There is one special case: if the impl block contains only private items.
|
||||||
|
if imp.trait_.is_none() {
|
||||||
|
// If the only items present are private ones and we're not rendering private items,
|
||||||
|
// we don't document it.
|
||||||
|
if !imp.items.is_empty()
|
||||||
|
&& !self.document_private
|
||||||
|
&& imp.items.iter().all(|i| {
|
||||||
|
let item_id = i.item_id;
|
||||||
|
item_id.is_local()
|
||||||
|
&& !is_item_reachable(
|
||||||
|
self.is_json_output,
|
||||||
|
&self.cache.access_levels,
|
||||||
|
item_id,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
} else if imp.items.is_empty() && i.doc_value().is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some(did) = imp.for_.def_id(self.cache) {
|
if let Some(did) = imp.for_.def_id(self.cache) {
|
||||||
if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
|
if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue