diff options
Diffstat (limited to 'src/rustdoc')
| -rw-r--r-- | src/rustdoc/doc.rs | 84 | ||||
| -rw-r--r-- | src/rustdoc/page_pass.rs | 152 | ||||
| -rw-r--r-- | src/rustdoc/rustdoc.rc | 1 |
3 files changed, 237 insertions, 0 deletions
diff --git a/src/rustdoc/doc.rs b/src/rustdoc/doc.rs index b7a7fb4dd88..ccee1335835 100644 --- a/src/rustdoc/doc.rs +++ b/src/rustdoc/doc.rs @@ -240,6 +240,90 @@ impl util for moddoc { } } +impl util for [page] { + + fn mods() -> [moddoc] { + vec::filter_map(self) {|page| + alt page { + itempage(modtag(moddoc)) { some(moddoc) } + _ { none } + } + } + } + + fn nmods() -> [nmoddoc] { + vec::filter_map(self) {|page| + alt page { + itempage(nmodtag(nmoddoc)) { some(nmoddoc) } + _ { none } + } + } + } + + fn fns() -> [fndoc] { + vec::filter_map(self) {|page| + alt page { + itempage(fntag(fndoc)) { some(fndoc) } + _ { none } + } + } + } + + fn consts() -> [constdoc] { + vec::filter_map(self) {|page| + alt page { + itempage(consttag(constdoc)) { some(constdoc) } + _ { none } + } + } + } + + fn enums() -> [enumdoc] { + vec::filter_map(self) {|page| + alt page { + itempage(enumtag(enumdoc)) { some(enumdoc) } + _ { none } + } + } + } + + fn resources() -> [resdoc] { + vec::filter_map(self) {|page| + alt page { + itempage(restag(resdoc)) { some(resdoc) } + _ { none } + } + } + } + + fn ifaces() -> [ifacedoc] { + vec::filter_map(self) {|page| + alt page { + itempage(ifacetag(ifacedoc)) { some(ifacedoc) } + _ { none } + } + } + } + + fn impls() -> [impldoc] { + vec::filter_map(self) {|page| + alt page { + itempage(impltag(impldoc)) { some(impldoc) } + _ { none } + } + } + } + + fn types() -> [tydoc] { + vec::filter_map(self) {|page| + alt page { + itempage(tytag(tydoc)) { some(tydoc) } + _ { none } + } + } + } +} + iface item { fn item() -> itemdoc; } diff --git a/src/rustdoc/page_pass.rs b/src/rustdoc/page_pass.rs new file mode 100644 index 00000000000..e3f2c4235e7 --- /dev/null +++ b/src/rustdoc/page_pass.rs @@ -0,0 +1,152 @@ +#[doc = " + +Divides the document tree into pages. + +Each page corresponds is a logical section. There may be pages for individual +modules, pages for the crate, indexes, etc. + +"]; + +export mk_pass; + +fn mk_pass(output_style: config::output_style) -> pass { + { + name: "page", + f: fn~(srv: astsrv::srv, doc: doc::doc) -> doc::doc { + run(srv, doc, output_style) + } + } +} + +fn run( + _srv: astsrv::srv, + doc: doc::doc, + output_style: config::output_style +) -> doc::doc { + + if output_style == config::doc_per_crate { + ret doc; + } + + let result_port = comm::port(); + let result_chan = comm::chan(result_port); + let page_chan = task::spawn_listener {|page_port| + comm::send(result_chan, make_doc_from_pages(page_port)); + }; + + find_pages(doc, page_chan); + comm::recv(result_port) +} + +type page_port = comm::port<option<doc::page>>; +type page_chan = comm::chan<option<doc::page>>; + +fn make_doc_from_pages(page_port: page_port) -> doc::doc { + let mut pages = []; + while true { + let val = comm::recv(page_port); + if option::is_some(val) { + pages += [option::unwrap(val)]; + } else { + break; + } + } + { + pages: pages + } +} + +fn find_pages(doc: doc::doc, page_chan: page_chan) { + let fold = fold::fold({ + fold_crate: fold_crate, + fold_mod: fold_mod + with *fold::default_any_fold(page_chan) + }); + fold.fold_doc(fold, doc); + + comm::send(page_chan, none); +} + +fn fold_crate( + fold: fold::fold<page_chan>, + doc: doc::cratedoc +) -> doc::cratedoc { + + let doc = fold::default_seq_fold_crate(fold, doc); + + let page = doc::cratepage({ + topmod: strip_mod(doc.topmod) + with doc + }); + + comm::send(fold.ctxt, some(page)); + + doc +} + +fn fold_mod( + fold: fold::fold<page_chan>, + doc: doc::moddoc +) -> doc::moddoc { + + let doc = fold::default_any_fold_mod(fold, doc); + + if doc.id() != rustc::syntax::ast::crate_node_id { + + let doc = strip_mod(doc); + let page = doc::itempage(doc::modtag(doc)); + comm::send(fold.ctxt, some(page)); + } + + doc +} + +fn strip_mod(doc: doc::moddoc) -> doc::moddoc { + { + items: vec::filter(doc.items) {|item| + alt item { + doc::modtag(_) { false } + _ { true } + } + } + with doc + } +} + +#[test] +fn should_not_split_the_doc_into_pages_for_doc_per_crate() { + let doc = test::mk_doc_( + config::doc_per_crate, + "mod a { } mod b { mod c { } }" + ); + assert doc.pages.len() == 1u; +} + +#[test] +fn should_make_a_page_for_every_mod() { + let doc = test::mk_doc("mod a { }"); + assert doc.pages.mods()[0].name() == "a"; +} + +#[test] +fn should_remove_mods_from_containing_mods() { + let doc = test::mk_doc("mod a { }"); + assert vec::is_empty(doc.cratemod().mods()); +} + +#[cfg(test)] +mod test { + fn mk_doc_( + output_style: config::output_style, + source: str + ) -> doc::doc { + astsrv::from_str(source) {|srv| + let doc = extract::from_srv(srv, ""); + run(srv, doc, output_style) + } + } + + fn mk_doc(source: str) -> doc::doc { + mk_doc_(config::doc_per_mod, source) + } +} \ No newline at end of file diff --git a/src/rustdoc/rustdoc.rc b/src/rustdoc/rustdoc.rc index 69a95cfd24c..c53b11fa021 100644 --- a/src/rustdoc/rustdoc.rc +++ b/src/rustdoc/rustdoc.rc @@ -38,3 +38,4 @@ mod sort_item_name_pass; mod sort_item_type_pass; mod reexport_pass; mod par; +mod page_pass; |
