rust/src/librustdoc/page_pass.rs

178 lines
3.8 KiB
Rust
Raw Normal View History

/*!
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.
*/
2012-09-18 18:48:40 -05:00
use doc::{ItemUtils, PageUtils};
2012-09-05 12:41:47 -05:00
use syntax::ast;
export mk_pass;
2012-09-18 18:48:40 -05:00
fn mk_pass(output_style: config::OutputStyle) -> Pass {
{
name: ~"page",
2012-09-18 18:48:40 -05:00
f: fn~(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
run(srv, doc, output_style)
}
}
}
fn run(
2012-09-18 18:48:40 -05:00
_srv: astsrv::Srv,
doc: doc::Doc,
output_style: config::OutputStyle
) -> doc::Doc {
2012-09-18 18:48:40 -05:00
if output_style == config::DocPerCrate {
2012-08-01 19:30:05 -05:00
return doc;
}
2012-08-08 15:38:26 -05:00
let (result_port, page_chan) = do task::spawn_conversation
|page_port, result_chan| {
comm::send(result_chan, make_doc_from_pages(page_port));
};
find_pages(doc, page_chan);
comm::recv(result_port)
}
2012-09-18 18:48:40 -05:00
type PagePort = comm::Port<Option<doc::Page>>;
type PageChan = comm::Chan<Option<doc::Page>>;
2012-09-18 18:48:40 -05:00
fn make_doc_from_pages(page_port: PagePort) -> doc::Doc {
let mut pages = ~[];
loop {
let val = comm::recv(page_port);
2012-09-21 21:37:57 -05:00
if val.is_some() {
2012-09-19 00:43:54 -05:00
pages += ~[option::unwrap(move val)];
} else {
break;
}
}
2012-09-18 18:48:40 -05:00
doc::Doc_({
pages: pages
})
}
2012-09-18 18:48:40 -05:00
fn find_pages(doc: doc::Doc, page_chan: PageChan) {
let fold = fold::Fold({
fold_crate: fold_crate,
fold_mod: fold_mod,
2012-09-04 15:29:32 -05:00
fold_nmod: fold_nmod,
.. *fold::default_any_fold(page_chan)
});
fold.fold_doc(fold, doc);
2012-08-20 14:23:37 -05:00
comm::send(page_chan, None);
}
fn fold_crate(
2012-09-18 18:48:40 -05:00
fold: fold::Fold<PageChan>,
doc: doc::CrateDoc
) -> doc::CrateDoc {
let doc = fold::default_seq_fold_crate(fold, doc);
2012-09-18 18:48:40 -05:00
let page = doc::CratePage({
2012-09-04 15:29:32 -05:00
topmod: strip_mod(doc.topmod),
.. doc
});
2012-08-20 14:23:37 -05:00
comm::send(fold.ctxt, Some(page));
doc
}
fn fold_mod(
2012-09-18 18:48:40 -05:00
fold: fold::Fold<PageChan>,
doc: doc::ModDoc
) -> doc::ModDoc {
let doc = fold::default_any_fold_mod(fold, doc);
if doc.id() != ast::crate_node_id {
let doc = strip_mod(doc);
2012-09-18 18:48:40 -05:00
let page = doc::ItemPage(doc::ModTag(doc));
2012-08-20 14:23:37 -05:00
comm::send(fold.ctxt, Some(page));
}
doc
}
2012-09-18 18:48:40 -05:00
fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc {
doc::ModDoc_({
2012-06-30 18:19:07 -05:00
items: do vec::filter(doc.items) |item| {
2012-09-28 00:20:47 -05:00
match *item {
2012-09-18 18:48:40 -05:00
doc::ModTag(_) => false,
doc::NmodTag(_) => false,
2012-08-03 21:59:04 -05:00
_ => true
}
2012-09-04 15:29:32 -05:00
},
.. *doc
})
}
fn fold_nmod(
2012-09-18 18:48:40 -05:00
fold: fold::Fold<PageChan>,
doc: doc::NmodDoc
) -> doc::NmodDoc {
let doc = fold::default_seq_fold_nmod(fold, doc);
2012-09-18 18:48:40 -05:00
let page = doc::ItemPage(doc::NmodTag(doc));
2012-08-20 14:23:37 -05:00
comm::send(fold.ctxt, Some(page));
2012-08-01 19:30:05 -05:00
return doc;
}
#[test]
fn should_not_split_the_doc_into_pages_for_doc_per_crate() {
let doc = test::mk_doc_(
2012-09-18 18:48:40 -05:00
config::DocPerCrate,
~"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());
}
#[test]
fn should_make_a_page_for_every_foreign_mod() {
let doc = test::mk_doc(~"extern mod a { }");
assert doc.pages.nmods()[0].name() == ~"a";
}
#[test]
fn should_remove_foreign_mods_from_containing_mods() {
let doc = test::mk_doc(~"extern mod a { }");
assert vec::is_empty(doc.cratemod().nmods());
}
#[cfg(test)]
mod test {
#[legacy_exports];
fn mk_doc_(
2012-09-18 18:48:40 -05:00
output_style: config::OutputStyle,
source: ~str
2012-09-18 18:48:40 -05:00
) -> doc::Doc {
2012-06-30 18:19:07 -05:00
do astsrv::from_str(source) |srv| {
let doc = extract::from_srv(srv, ~"");
run(srv, doc, output_style)
}
}
2012-09-18 18:48:40 -05:00
fn mk_doc(source: ~str) -> doc::Doc {
mk_doc_(config::DocPerMod, source)
}
}