"Fossies" - the Fresh Open Source Software Archive

Member "rustc-1.61.0-src/src/librustdoc/visit_lib.rs" (18 May 2022, 2912 Bytes) of package /linux/misc/rustc-1.61.0-src.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Rust source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "visit_lib.rs": 1.59.0_vs_1.60.0.

    1 use rustc_data_structures::fx::FxHashSet;
    2 use rustc_hir::def::{DefKind, Res};
    3 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
    4 use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
    5 use rustc_middle::ty::TyCtxt;
    6 
    7 // FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
    8 
    9 /// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
   10 /// specific rustdoc annotations into account (i.e., `doc(hidden)`)
   11 crate struct LibEmbargoVisitor<'a, 'tcx> {
   12     tcx: TyCtxt<'tcx>,
   13     // Accessibility levels for reachable nodes
   14     access_levels: &'a mut AccessLevels<DefId>,
   15     // Previous accessibility level, None means unreachable
   16     prev_level: Option<AccessLevel>,
   17     // Keeps track of already visited modules, in case a module re-exports its parent
   18     visited_mods: FxHashSet<DefId>,
   19 }
   20 
   21 impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
   22     crate fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
   23         LibEmbargoVisitor {
   24             tcx: cx.tcx,
   25             access_levels: &mut cx.cache.access_levels,
   26             prev_level: Some(AccessLevel::Public),
   27             visited_mods: FxHashSet::default(),
   28         }
   29     }
   30 
   31     crate fn visit_lib(&mut self, cnum: CrateNum) {
   32         let did = DefId { krate: cnum, index: CRATE_DEF_INDEX };
   33         self.update(did, Some(AccessLevel::Public));
   34         self.visit_mod(did);
   35     }
   36 
   37     // Updates node level and returns the updated level
   38     fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
   39         let is_hidden = self.tcx.is_doc_hidden(did);
   40 
   41         let old_level = self.access_levels.map.get(&did).cloned();
   42         // Accessibility levels can only grow
   43         if level > old_level && !is_hidden {
   44             self.access_levels.map.insert(did, level.unwrap());
   45             level
   46         } else {
   47             old_level
   48         }
   49     }
   50 
   51     crate fn visit_mod(&mut self, def_id: DefId) {
   52         if !self.visited_mods.insert(def_id) {
   53             return;
   54         }
   55 
   56         for item in self.tcx.module_children(def_id).iter() {
   57             if let Some(def_id) = item.res.opt_def_id() {
   58                 if self.tcx.def_key(def_id).parent.map_or(false, |d| d == def_id.index)
   59                     || item.vis.is_public()
   60                 {
   61                     self.visit_item(item.res);
   62                 }
   63             }
   64         }
   65     }
   66 
   67     fn visit_item(&mut self, res: Res<!>) {
   68         let def_id = res.def_id();
   69         let vis = self.tcx.visibility(def_id);
   70         let inherited_item_level = if vis.is_public() { self.prev_level } else { None };
   71 
   72         let item_level = self.update(def_id, inherited_item_level);
   73 
   74         if let Res::Def(DefKind::Mod, _) = res {
   75             let orig_level = self.prev_level;
   76 
   77             self.prev_level = item_level;
   78             self.visit_mod(def_id);
   79             self.prev_level = orig_level;
   80         }
   81     }
   82 }