2012-01-17 19:44:32 -06:00
|
|
|
#[doc = "Converts the Rust AST to the rustdoc document model"];
|
|
|
|
|
2012-01-15 19:23:19 -06:00
|
|
|
import rustc::syntax::ast;
|
2012-01-15 23:45:13 -06:00
|
|
|
|
2012-01-16 19:30:57 -06:00
|
|
|
export from_srv, extract;
|
|
|
|
|
|
|
|
fn from_srv(
|
2012-01-17 18:12:31 -06:00
|
|
|
srv: astsrv::srv,
|
2012-01-16 19:30:57 -06:00
|
|
|
default_name: str
|
|
|
|
) -> doc::cratedoc {
|
2012-01-18 16:06:22 -06:00
|
|
|
|
|
|
|
#[doc = "Use the AST service to create a document tree"];
|
|
|
|
|
2012-01-17 18:12:31 -06:00
|
|
|
astsrv::exec(srv) {|ctxt|
|
2012-01-16 19:30:57 -06:00
|
|
|
extract(ctxt.ast, default_name)
|
|
|
|
}
|
|
|
|
}
|
2012-01-15 19:23:19 -06:00
|
|
|
|
2012-01-15 23:45:13 -06:00
|
|
|
fn extract(
|
2012-01-16 02:19:35 -06:00
|
|
|
crate: @ast::crate,
|
|
|
|
default_name: str
|
2012-01-15 23:45:13 -06:00
|
|
|
) -> doc::cratedoc {
|
|
|
|
~{
|
2012-01-16 02:19:35 -06:00
|
|
|
topmod: top_moddoc_from_crate(crate, default_name),
|
2012-01-15 23:45:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn top_moddoc_from_crate(
|
2012-01-16 02:19:35 -06:00
|
|
|
crate: @ast::crate,
|
|
|
|
default_name: str
|
2012-01-15 23:45:13 -06:00
|
|
|
) -> doc::moddoc {
|
2012-01-18 20:35:55 -06:00
|
|
|
moddoc_from_mod(crate.node.module, default_name, ast::crate_node_id)
|
2012-01-15 23:45:13 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn moddoc_from_mod(
|
|
|
|
module: ast::_mod,
|
2012-01-18 20:35:55 -06:00
|
|
|
name: ast::ident,
|
|
|
|
id: ast::node_id
|
2012-01-15 23:45:13 -06:00
|
|
|
) -> doc::moddoc {
|
|
|
|
~{
|
2012-01-18 20:35:55 -06:00
|
|
|
id: id,
|
2012-01-15 23:45:13 -06:00
|
|
|
name: name,
|
2012-01-19 01:23:10 -06:00
|
|
|
path: [],
|
2012-01-18 20:11:26 -06:00
|
|
|
brief: none,
|
|
|
|
desc: none,
|
2012-01-28 16:36:35 -06:00
|
|
|
items: vec::filter_map(module.items) {|item|
|
|
|
|
alt item.node {
|
|
|
|
ast::item_res(decl, _, _, _, _) {
|
|
|
|
some(doc::restag(
|
|
|
|
resdoc_from_resource(decl, item.ident, item.id)
|
|
|
|
))
|
|
|
|
}
|
|
|
|
_ {
|
|
|
|
none
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2012-01-15 23:45:13 -06:00
|
|
|
mods: doc::modlist(
|
|
|
|
vec::filter_map(module.items) {|item|
|
|
|
|
alt item.node {
|
|
|
|
ast::item_mod(m) {
|
2012-01-18 20:35:55 -06:00
|
|
|
some(moddoc_from_mod(m, item.ident, item.id))
|
2012-01-15 23:45:13 -06:00
|
|
|
}
|
|
|
|
_ {
|
|
|
|
none
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
fns: doc::fnlist(
|
|
|
|
vec::filter_map(module.items) {|item|
|
|
|
|
alt item.node {
|
2012-01-16 18:01:33 -06:00
|
|
|
ast::item_fn(decl, _, _) {
|
2012-01-15 23:45:13 -06:00
|
|
|
some(fndoc_from_fn(
|
2012-01-16 18:01:33 -06:00
|
|
|
decl, item.ident, item.id))
|
2012-01-15 23:45:13 -06:00
|
|
|
}
|
|
|
|
_ {
|
|
|
|
none
|
|
|
|
}
|
|
|
|
}
|
2012-01-24 01:09:18 -06:00
|
|
|
}),
|
2012-01-24 01:17:13 -06:00
|
|
|
consts: doc::constlist(
|
|
|
|
vec::filter_map(module.items) {|item|
|
|
|
|
alt item.node {
|
|
|
|
ast::item_const(_, _) {
|
|
|
|
some(constdoc_from_const(item.ident, item.id))
|
|
|
|
}
|
|
|
|
_ {
|
|
|
|
none
|
|
|
|
}
|
|
|
|
}
|
2012-01-25 00:45:34 -06:00
|
|
|
}),
|
2012-01-25 18:50:32 -06:00
|
|
|
enums: doc::enumlist(
|
|
|
|
vec::filter_map(module.items) {|item|
|
|
|
|
alt item.node {
|
|
|
|
ast::item_enum(variants, _) {
|
|
|
|
some(enumdoc_from_enum(item.ident, item.id, variants))
|
|
|
|
}
|
|
|
|
_ {
|
|
|
|
none
|
|
|
|
}
|
|
|
|
}
|
2012-01-26 20:02:39 -06:00
|
|
|
})
|
2012-01-15 23:45:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fndoc_from_fn(
|
2012-01-18 16:43:19 -06:00
|
|
|
decl: ast::fn_decl,
|
2012-01-15 23:45:13 -06:00
|
|
|
name: ast::ident,
|
2012-01-16 18:01:33 -06:00
|
|
|
id: ast::node_id
|
2012-01-15 23:45:13 -06:00
|
|
|
) -> doc::fndoc {
|
2012-01-16 18:01:33 -06:00
|
|
|
~{
|
|
|
|
id: id,
|
|
|
|
name: name,
|
|
|
|
brief: none,
|
|
|
|
desc: none,
|
2012-01-18 23:57:18 -06:00
|
|
|
args: argdocs_from_args(decl.inputs),
|
2012-01-19 21:14:12 -06:00
|
|
|
return: {
|
|
|
|
desc: none,
|
|
|
|
ty: none
|
|
|
|
},
|
2012-01-24 20:05:57 -06:00
|
|
|
failure: none,
|
2012-01-19 20:09:19 -06:00
|
|
|
sig: none
|
2012-01-16 18:01:33 -06:00
|
|
|
}
|
2012-01-15 19:23:19 -06:00
|
|
|
}
|
|
|
|
|
2012-01-18 16:43:19 -06:00
|
|
|
#[test]
|
|
|
|
fn should_extract_fn_args() {
|
|
|
|
let source = "fn a(b: int, c: int) { }";
|
|
|
|
let ast = parse::from_str(source);
|
|
|
|
let doc = extract(ast, "");
|
|
|
|
let fn_ = doc.topmod.fns[0];
|
2012-01-18 16:47:18 -06:00
|
|
|
assert fn_.args[0].name == "b";
|
|
|
|
assert fn_.args[1].name == "c";
|
2012-01-18 16:43:19 -06:00
|
|
|
}
|
|
|
|
|
2012-01-18 16:47:18 -06:00
|
|
|
fn argdocs_from_args(args: [ast::arg]) -> [doc::argdoc] {
|
2012-01-18 16:43:19 -06:00
|
|
|
vec::map(args, argdoc_from_arg)
|
|
|
|
}
|
|
|
|
|
2012-01-18 16:47:18 -06:00
|
|
|
fn argdoc_from_arg(arg: ast::arg) -> doc::argdoc {
|
|
|
|
~{
|
2012-01-18 19:05:03 -06:00
|
|
|
name: arg.ident,
|
2012-01-19 00:24:29 -06:00
|
|
|
desc: none,
|
2012-01-18 19:05:03 -06:00
|
|
|
ty: none
|
2012-01-18 16:47:18 -06:00
|
|
|
}
|
2012-01-18 16:43:19 -06:00
|
|
|
}
|
|
|
|
|
2012-01-24 01:17:13 -06:00
|
|
|
fn constdoc_from_const(
|
|
|
|
name: ast::ident,
|
|
|
|
id: ast::node_id
|
|
|
|
) -> doc::constdoc {
|
|
|
|
~{
|
|
|
|
id: id,
|
|
|
|
name: name,
|
2012-01-24 01:55:41 -06:00
|
|
|
brief: none,
|
|
|
|
desc: none,
|
2012-01-24 01:17:13 -06:00
|
|
|
ty: none
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_extract_const_name_and_id() {
|
|
|
|
let source = "const a: int = 0;";
|
|
|
|
let ast = parse::from_str(source);
|
|
|
|
let doc = extract(ast, "");
|
|
|
|
assert doc.topmod.consts[0].id != 0;
|
|
|
|
assert doc.topmod.consts[0].name == "a";
|
|
|
|
}
|
|
|
|
|
2012-01-25 18:50:32 -06:00
|
|
|
fn enumdoc_from_enum(
|
|
|
|
name: ast::ident,
|
|
|
|
id: ast::node_id,
|
|
|
|
variants: [ast::variant]
|
|
|
|
) -> doc::enumdoc {
|
|
|
|
~{
|
|
|
|
id: id,
|
|
|
|
name: name,
|
|
|
|
brief: none,
|
|
|
|
desc: none,
|
|
|
|
variants: variantdocs_from_variants(variants)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn variantdocs_from_variants(
|
|
|
|
variants: [ast::variant]
|
|
|
|
) -> [doc::variantdoc] {
|
|
|
|
vec::map(variants, variantdoc_from_variant)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn variantdoc_from_variant(variant: ast::variant) -> doc::variantdoc {
|
|
|
|
~{
|
|
|
|
name: variant.node.name,
|
|
|
|
desc: none,
|
|
|
|
sig: none
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_extract_enums() {
|
|
|
|
let source = "enum e { v }";
|
|
|
|
let ast = parse::from_str(source);
|
|
|
|
let doc = extract(ast, "");
|
|
|
|
assert doc.topmod.enums[0].id != 0;
|
|
|
|
assert doc.topmod.enums[0].name == "e";
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_extract_enum_variants() {
|
|
|
|
let source = "enum e { v }";
|
|
|
|
let ast = parse::from_str(source);
|
|
|
|
let doc = extract(ast, "");
|
|
|
|
assert doc.topmod.enums[0].variants[0].name == "v";
|
|
|
|
}
|
|
|
|
|
2012-01-26 20:02:39 -06:00
|
|
|
fn resdoc_from_resource(
|
2012-01-27 00:14:16 -06:00
|
|
|
decl: ast::fn_decl,
|
2012-01-26 20:02:39 -06:00
|
|
|
name: str,
|
|
|
|
id: ast::node_id
|
|
|
|
) -> doc::resdoc {
|
|
|
|
~{
|
|
|
|
id: id,
|
|
|
|
name: name,
|
|
|
|
brief: none,
|
|
|
|
desc: none,
|
2012-01-27 00:14:16 -06:00
|
|
|
args: argdocs_from_args(decl.inputs),
|
2012-01-26 20:02:39 -06:00
|
|
|
sig: none
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_extract_resources() {
|
|
|
|
let source = "resource r(b: bool) { }";
|
|
|
|
let ast = parse::from_str(source);
|
|
|
|
let doc = extract(ast, "");
|
2012-01-28 16:36:35 -06:00
|
|
|
assert doc.topmod.resources()[0].id != 0;
|
|
|
|
assert doc.topmod.resources()[0].name == "r";
|
2012-01-26 20:02:39 -06:00
|
|
|
}
|
|
|
|
|
2012-01-27 00:14:16 -06:00
|
|
|
#[test]
|
|
|
|
fn should_extract_resource_args() {
|
|
|
|
let source = "resource r(b: bool) { }";
|
|
|
|
let ast = parse::from_str(source);
|
|
|
|
let doc = extract(ast, "");
|
2012-01-28 16:36:35 -06:00
|
|
|
assert doc.topmod.resources()[0].args[0].name == "b";
|
2012-01-27 00:14:16 -06:00
|
|
|
}
|
|
|
|
|
2012-01-15 19:23:19 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn extract_empty_crate() {
|
|
|
|
let source = ""; // empty crate
|
|
|
|
let ast = parse::from_str(source);
|
2012-01-16 02:19:35 -06:00
|
|
|
let doc = extract(ast, "");
|
2012-01-15 23:45:13 -06:00
|
|
|
// FIXME #1535: These are boxed to prevent a crash
|
|
|
|
assert ~doc.topmod.mods == ~doc::modlist([]);
|
|
|
|
assert ~doc.topmod.fns == ~doc::fnlist([]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn extract_mods() {
|
|
|
|
let source = "mod a { mod b { } mod c { } }";
|
|
|
|
let ast = parse::from_str(source);
|
2012-01-16 02:19:35 -06:00
|
|
|
let doc = extract(ast, "");
|
2012-01-15 23:45:13 -06:00
|
|
|
assert doc.topmod.mods[0].name == "a";
|
|
|
|
assert doc.topmod.mods[0].mods[0].name == "b";
|
|
|
|
assert doc.topmod.mods[0].mods[1].name == "c";
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn extract_mods_deep() {
|
|
|
|
let source = "mod a { mod b { mod c { } } }";
|
|
|
|
let ast = parse::from_str(source);
|
2012-01-16 02:19:35 -06:00
|
|
|
let doc = extract(ast, "");
|
2012-01-15 23:45:13 -06:00
|
|
|
assert doc.topmod.mods[0].mods[0].mods[0].name == "c";
|
|
|
|
}
|
|
|
|
|
2012-01-18 20:35:55 -06:00
|
|
|
#[test]
|
|
|
|
fn extract_should_set_mod_ast_id() {
|
|
|
|
let source = "mod a { }";
|
|
|
|
let ast = parse::from_str(source);
|
|
|
|
let doc = extract(ast, "");
|
|
|
|
assert doc.topmod.mods[0].id != 0;
|
|
|
|
}
|
|
|
|
|
2012-01-15 23:45:13 -06:00
|
|
|
#[test]
|
|
|
|
fn extract_fns() {
|
|
|
|
let source =
|
|
|
|
"fn a() { } \
|
|
|
|
mod b { fn c() { } }";
|
|
|
|
let ast = parse::from_str(source);
|
2012-01-16 02:19:35 -06:00
|
|
|
let doc = extract(ast, "");
|
2012-01-15 23:45:13 -06:00
|
|
|
assert doc.topmod.fns[0].name == "a";
|
|
|
|
assert doc.topmod.mods[0].fns[0].name == "c";
|
2012-01-15 19:23:19 -06:00
|
|
|
}
|
2012-01-16 02:15:03 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn extract_should_set_fn_ast_id() {
|
|
|
|
let source = "fn a() { }";
|
|
|
|
let ast = parse::from_str(source);
|
2012-01-16 02:19:35 -06:00
|
|
|
let doc = extract(ast, "");
|
2012-01-16 02:15:03 -06:00
|
|
|
assert doc.topmod.fns[0].id != 0;
|
|
|
|
}
|
2012-01-16 02:19:35 -06:00
|
|
|
|
|
|
|
#[test]
|
2012-01-16 18:01:33 -06:00
|
|
|
fn extract_should_use_default_crate_name() {
|
2012-01-16 02:19:35 -06:00
|
|
|
let source = "";
|
|
|
|
let ast = parse::from_str(source);
|
|
|
|
let doc = extract(ast, "burp");
|
|
|
|
assert doc.topmod.name == "burp";
|
|
|
|
}
|
2012-01-16 19:30:57 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn extract_from_seq_srv() {
|
|
|
|
let source = "";
|
2012-01-17 18:12:31 -06:00
|
|
|
let srv = astsrv::mk_srv_from_str(source);
|
2012-01-16 19:30:57 -06:00
|
|
|
let doc = from_srv(srv, "name");
|
|
|
|
assert doc.topmod.name == "name";
|
|
|
|
}
|
2012-01-15 19:23:19 -06:00
|
|
|
}
|