Skip to content

Commit

Permalink
auto merge of #18822 : scialex/rust/better-rustdoc, r=alexcrichton
Browse files Browse the repository at this point in the history
Changed `rustdoc` so that if we do not have the `strip-private` pass
enabled private modules will be included in the generated documentation

I added this because it is useful to be able to read the documentation in the very nice `rustdoc` web interface when doing internal work on a project. In this case we want the `rustdoc` to include modules that are hidden from consumers. Since this is not currently possible I added it here.
  • Loading branch information
bors committed Nov 21, 2014
2 parents 97c043b + 26107f6 commit cd75847
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 47 deletions.
86 changes: 47 additions & 39 deletions src/librustdoc/html/render.rs
Expand Up @@ -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<String>,
}

/// Indicates where an external crate can be found.
Expand Down Expand Up @@ -190,6 +192,7 @@ pub struct Cache {
parent_stack: Vec<ast::DefId>,
search_index: Vec<IndexItem>,
privmod: bool,
remove_priv: bool,
public_items: NodeSet,

// In rare case where a structure is defined in one module but implemented
Expand Down Expand Up @@ -236,9 +239,13 @@ local_data_key!(pub cache_key: Arc<Cache>)
local_data_key!(pub current_location_key: Vec<String> )

/// 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<String>) -> io::IoResult<()> {
let mut cx = Context {
dst: dst,
passes: passes,
current: Vec::new(),
root_path: String::new(),
sidebar: HashMap::new(),
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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);
}
Expand All @@ -1230,6 +1238,40 @@ impl Context {
_ => Ok(())
}
}

fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<String>> {
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> {
Expand Down Expand Up @@ -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::<Vec<uint>>();

fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering {
Expand Down Expand Up @@ -2157,29 +2199,6 @@ impl<'a> fmt::Show for Sidebar<'a> {
}
}

fn build_sidebar(m: &clean::Module) -> HashMap<String, Vec<String>> {
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;
Expand Down Expand Up @@ -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"
}
Expand Down
23 changes: 15 additions & 8 deletions src/librustdoc/lib.rs
Expand Up @@ -86,7 +86,11 @@ static DEFAULT_PASSES: &'static [&'static str] = &[

local_data_key!(pub analysiskey: core::CrateAnalysis)

type Output = (clean::Crate, Vec<plugins::PluginJson> );
struct Output {
krate: clean::Crate,
json_plugins: Vec<plugins::PluginJson>,
passes: Vec<String>,
}

pub fn main() {
std::os::set_exit_status(main_args(std::os::args().as_slice()));
Expand Down Expand Up @@ -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),
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -435,7 +442,7 @@ fn json_input(input: &str) -> Result<Output, String> {
// 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 \
Expand Down

0 comments on commit cd75847

Please sign in to comment.