Skip to content

Commit

Permalink
rustdoc: Don't generate empty files for stripped items
Browse files Browse the repository at this point in the history
We need to traverse stripped modules to generate redirect pages, but we shouldn't generate
anything else for them.

This now renders the file contents to a Vec before writing it to a file in one go. I think
that's probably a better strategy anyway.
  • Loading branch information
ollie27 committed Jun 2, 2016
1 parent 433d70c commit cfb4ad2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
41 changes: 24 additions & 17 deletions src/librustdoc/html/render.rs
Expand Up @@ -1255,7 +1255,6 @@ impl Context {

info!("Recursing into {}", self.dst.display());

mkdir(&self.dst).unwrap();
let ret = f(self);

info!("Recursed; leaving {}", self.dst.display());
Expand Down Expand Up @@ -1299,7 +1298,7 @@ impl Context {
fn item<F>(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where
F: FnMut(&mut Context, clean::Item),
{
fn render(w: File, cx: &Context, it: &clean::Item,
fn render(writer: &mut io::Write, cx: &Context, it: &clean::Item,
pushname: bool) -> io::Result<()> {
// A little unfortunate that this is done like this, but it sure
// does make formatting *a lot* nicer.
Expand Down Expand Up @@ -1334,12 +1333,8 @@ impl Context {

reset_ids(true);

// We have a huge number of calls to write, so try to alleviate some
// of the pain by using a buffered writer instead of invoking the
// write syscall all the time.
let mut writer = BufWriter::new(w);
if !cx.render_redirect_pages {
layout::render(&mut writer, &cx.shared.layout, &page,
layout::render(writer, &cx.shared.layout, &page,
&Sidebar{ cx: cx, item: it },
&Item{ cx: cx, item: it },
cx.shared.css_file_extension.is_some())?;
Expand All @@ -1352,10 +1347,10 @@ impl Context {
url.push_str("/");
}
url.push_str(&item_path(it));
layout::redirect(&mut writer, &url)?;
layout::redirect(writer, &url)?;
}
}
writer.flush()
Ok(())
}

// Stripped modules survive the rustdoc passes (i.e. `strip-private`)
Expand All @@ -1376,9 +1371,16 @@ impl Context {
let mut item = Some(item);
self.recurse(name, |this| {
let item = item.take().unwrap();
let joint_dst = this.dst.join("index.html");
let dst = try_err!(File::create(&joint_dst), &joint_dst);
try_err!(render(dst, this, &item, false), &joint_dst);

let mut buf = Vec::new();
render(&mut buf, this, &item, false).unwrap();
// buf will be empty if the module is stripped and there is no redirect for it
if !buf.is_empty() {
let joint_dst = this.dst.join("index.html");
try_err!(fs::create_dir_all(&this.dst), &this.dst);
let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
try_err!(dst.write_all(&buf), &joint_dst);
}

let m = match item.inner {
clean::StrippedItem(box clean::ModuleItem(m)) |
Expand All @@ -1387,7 +1389,7 @@ impl Context {
};

// render sidebar-items.js used throughout this module
{
if !this.render_redirect_pages {
let items = this.build_sidebar_items(&m);
let js_dst = this.dst.join("sidebar-items.js");
let mut js_out = BufWriter::new(try_err!(File::create(&js_dst), &js_dst));
Expand All @@ -1401,10 +1403,15 @@ impl Context {
Ok(())
})
} else if item.name.is_some() {
let joint_dst = self.dst.join(&item_path(&item));

let dst = try_err!(File::create(&joint_dst), &joint_dst);
try_err!(render(dst, self, &item, true), &joint_dst);
let mut buf = Vec::new();
render(&mut buf, self, &item, true).unwrap();
// buf will be empty if the item is stripped and there is no redirect for it
if !buf.is_empty() {
let joint_dst = self.dst.join(&item_path(&item));
try_err!(fs::create_dir_all(&self.dst), &self.dst);
let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
try_err!(dst.write_all(&buf), &joint_dst);
}
Ok(())
} else {
Ok(())
Expand Down
22 changes: 22 additions & 0 deletions src/test/rustdoc/issue-34025.rs
@@ -0,0 +1,22 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_name = "foo"]

// @!has 'foo/sys/index.html'
// @!has 'foo/sys/sidebar-items.js'
#[doc(hidden)]
pub mod sys {
extern "C" {
// @!has 'foo/sys/fn.foo.html'
#[doc(hidden)]
pub fn foo();
}
}

0 comments on commit cfb4ad2

Please sign in to comment.