From 26107f6181a5301d3af9c9614fee4c69d76c7213 Mon Sep 17 00:00:00 2001 From: Alexander Light Date: Sun, 9 Nov 2014 19:09:17 -0500 Subject: [PATCH] rustdoc: Allow private modules be included in docs Made it so that what passes are used is passed onto the renderer so it can intelligently deal with private modules. --- src/librustdoc/html/render.rs | 86 +++++++++++++++++++---------------- src/librustdoc/lib.rs | 23 ++++++---- 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5e4ac259e7180..97a18e9708fe2 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -101,6 +101,8 @@ pub struct Context { /// real location of an item. This is used to allow external links to /// publicly reused items to redirect to the right location. pub render_redirect_pages: bool, + /// All the passes that were run on this crate. + pub passes: HashSet, } /// Indicates where an external crate can be found. @@ -190,6 +192,7 @@ pub struct Cache { parent_stack: Vec, search_index: Vec, privmod: bool, + remove_priv: bool, public_items: NodeSet, // In rare case where a structure is defined in one module but implemented @@ -236,9 +239,13 @@ local_data_key!(pub cache_key: Arc) local_data_key!(pub current_location_key: Vec ) /// Generates the documentation for `crate` into the directory `dst` -pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) -> io::IoResult<()> { +pub fn run(mut krate: clean::Crate, + external_html: &ExternalHtml, + dst: Path, + passes: HashSet) -> io::IoResult<()> { let mut cx = Context { dst: dst, + passes: passes, current: Vec::new(), root_path: String::new(), sidebar: HashMap::new(), @@ -320,6 +327,7 @@ pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) -> search_index: Vec::new(), extern_locations: HashMap::new(), primitive_locations: HashMap::new(), + remove_priv: cx.passes.contains("strip-private"), privmod: false, public_items: public_items, orphan_methods: Vec::new(), @@ -767,7 +775,7 @@ impl DocFolder for Cache { let orig_privmod = match item.inner { clean::ModuleItem(..) => { let prev = self.privmod; - self.privmod = prev || item.visibility != Some(ast::Public); + self.privmod = prev || (self.remove_priv && item.visibility != Some(ast::Public)); prev } _ => self.privmod, @@ -1192,7 +1200,7 @@ impl Context { // these modules are recursed into, but not rendered normally (a // flag on the context). if !self.render_redirect_pages { - self.render_redirect_pages = ignore_private_item(&item); + self.render_redirect_pages = self.ignore_private_item(&item); } match item.inner { @@ -1211,7 +1219,7 @@ impl Context { clean::ModuleItem(m) => m, _ => unreachable!() }; - this.sidebar = build_sidebar(&m); + this.sidebar = this.build_sidebar(&m); for item in m.items.into_iter() { f(this,item); } @@ -1230,6 +1238,40 @@ impl Context { _ => Ok(()) } } + + fn build_sidebar(&self, m: &clean::Module) -> HashMap> { + let mut map = HashMap::new(); + for item in m.items.iter() { + if self.ignore_private_item(item) { continue } + + let short = shortty(item).to_static_str(); + let myname = match item.name { + None => continue, + Some(ref s) => s.to_string(), + }; + let v = match map.entry(short.to_string()) { + Vacant(entry) => entry.set(Vec::with_capacity(1)), + Occupied(entry) => entry.into_mut(), + }; + v.push(myname); + } + + for (_, items) in map.iter_mut() { + items.as_mut_slice().sort(); + } + return map; + } + + fn ignore_private_item(&self, it: &clean::Item) -> bool { + match it.inner { + clean::ModuleItem(ref m) => { + (m.items.len() == 0 && it.doc_value().is_none()) || + (self.passes.contains("strip-private") && it.visibility != Some(ast::Public)) + } + clean::PrimitiveItem(..) => it.visibility != Some(ast::Public), + _ => false, + } + } } impl<'a> Item<'a> { @@ -1443,7 +1485,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, try!(document(w, item)); let mut indices = range(0, items.len()).filter(|i| { - !ignore_private_item(&items[*i]) + !cx.ignore_private_item(&items[*i]) }).collect::>(); fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { @@ -2157,29 +2199,6 @@ impl<'a> fmt::Show for Sidebar<'a> { } } -fn build_sidebar(m: &clean::Module) -> HashMap> { - let mut map = HashMap::new(); - for item in m.items.iter() { - if ignore_private_item(item) { continue } - - let short = shortty(item).to_static_str(); - let myname = match item.name { - None => continue, - Some(ref s) => s.to_string(), - }; - let v = match map.entry(short.to_string()) { - Vacant(entry) => entry.set(Vec::with_capacity(1)), - Occupied(entry) => entry.into_mut(), - }; - v.push(myname); - } - - for (_, items) in map.iter_mut() { - items.as_mut_slice().sort(); - } - return map; -} - impl<'a> fmt::Show for Source<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let Source(s) = *self; @@ -2214,17 +2233,6 @@ fn item_primitive(w: &mut fmt::Formatter, render_methods(w, it) } -fn ignore_private_item(it: &clean::Item) -> bool { - match it.inner { - clean::ModuleItem(ref m) => { - (m.items.len() == 0 && it.doc_value().is_none()) || - it.visibility != Some(ast::Public) - } - clean::PrimitiveItem(..) => it.visibility != Some(ast::Public), - _ => false, - } -} - fn get_basic_keywords() -> &'static str { "rust, rustlang, rust-lang" } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 4a512ca33fc45..54e9196d8a9f6 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -86,7 +86,11 @@ static DEFAULT_PASSES: &'static [&'static str] = &[ local_data_key!(pub analysiskey: core::CrateAnalysis) -type Output = (clean::Crate, Vec ); +struct Output { + krate: clean::Crate, + json_plugins: Vec, + passes: Vec, +} pub fn main() { std::os::set_exit_status(main_args(std::os::args().as_slice())); @@ -229,24 +233,26 @@ pub fn main_args(args: &[String]) -> int { (false, false) => {} } - let (krate, res) = match acquire_input(input, externs, &matches) { - Ok(pair) => pair, + let out = match acquire_input(input, externs, &matches) { + Ok(out) => out, Err(s) => { println!("input error: {}", s); return 1; } }; - + let Output { krate, json_plugins, passes, } = out; info!("going to format"); match matches.opt_str("w").as_ref().map(|s| s.as_slice()) { Some("html") | None => { - match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc"))) { + match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc")), + passes.into_iter().collect()) { Ok(()) => {} Err(e) => panic!("failed to generate documentation: {}", e), } } Some("json") => { - match json_output(krate, res, output.unwrap_or(Path::new("doc.json"))) { + match json_output(krate, json_plugins, + output.unwrap_or(Path::new("doc.json"))) { Ok(()) => {} Err(e) => panic!("failed to write json: {}", e), } @@ -397,7 +403,8 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche // Run everything! info!("Executing passes/plugins"); - return pm.run_plugins(krate); + let (krate, json) = pm.run_plugins(krate); + return Output { krate: krate, json_plugins: json, passes: passes, }; } /// This input format purely deserializes the json output file. No passes are @@ -435,7 +442,7 @@ fn json_input(input: &str) -> Result { // FIXME: this should read from the "plugins" field, but currently // Json doesn't implement decodable... let plugin_output = Vec::new(); - Ok((krate, plugin_output)) + Ok(Output { krate: krate, json_plugins: plugin_output, passes: Vec::new(), }) } Ok(..) => { Err("malformed json input: expected an object at the \