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:
parent
ee97698f85
commit
356423d8f1
1 changed files with 179 additions and 166 deletions
|
@ -229,6 +229,8 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
|
||||||
};
|
};
|
||||||
try!(mkdir(&cx.dst));
|
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(&[])) {
|
match krate.module.as_ref().map(|m| m.doc_list().unwrap_or(&[])) {
|
||||||
Some(attrs) => {
|
Some(attrs) => {
|
||||||
for attr in attrs.iter() {
|
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());
|
cache.stack.push(krate.name.clone());
|
||||||
krate = cache.fold_crate(krate);
|
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 nodeid_to_pathid = HashMap::new();
|
||||||
let mut pathid_to_nodeid = Vec::new();
|
let mut pathid_to_nodeid = Vec::new();
|
||||||
{
|
{
|
||||||
let Cache { search_index: ref mut index,
|
let Cache { ref mut search_index,
|
||||||
orphan_methods: ref meths, paths: ref mut paths, ..} = cache;
|
ref orphan_methods,
|
||||||
|
ref mut paths, .. } = *cache;
|
||||||
|
|
||||||
// Attach all orphan methods to the type's definition if the type
|
// Attach all orphan methods to the type's definition if the type
|
||||||
// has since been learned.
|
// 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);
|
let did = ast_util::local_def(pid);
|
||||||
match paths.find(&did) {
|
match paths.find(&did) {
|
||||||
Some(&(ref fqp, _)) => {
|
Some(&(ref fqp, _)) => {
|
||||||
index.push(IndexItem {
|
search_index.push(IndexItem {
|
||||||
ty: shortty(item),
|
ty: shortty(item),
|
||||||
name: item.name.clone().unwrap(),
|
name: item.name.clone().unwrap(),
|
||||||
path: fqp.slice_to(fqp.len() - 1).connect("::")
|
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,
|
// Reduce `NodeId` in paths into smaller sequential numbers,
|
||||||
// and prune the paths that do not appear in the index.
|
// 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 {
|
match item.parent {
|
||||||
Some(nodeid) => {
|
Some(nodeid) => {
|
||||||
if !nodeid_to_pathid.contains_key(&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());
|
assert_eq!(nodeid_to_pathid.len(), pathid_to_nodeid.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish the search index
|
// Collect the index into a string
|
||||||
let index = {
|
|
||||||
let mut w = MemWriter::new();
|
let mut w = MemWriter::new();
|
||||||
try!(write!(&mut w, r#"searchIndex['{}'] = \{"items":["#, krate.name));
|
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"]\};"));
|
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
|
// 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
|
// docs placed in the output directory, so this needs to be a synchronized
|
||||||
// operation with respect to all other rustdocs running around.
|
// operation with respect to all other rustdocs running around.
|
||||||
{
|
|
||||||
try!(mkdir(&cx.dst));
|
try!(mkdir(&cx.dst));
|
||||||
let _lock = ::flock::Lock::new(&cx.dst.join(".lock"));
|
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"));
|
"searchIndex"));
|
||||||
let mut w = try!(File::create(&dst));
|
let mut w = try!(File::create(&dst));
|
||||||
try!(writeln!(&mut w, r"var searchIndex = \{\};"));
|
try!(writeln!(&mut w, r"var searchIndex = \{\};"));
|
||||||
try!(writeln!(&mut w, "{}", index));
|
try!(writeln!(&mut w, "{}", search_index));
|
||||||
for index in all_indexes.iter() {
|
for index in all_indexes.iter() {
|
||||||
try!(writeln!(&mut w, "{}", *index));
|
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"\})()"));
|
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");
|
info!("emitting source files");
|
||||||
let dst = cx.dst.join("src");
|
let dst = cx.dst.join("src");
|
||||||
try!(mkdir(&dst));
|
try!(mkdir(&dst));
|
||||||
|
@ -507,21 +530,11 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
|
||||||
let mut folder = SourceCollector {
|
let mut folder = SourceCollector {
|
||||||
dst: dst,
|
dst: dst,
|
||||||
seen: HashSet::new(),
|
seen: HashSet::new(),
|
||||||
cx: &mut cx,
|
cx: cx,
|
||||||
};
|
};
|
||||||
// skip all invalid spans
|
// skip all invalid spans
|
||||||
folder.seen.insert("".to_string());
|
folder.seen.insert("".to_string());
|
||||||
krate = folder.fold_crate(krate);
|
Ok(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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the entire contents of a string to a destination, not attempting to
|
/// Writes the entire contents of a string to a destination, not attempting to
|
||||||
|
|
Loading…
Reference in a new issue