2012-07-04 16:53:12 -05:00
|
|
|
/*!
|
|
|
|
* 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-03-06 15:56:33 -06:00
|
|
|
|
2012-07-11 17:00:40 -05:00
|
|
|
import doc::{item_utils, page_utils};
|
2012-05-13 19:12:56 -05:00
|
|
|
import syntax::ast;
|
|
|
|
|
2012-03-06 15:56:33 -06:00
|
|
|
export mk_pass;
|
|
|
|
|
|
|
|
fn mk_pass(output_style: config::output_style) -> pass {
|
|
|
|
{
|
2012-07-14 00:57:48 -05:00
|
|
|
name: ~"page",
|
2012-03-06 15:56:33 -06:00
|
|
|
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 {
|
2012-08-01 19:30:05 -05:00
|
|
|
return doc;
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
2012-08-08 15:38:26 -05:00
|
|
|
let (result_port, page_chan) = do task::spawn_conversation
|
|
|
|
|page_port, result_chan| {
|
2012-03-06 15:56:33 -06:00
|
|
|
comm::send(result_chan, make_doc_from_pages(page_port));
|
|
|
|
};
|
|
|
|
|
|
|
|
find_pages(doc, page_chan);
|
|
|
|
comm::recv(result_port)
|
|
|
|
}
|
|
|
|
|
2012-08-20 14:23:37 -05:00
|
|
|
type page_port = comm::Port<Option<doc::page>>;
|
|
|
|
type page_chan = comm::Chan<Option<doc::page>>;
|
2012-03-06 15:56:33 -06:00
|
|
|
|
|
|
|
fn make_doc_from_pages(page_port: page_port) -> doc::doc {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut pages = ~[];
|
2012-03-09 18:11:56 -06:00
|
|
|
loop {
|
2012-03-06 15:56:33 -06:00
|
|
|
let val = comm::recv(page_port);
|
|
|
|
if option::is_some(val) {
|
2012-06-29 18:26:56 -05:00
|
|
|
pages += ~[option::unwrap(val)];
|
2012-03-06 15:56:33 -06:00
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-07-11 17:00:40 -05:00
|
|
|
doc::doc_({
|
2012-03-06 15:56:33 -06:00
|
|
|
pages: pages
|
2012-07-11 17:00:40 -05:00
|
|
|
})
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn find_pages(doc: doc::doc, page_chan: page_chan) {
|
|
|
|
let fold = fold::fold({
|
|
|
|
fold_crate: fold_crate,
|
2012-03-10 18:44:48 -06:00
|
|
|
fold_mod: fold_mod,
|
|
|
|
fold_nmod: fold_nmod
|
2012-03-06 15:56:33 -06:00
|
|
|
with *fold::default_any_fold(page_chan)
|
|
|
|
});
|
|
|
|
fold.fold_doc(fold, doc);
|
|
|
|
|
2012-08-20 14:23:37 -05:00
|
|
|
comm::send(page_chan, None);
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
});
|
|
|
|
|
2012-08-20 14:23:37 -05:00
|
|
|
comm::send(fold.ctxt, Some(page));
|
2012-03-06 15:56:33 -06:00
|
|
|
|
|
|
|
doc
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fold_mod(
|
|
|
|
fold: fold::fold<page_chan>,
|
|
|
|
doc: doc::moddoc
|
|
|
|
) -> doc::moddoc {
|
|
|
|
|
|
|
|
let doc = fold::default_any_fold_mod(fold, doc);
|
|
|
|
|
2012-05-13 19:12:56 -05:00
|
|
|
if doc.id() != ast::crate_node_id {
|
2012-03-06 15:56:33 -06:00
|
|
|
|
|
|
|
let doc = strip_mod(doc);
|
|
|
|
let page = doc::itempage(doc::modtag(doc));
|
2012-08-20 14:23:37 -05:00
|
|
|
comm::send(fold.ctxt, Some(page));
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
doc
|
|
|
|
}
|
|
|
|
|
|
|
|
fn strip_mod(doc: doc::moddoc) -> doc::moddoc {
|
2012-07-11 17:00:40 -05:00
|
|
|
doc::moddoc_({
|
2012-06-30 18:19:07 -05:00
|
|
|
items: do vec::filter(doc.items) |item| {
|
2012-08-06 14:34:08 -05:00
|
|
|
match item {
|
2012-08-03 21:59:04 -05:00
|
|
|
doc::modtag(_) => false,
|
|
|
|
doc::nmodtag(_) => false,
|
|
|
|
_ => true
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
}
|
2012-07-11 17:00:40 -05:00
|
|
|
with *doc
|
|
|
|
})
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
2012-03-10 18:44:48 -06:00
|
|
|
fn fold_nmod(
|
|
|
|
fold: fold::fold<page_chan>,
|
|
|
|
doc: doc::nmoddoc
|
|
|
|
) -> doc::nmoddoc {
|
|
|
|
let doc = fold::default_seq_fold_nmod(fold, doc);
|
|
|
|
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;
|
2012-03-10 18:44:48 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 15:56:33 -06:00
|
|
|
#[test]
|
|
|
|
fn should_not_split_the_doc_into_pages_for_doc_per_crate() {
|
|
|
|
let doc = test::mk_doc_(
|
|
|
|
config::doc_per_crate,
|
2012-07-14 00:57:48 -05:00
|
|
|
~"mod a { } mod b { mod c { } }"
|
2012-03-06 15:56:33 -06:00
|
|
|
);
|
|
|
|
assert doc.pages.len() == 1u;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_make_a_page_for_every_mod() {
|
2012-07-14 00:57:48 -05:00
|
|
|
let doc = test::mk_doc(~"mod a { }");
|
|
|
|
assert doc.pages.mods()[0].name() == ~"a";
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_remove_mods_from_containing_mods() {
|
2012-07-14 00:57:48 -05:00
|
|
|
let doc = test::mk_doc(~"mod a { }");
|
2012-03-06 15:56:33 -06:00
|
|
|
assert vec::is_empty(doc.cratemod().mods());
|
|
|
|
}
|
|
|
|
|
2012-03-10 18:44:48 -06:00
|
|
|
#[test]
|
2012-06-26 18:18:37 -05:00
|
|
|
fn should_make_a_page_for_every_foreign_mod() {
|
2012-07-14 00:57:48 -05:00
|
|
|
let doc = test::mk_doc(~"extern mod a { }");
|
|
|
|
assert doc.pages.nmods()[0].name() == ~"a";
|
2012-03-10 18:44:48 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-06-26 18:18:37 -05:00
|
|
|
fn should_remove_foreign_mods_from_containing_mods() {
|
2012-07-14 00:57:48 -05:00
|
|
|
let doc = test::mk_doc(~"extern mod a { }");
|
2012-03-10 18:44:48 -06:00
|
|
|
assert vec::is_empty(doc.cratemod().nmods());
|
|
|
|
}
|
|
|
|
|
2012-03-06 15:56:33 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
fn mk_doc_(
|
|
|
|
output_style: config::output_style,
|
2012-07-14 00:57:48 -05:00
|
|
|
source: ~str
|
2012-03-06 15:56:33 -06:00
|
|
|
) -> doc::doc {
|
2012-06-30 18:19:07 -05:00
|
|
|
do astsrv::from_str(source) |srv| {
|
2012-07-14 00:57:48 -05:00
|
|
|
let doc = extract::from_srv(srv, ~"");
|
2012-03-06 15:56:33 -06:00
|
|
|
run(srv, doc, output_style)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn mk_doc(source: ~str) -> doc::doc {
|
2012-03-06 15:56:33 -06:00
|
|
|
mk_doc_(config::doc_per_mod, source)
|
|
|
|
}
|
2012-06-25 22:00:46 -05:00
|
|
|
}
|