Fix handling of items inside a doc(hidden)
block
This commit is contained in:
parent
34685485c7
commit
5b654a7e5e
@ -2225,21 +2225,17 @@ fn clean_maybe_renamed_item<'tcx>(
|
||||
get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs);
|
||||
}
|
||||
|
||||
if !extra_attrs.is_empty() {
|
||||
let mut item = if !extra_attrs.is_empty() {
|
||||
extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
|
||||
let attrs = Attributes::from_ast(&extra_attrs);
|
||||
let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
|
||||
|
||||
vec![Item::from_def_id_and_attrs_and_parts(
|
||||
def_id,
|
||||
Some(name),
|
||||
kind,
|
||||
Box::new(attrs),
|
||||
cfg,
|
||||
)]
|
||||
Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg)
|
||||
} else {
|
||||
vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)]
|
||||
}
|
||||
Item::from_def_id_and_parts(def_id, Some(name), kind, cx)
|
||||
};
|
||||
item.inline_stmt_id = import_id.map(|def_id| def_id.to_def_id());
|
||||
vec![item]
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
//! Strip all doc(hidden) items from the output.
|
||||
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::symbol::sym;
|
||||
use std::mem;
|
||||
|
||||
@ -7,6 +9,7 @@ use crate::clean::{Item, ItemIdSet, NestedAttributesExt};
|
||||
use crate::core::DocContext;
|
||||
use crate::fold::{strip_item, DocFolder};
|
||||
use crate::passes::{ImplStripper, Pass};
|
||||
use crate::visit_ast::inherits_doc_hidden;
|
||||
|
||||
pub(crate) const STRIP_HIDDEN: Pass = Pass {
|
||||
name: "strip-hidden",
|
||||
@ -21,7 +24,12 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
|
||||
|
||||
// strip all #[doc(hidden)] items
|
||||
let krate = {
|
||||
let mut stripper = Stripper { retained: &mut retained, update_retained: true };
|
||||
let mut stripper = Stripper {
|
||||
retained: &mut retained,
|
||||
update_retained: true,
|
||||
tcx: cx.tcx,
|
||||
is_in_hidden_item: false,
|
||||
};
|
||||
stripper.fold_crate(krate)
|
||||
};
|
||||
|
||||
@ -36,14 +44,38 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
|
||||
stripper.fold_crate(krate)
|
||||
}
|
||||
|
||||
struct Stripper<'a> {
|
||||
struct Stripper<'a, 'tcx> {
|
||||
retained: &'a mut ItemIdSet,
|
||||
update_retained: bool,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
is_in_hidden_item: bool,
|
||||
}
|
||||
|
||||
impl<'a> DocFolder for Stripper<'a> {
|
||||
impl<'a, 'tcx> Stripper<'a, 'tcx> {
|
||||
fn set_is_in_hidden_item_and_fold(&mut self, is_in_hidden_item: bool, i: Item) -> Item {
|
||||
let prev = self.is_in_hidden_item;
|
||||
self.is_in_hidden_item |= is_in_hidden_item;
|
||||
let ret = self.fold_item_recur(i);
|
||||
self.is_in_hidden_item = prev;
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
|
||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
if i.attrs.lists(sym::doc).has_word(sym::hidden) {
|
||||
let has_doc_hidden = i.attrs.lists(sym::doc).has_word(sym::hidden);
|
||||
let mut is_hidden = self.is_in_hidden_item || has_doc_hidden;
|
||||
if !is_hidden && i.inline_stmt_id.is_none() {
|
||||
// We don't need to check if it's coming from a reexport since the reexport itself was
|
||||
// already checked.
|
||||
is_hidden = i
|
||||
.item_id
|
||||
.as_def_id()
|
||||
.and_then(|def_id| def_id.as_local())
|
||||
.map(|def_id| inherits_doc_hidden(self.tcx, def_id))
|
||||
.unwrap_or(false);
|
||||
}
|
||||
if is_hidden {
|
||||
debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name);
|
||||
// Use a dedicated hidden item for fields, variants, and modules.
|
||||
// We need to keep private fields and variants, so that the docs
|
||||
@ -53,23 +85,31 @@ impl<'a> DocFolder for Stripper<'a> {
|
||||
// module it's defined in. Both of these are marked "stripped," and
|
||||
// not included in the final docs, but since they still have an effect
|
||||
// on the final doc, cannot be completely removed from the Clean IR.
|
||||
match *i.kind {
|
||||
return match *i.kind {
|
||||
clean::StructFieldItem(..) | clean::ModuleItem(..) | clean::VariantItem(..) => {
|
||||
// We need to recurse into stripped modules to
|
||||
// strip things like impl methods but when doing so
|
||||
// we must not add any items to the `retained` set.
|
||||
let old = mem::replace(&mut self.update_retained, false);
|
||||
let ret = strip_item(self.fold_item_recur(i));
|
||||
let ret = strip_item(self.set_is_in_hidden_item_and_fold(true, i));
|
||||
self.update_retained = old;
|
||||
return Some(ret);
|
||||
Some(ret)
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
} else {
|
||||
if self.update_retained {
|
||||
self.retained.insert(i.item_id);
|
||||
}
|
||||
_ => {
|
||||
let ret = self.set_is_in_hidden_item_and_fold(true, i);
|
||||
if has_doc_hidden {
|
||||
// If the item itself has `#[doc(hidden)]`, then we simply remove it.
|
||||
None
|
||||
} else {
|
||||
// However if it's a "descendant" of a `#[doc(hidden)]` item, then we strip it.
|
||||
Some(strip_item(ret))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Some(self.fold_item_recur(i))
|
||||
if self.update_retained {
|
||||
self.retained.insert(i.item_id);
|
||||
}
|
||||
Some(self.set_is_in_hidden_item_and_fold(is_hidden, i))
|
||||
}
|
||||
}
|
||||
|
@ -187,6 +187,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
self.inside_public_path = orig_inside_public_path;
|
||||
debug!("Leaving module {:?}", m);
|
||||
}
|
||||
|
||||
/// Tries to resolve the target of a `pub use` statement and inlines the
|
||||
@ -290,7 +291,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
&mut self,
|
||||
item: &'tcx hir::Item<'_>,
|
||||
renamed: Option<Symbol>,
|
||||
parent_id: Option<LocalDefId>,
|
||||
import_id: Option<LocalDefId>,
|
||||
) -> bool {
|
||||
debug!("visiting item {:?}", item);
|
||||
let name = renamed.unwrap_or(item.ident.name);
|
||||
@ -347,7 +348,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
self.add_to_current_mod(item, renamed, parent_id);
|
||||
self.add_to_current_mod(item, renamed, import_id);
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Macro(ref macro_def, _) => {
|
||||
@ -383,13 +384,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
| hir::ItemKind::Static(..)
|
||||
| hir::ItemKind::Trait(..)
|
||||
| hir::ItemKind::TraitAlias(..) => {
|
||||
self.add_to_current_mod(item, renamed, parent_id);
|
||||
self.add_to_current_mod(item, renamed, import_id);
|
||||
}
|
||||
hir::ItemKind::Const(..) => {
|
||||
// Underscore constants do not correspond to a nameable item and
|
||||
// so are never useful in documentation.
|
||||
if name != kw::Underscore {
|
||||
self.add_to_current_mod(item, renamed, parent_id);
|
||||
self.add_to_current_mod(item, renamed, import_id);
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Impl(impl_) => {
|
||||
@ -437,12 +438,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
|
||||
let parent_id = if self.modules.len() > 1 {
|
||||
Some(self.modules[self.modules.len() - 2].def_id)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if self.visit_item_inner(i, None, parent_id) {
|
||||
if self.visit_item_inner(i, None, None) {
|
||||
walk_item(self, i);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user