From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/librustdoc/passes/strip_hidden.rs | 68 +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/librustdoc/passes/strip_hidden.rs (limited to 'src/librustdoc/passes/strip_hidden.rs') diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs new file mode 100644 index 000000000..533e2ce46 --- /dev/null +++ b/src/librustdoc/passes/strip_hidden.rs @@ -0,0 +1,68 @@ +//! Strip all doc(hidden) items from the output. +use rustc_span::symbol::sym; +use std::mem; + +use crate::clean; +use crate::clean::{Item, ItemIdSet, NestedAttributesExt}; +use crate::core::DocContext; +use crate::fold::{strip_item, DocFolder}; +use crate::passes::{ImplStripper, Pass}; + +pub(crate) const STRIP_HIDDEN: Pass = Pass { + name: "strip-hidden", + run: strip_hidden, + description: "strips all `#[doc(hidden)]` items from the output", +}; + +/// Strip items marked `#[doc(hidden)]` +pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { + let mut retained = ItemIdSet::default(); + + // strip all #[doc(hidden)] items + let krate = { + let mut stripper = Stripper { retained: &mut retained, update_retained: true }; + stripper.fold_crate(krate) + }; + + // strip all impls referencing stripped items + let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache }; + stripper.fold_crate(krate) +} + +struct Stripper<'a> { + retained: &'a mut ItemIdSet, + update_retained: bool, +} + +impl<'a> DocFolder for Stripper<'a> { + fn fold_item(&mut self, i: Item) -> Option { + if i.attrs.lists(sym::doc).has_word(sym::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 + // can show a placeholder "// some variants omitted". We need to keep + // private modules, because they can contain impl blocks, and impl + // block privacy is inherited from the type and trait, not from the + // 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 { + 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)); + self.update_retained = old; + return Some(ret); + } + _ => return None, + } + } else { + if self.update_retained { + self.retained.insert(i.item_id); + } + } + Some(self.fold_item_recur(i)) + } +} -- cgit v1.2.3