2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/*!
|
2012-09-20 18:09:46 -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
|
|
|
|
2013-05-17 17:28:44 -05:00
|
|
|
use core::prelude::*;
|
|
|
|
|
2012-12-23 16:41:37 -06:00
|
|
|
use astsrv;
|
|
|
|
use config;
|
2013-03-26 15:38:07 -05:00
|
|
|
use doc::ItemUtils;
|
2012-12-23 16:41:37 -06:00
|
|
|
use doc;
|
2012-12-05 17:06:54 -06:00
|
|
|
use fold::Fold;
|
2012-12-23 16:41:37 -06:00
|
|
|
use fold;
|
2013-01-08 21:37:25 -06:00
|
|
|
use pass::Pass;
|
2012-11-26 20:03:36 -06:00
|
|
|
use util::NominalOp;
|
2012-12-23 16:41:37 -06:00
|
|
|
|
2013-02-02 05:10:12 -06:00
|
|
|
use core::comm::*;
|
2013-05-24 21:35:29 -05:00
|
|
|
use core::task;
|
2012-12-23 16:41:37 -06:00
|
|
|
use syntax::ast;
|
2012-05-13 19:12:56 -05:00
|
|
|
|
2013-03-26 15:38:07 -05:00
|
|
|
#[cfg(test)] use doc::PageUtils;
|
|
|
|
|
2012-11-19 20:00:12 -06:00
|
|
|
pub fn mk_pass(output_style: config::OutputStyle) -> Pass {
|
2013-01-08 16:00:45 -06:00
|
|
|
Pass {
|
2012-07-14 00:57:48 -05:00
|
|
|
name: ~"page",
|
2013-01-31 19:12:29 -06:00
|
|
|
f: |srv, doc| run(srv, doc, output_style)
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-08 21:37:25 -06:00
|
|
|
pub fn run(
|
2012-09-18 18:48:40 -05:00
|
|
|
_srv: astsrv::Srv,
|
2013-01-30 21:32:36 -06:00
|
|
|
doc: doc::Doc,
|
2012-09-18 18:48:40 -05:00
|
|
|
output_style: config::OutputStyle
|
|
|
|
) -> doc::Doc {
|
2012-03-06 15:56:33 -06:00
|
|
|
|
2012-09-18 18:48:40 -05:00
|
|
|
if output_style == config::DocPerCrate {
|
2012-08-01 19:30:05 -05:00
|
|
|
return doc;
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
2013-02-01 02:16:14 -06:00
|
|
|
let (result_port, result_chan) = stream();
|
|
|
|
let (page_port, page_chan) = stream();
|
2013-04-17 01:45:29 -05:00
|
|
|
let page_chan = SharedChan::new(page_chan);
|
2013-02-01 02:16:14 -06:00
|
|
|
do task::spawn {
|
|
|
|
result_chan.send(make_doc_from_pages(&page_port));
|
2012-03-06 15:56:33 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
find_pages(doc, page_chan);
|
2013-02-01 02:16:14 -06:00
|
|
|
result_port.recv()
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
2013-02-01 02:16:14 -06:00
|
|
|
type PagePort = Port<Option<doc::Page>>;
|
|
|
|
type PageChan = SharedChan<Option<doc::Page>>;
|
2012-03-06 15:56:33 -06:00
|
|
|
|
2012-11-26 20:03:36 -06:00
|
|
|
type NominalPageChan = NominalOp<PageChan>;
|
|
|
|
|
2013-02-01 02:16:14 -06:00
|
|
|
fn make_doc_from_pages(page_port: &PagePort) -> doc::Doc {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut pages = ~[];
|
2012-03-09 18:11:56 -06:00
|
|
|
loop {
|
2013-02-01 02:16:14 -06:00
|
|
|
let val = page_port.recv();
|
2012-09-21 21:37:57 -05:00
|
|
|
if val.is_some() {
|
2013-05-27 18:04:00 -05:00
|
|
|
pages += [val.unwrap()];
|
2012-03-06 15:56:33 -06:00
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-01-29 21:45:53 -06:00
|
|
|
doc::Doc {
|
2012-03-06 15:56:33 -06:00
|
|
|
pages: pages
|
2013-01-29 21:45:53 -06:00
|
|
|
}
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
2013-01-30 21:32:36 -06:00
|
|
|
fn find_pages(doc: doc::Doc, page_chan: PageChan) {
|
2012-12-05 17:06:54 -06:00
|
|
|
let fold = Fold {
|
2013-02-01 02:16:14 -06:00
|
|
|
ctxt: NominalOp { op: page_chan.clone() },
|
2012-03-06 15:56:33 -06:00
|
|
|
fold_crate: fold_crate,
|
2012-03-10 18:44:48 -06:00
|
|
|
fold_mod: fold_mod,
|
2012-09-04 15:29:32 -05:00
|
|
|
fold_nmod: fold_nmod,
|
2013-02-01 02:16:14 -06:00
|
|
|
.. fold::default_any_fold(NominalOp { op: page_chan.clone() })
|
2012-12-05 17:06:54 -06:00
|
|
|
};
|
2013-01-30 15:14:35 -06:00
|
|
|
(fold.fold_doc)(&fold, copy doc);
|
2012-03-06 15:56:33 -06:00
|
|
|
|
2013-02-01 02:16:14 -06:00
|
|
|
page_chan.send(None);
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn fold_crate(
|
2012-11-26 20:03:36 -06:00
|
|
|
fold: &fold::Fold<NominalPageChan>,
|
2013-01-30 21:32:36 -06:00
|
|
|
doc: doc::CrateDoc
|
2012-09-18 18:48:40 -05:00
|
|
|
) -> doc::CrateDoc {
|
2012-03-06 15:56:33 -06:00
|
|
|
|
|
|
|
let doc = fold::default_seq_fold_crate(fold, doc);
|
|
|
|
|
2013-01-25 18:57:39 -06:00
|
|
|
let page = doc::CratePage(doc::CrateDoc {
|
2013-01-30 20:52:31 -06:00
|
|
|
topmod: strip_mod(copy doc.topmod),
|
2013-01-30 15:14:35 -06:00
|
|
|
.. copy doc
|
2012-03-06 15:56:33 -06:00
|
|
|
});
|
|
|
|
|
2013-02-01 02:16:14 -06:00
|
|
|
fold.ctxt.op.send(Some(page));
|
2012-03-06 15:56:33 -06:00
|
|
|
|
|
|
|
doc
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fold_mod(
|
2012-11-26 20:03:36 -06:00
|
|
|
fold: &fold::Fold<NominalPageChan>,
|
2013-01-30 21:32:36 -06:00
|
|
|
doc: doc::ModDoc
|
2012-09-18 18:48:40 -05:00
|
|
|
) -> doc::ModDoc {
|
2012-03-06 15:56:33 -06:00
|
|
|
|
|
|
|
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
|
|
|
|
2013-01-30 20:52:31 -06:00
|
|
|
let doc = strip_mod(copy doc);
|
2012-09-18 18:48:40 -05:00
|
|
|
let page = doc::ItemPage(doc::ModTag(doc));
|
2013-02-01 02:16:14 -06:00
|
|
|
fold.ctxt.op.send(Some(page));
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
doc
|
|
|
|
}
|
|
|
|
|
2013-01-30 21:32:36 -06:00
|
|
|
fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc {
|
2013-01-29 21:45:53 -06:00
|
|
|
doc::ModDoc {
|
2013-01-07 23:15:25 -06:00
|
|
|
items: do doc.items.filtered |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-03-06 15:56:33 -06:00
|
|
|
}
|
2012-09-04 15:29:32 -05:00
|
|
|
},
|
2013-01-30 15:14:35 -06:00
|
|
|
.. copy doc
|
2013-01-29 21:45:53 -06:00
|
|
|
}
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
|
2012-03-10 18:44:48 -06:00
|
|
|
fn fold_nmod(
|
2012-11-26 20:03:36 -06:00
|
|
|
fold: &fold::Fold<NominalPageChan>,
|
2013-01-30 21:32:36 -06:00
|
|
|
doc: doc::NmodDoc
|
2012-09-18 18:48:40 -05:00
|
|
|
) -> doc::NmodDoc {
|
2012-03-10 18:44:48 -06:00
|
|
|
let doc = fold::default_seq_fold_nmod(fold, doc);
|
2013-01-30 15:14:35 -06:00
|
|
|
let page = doc::ItemPage(doc::NmodTag(copy doc));
|
2013-02-01 02:16:14 -06:00
|
|
|
fold.ctxt.op.send(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
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2012-12-29 19:38:20 -06:00
|
|
|
use astsrv;
|
|
|
|
use config;
|
|
|
|
use doc;
|
|
|
|
use extract;
|
2013-01-08 21:37:25 -06:00
|
|
|
use page_pass::run;
|
2013-04-15 10:09:55 -05:00
|
|
|
use core::vec;
|
2012-12-29 19:38:20 -06:00
|
|
|
|
2013-04-15 10:09:55 -05:00
|
|
|
fn mk_doc_(
|
2012-09-18 18:48:40 -05:00
|
|
|
output_style: config::OutputStyle,
|
2013-01-30 21:32:36 -06:00
|
|
|
source: ~str
|
2012-09-18 18:48:40 -05:00
|
|
|
) -> doc::Doc {
|
2013-01-30 15:14:35 -06:00
|
|
|
do astsrv::from_str(copy source) |srv| {
|
2013-01-31 22:24:03 -06:00
|
|
|
let doc = extract::from_srv(srv.clone(), ~"");
|
|
|
|
run(srv.clone(), doc, output_style)
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-15 10:09:55 -05:00
|
|
|
fn mk_doc(source: ~str) -> doc::Doc {
|
2013-01-30 15:14:35 -06:00
|
|
|
mk_doc_(config::DocPerMod, copy source)
|
2012-03-06 15:56:33 -06:00
|
|
|
}
|
2013-04-15 10:09:55 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_not_split_the_doc_into_pages_for_doc_per_crate() {
|
|
|
|
let doc = mk_doc_(
|
|
|
|
config::DocPerCrate,
|
|
|
|
~"mod a { } mod b { mod c { } }"
|
|
|
|
);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(doc.pages.len(), 1u);
|
2013-04-15 10:09:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_make_a_page_for_every_mod() {
|
|
|
|
let doc = mk_doc(~"mod a { }");
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(doc.pages.mods()[0].name(), ~"a");
|
2013-04-15 10:09:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_remove_mods_from_containing_mods() {
|
|
|
|
let doc = mk_doc(~"mod a { }");
|
|
|
|
assert!(vec::is_empty(doc.cratemod().mods()));
|
|
|
|
}
|
2012-06-25 22:00:46 -05:00
|
|
|
}
|