rust/src/rustdoc/extract.rs

320 lines
7.6 KiB
Rust
Raw Normal View History

2012-01-17 19:44:32 -06:00
#[doc = "Converts the Rust AST to the rustdoc document model"];
import rustc::syntax::ast;
export from_srv, extract;
fn from_srv(
srv: astsrv::srv,
default_name: str
) -> doc::cratedoc {
2012-01-18 16:06:22 -06:00
#[doc = "Use the AST service to create a document tree"];
astsrv::exec(srv) {|ctxt|
extract(ctxt.ast, default_name)
}
}
fn extract(
crate: @ast::crate,
default_name: str
) -> doc::cratedoc {
~{
topmod: top_moddoc_from_crate(crate, default_name),
}
}
fn top_moddoc_from_crate(
crate: @ast::crate,
default_name: str
) -> doc::moddoc {
2012-01-18 20:35:55 -06:00
moddoc_from_mod(crate.node.module, default_name, ast::crate_node_id)
}
fn moddoc_from_mod(
module: ast::_mod,
2012-01-18 20:35:55 -06:00
name: ast::ident,
id: ast::node_id
) -> doc::moddoc {
~{
2012-01-18 20:35:55 -06:00
id: id,
name: name,
2012-01-19 01:23:10 -06:00
path: [],
brief: none,
desc: none,
items: [],
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))
}
_ {
none
}
}
}),
fns: doc::fnlist(
vec::filter_map(module.items) {|item|
alt item.node {
ast::item_fn(decl, _, _) {
some(fndoc_from_fn(
decl, item.ident, item.id))
}
_ {
none
}
}
2012-01-24 01:09:18 -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
}),
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
}
}
}),
resources: doc::reslist(
vec::filter_map(module.items) {|item|
alt item.node {
ast::item_res(decl, _, _, _, _) {
some(resdoc_from_resource(decl, item.ident, item.id))
}
_ {
none
}
}
})
}
}
fn fndoc_from_fn(
decl: ast::fn_decl,
name: ast::ident,
id: ast::node_id
) -> doc::fndoc {
~{
id: id,
name: name,
brief: none,
desc: none,
args: argdocs_from_args(decl.inputs),
2012-01-19 21:14:12 -06:00
return: {
desc: none,
ty: none
},
failure: none,
sig: none
}
}
#[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:47:18 -06:00
fn argdocs_from_args(args: [ast::arg]) -> [doc::argdoc] {
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,
desc: none,
2012-01-18 19:05:03 -06:00
ty: none
2012-01-18 16:47:18 -06:00
}
}
fn constdoc_from_const(
name: ast::ident,
id: ast::node_id
) -> doc::constdoc {
~{
id: id,
name: name,
brief: none,
desc: none,
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";
}
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";
}
fn resdoc_from_resource(
decl: ast::fn_decl,
name: str,
id: ast::node_id
) -> doc::resdoc {
~{
id: id,
name: name,
brief: none,
desc: none,
args: argdocs_from_args(decl.inputs),
sig: none
}
}
#[test]
fn should_extract_resources() {
let source = "resource r(b: bool) { }";
let ast = parse::from_str(source);
let doc = extract(ast, "");
assert doc.topmod.resources[0].id != 0;
assert doc.topmod.resources[0].name == "r";
}
#[test]
fn should_extract_resource_args() {
let source = "resource r(b: bool) { }";
let ast = parse::from_str(source);
let doc = extract(ast, "");
assert doc.topmod.resources[0].args[0].name == "b";
}
#[cfg(test)]
mod tests {
#[test]
fn extract_empty_crate() {
let source = ""; // empty crate
let ast = parse::from_str(source);
let doc = extract(ast, "");
// 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);
let doc = extract(ast, "");
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);
let doc = extract(ast, "");
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;
}
#[test]
fn extract_fns() {
let source =
"fn a() { } \
mod b { fn c() { } }";
let ast = parse::from_str(source);
let doc = extract(ast, "");
assert doc.topmod.fns[0].name == "a";
assert doc.topmod.mods[0].fns[0].name == "c";
}
#[test]
fn extract_should_set_fn_ast_id() {
let source = "fn a() { }";
let ast = parse::from_str(source);
let doc = extract(ast, "");
assert doc.topmod.fns[0].id != 0;
}
#[test]
fn extract_should_use_default_crate_name() {
let source = "";
let ast = parse::from_str(source);
let doc = extract(ast, "burp");
assert doc.topmod.name == "burp";
}
#[test]
fn extract_from_seq_srv() {
let source = "";
let srv = astsrv::mk_srv_from_str(source);
let doc = from_srv(srv, "name");
assert doc.topmod.name == "name";
}
}