rustdoc: Refactor structure of html::run

Instead of one giant function, this breaks it up into several smaller functions
which have explicit dependencies among one another.

There are no code changes as a result of this commit.
This commit is contained in:
Alex Crichton 2014-05-27 17:12:48 -07:00
parent ee97698f85
commit 356423d8f1

View file

@ -229,6 +229,8 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
};
try!(mkdir(&cx.dst));
// Crawl the crate attributes looking for attributes which control how we're
// going to emit HTML
match krate.module.as_ref().map(|m| m.doc_list().unwrap_or(&[])) {
Some(attrs) => {
for attr in attrs.iter() {
@ -297,19 +299,37 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
cache.stack.push(krate.name.clone());
krate = cache.fold_crate(krate);
for &(n, ref e) in krate.externs.iter() {
cache.extern_locations.insert(n, extern_location(e, &cx.dst));
let did = ast::DefId { krate: n, node: ast::CRATE_NODE_ID };
cache.paths.insert(did, (vec![e.name.to_string()], item_type::Module));
}
let index = try!(build_index(&krate, &mut cache));
try!(write_shared(&cx, &krate, &cache, index));
let krate = try!(render_sources(&mut cx, krate));
// And finally render the whole crate's documentation
cx.krate(krate, cache)
}
fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult<String> {
// Build the search index from the collected metadata
let mut nodeid_to_pathid = HashMap::new();
let mut pathid_to_nodeid = Vec::new();
{
let Cache { search_index: ref mut index,
orphan_methods: ref meths, paths: ref mut paths, ..} = cache;
let Cache { ref mut search_index,
ref orphan_methods,
ref mut paths, .. } = *cache;
// Attach all orphan methods to the type's definition if the type
// has since been learned.
for &(pid, ref item) in meths.iter() {
for &(pid, ref item) in orphan_methods.iter() {
let did = ast_util::local_def(pid);
match paths.find(&did) {
Some(&(ref fqp, _)) => {
index.push(IndexItem {
search_index.push(IndexItem {
ty: shortty(item),
name: item.name.clone().unwrap(),
path: fqp.slice_to(fqp.len() - 1).connect("::")
@ -324,7 +344,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
// Reduce `NodeId` in paths into smaller sequential numbers,
// and prune the paths that do not appear in the index.
for item in index.iter() {
for item in search_index.iter() {
match item.parent {
Some(nodeid) => {
if !nodeid_to_pathid.contains_key(&nodeid) {
@ -339,8 +359,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
assert_eq!(nodeid_to_pathid.len(), pathid_to_nodeid.len());
}
// Publish the search index
let index = {
// Collect the index into a string
let mut w = MemWriter::new();
try!(write!(&mut w, r#"searchIndex['{}'] = \{"items":["#, krate.name));
@ -384,13 +403,16 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
try!(write!(&mut w, r"]\};"));
str::from_utf8(w.unwrap().as_slice()).unwrap().to_string()
};
Ok(str::from_utf8(w.unwrap().as_slice()).unwrap().to_string())
}
fn write_shared(cx: &Context,
krate: &clean::Crate,
cache: &Cache,
search_index: String) -> io::IoResult<()> {
// Write out the shared files. Note that these are shared among all rustdoc
// docs placed in the output directory, so this needs to be a synchronized
// operation with respect to all other rustdocs running around.
{
try!(mkdir(&cx.dst));
let _lock = ::flock::Lock::new(&cx.dst.join(".lock"));
@ -438,7 +460,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
"searchIndex"));
let mut w = try!(File::create(&dst));
try!(writeln!(&mut w, r"var searchIndex = \{\};"));
try!(writeln!(&mut w, "{}", index));
try!(writeln!(&mut w, "{}", search_index));
for index in all_indexes.iter() {
try!(writeln!(&mut w, "{}", *index));
}
@ -495,10 +517,11 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
"));
try!(writeln!(&mut f, r"\})()"));
}
}
Ok(())
}
// Render all source files (this may turn into a giant no-op)
{
fn render_sources(cx: &mut Context,
krate: clean::Crate) -> io::IoResult<clean::Crate> {
info!("emitting source files");
let dst = cx.dst.join("src");
try!(mkdir(&dst));
@ -507,21 +530,11 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
let mut folder = SourceCollector {
dst: dst,
seen: HashSet::new(),
cx: &mut cx,
cx: cx,
};
// skip all invalid spans
folder.seen.insert("".to_string());
krate = folder.fold_crate(krate);
}
for &(n, ref e) in krate.externs.iter() {
cache.extern_locations.insert(n, extern_location(e, &cx.dst));
let did = ast::DefId { krate: n, node: ast::CRATE_NODE_ID };
cache.paths.insert(did, (vec![e.name.to_string()], item_type::Module));
}
// And finally render the whole crate's documentation
cx.krate(krate, cache)
Ok(folder.fold_crate(krate))
}
/// Writes the entire contents of a string to a destination, not attempting to