mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-20 10:55:14 +00:00
Merge branch 'master' into register-snapshots
This commit is contained in:
commit
e204aa281d
@ -30,7 +30,7 @@ This behavior can be disabled with the `no_core` crate attribute."
|
||||
|
||||
export box, char, float, bessel, f32, f64, int, str, ptr;
|
||||
export uint, u8, u32, u64, vec, bool;
|
||||
export either, option, result;
|
||||
export either, option, result, iter;
|
||||
export ctypes, sys, unsafe, comm, task, logging;
|
||||
export extfmt;
|
||||
export math;
|
||||
@ -64,7 +64,7 @@ mod either;
|
||||
mod option;
|
||||
mod result;
|
||||
mod tuple;
|
||||
|
||||
mod iter;
|
||||
|
||||
// Runtime and language-primitive support
|
||||
|
||||
|
171
src/libcore/iter.rs
Normal file
171
src/libcore/iter.rs
Normal file
@ -0,0 +1,171 @@
|
||||
iface iterable<A> {
|
||||
fn iter(blk: fn(A));
|
||||
}
|
||||
|
||||
impl<A> of iterable<A> for fn@(fn(A)) {
|
||||
fn iter(blk: fn(A)) {
|
||||
self(blk);
|
||||
}
|
||||
}
|
||||
|
||||
// accomodate the fact that int/uint are passed by value by default:
|
||||
impl of iterable<int> for fn@(fn(int)) {
|
||||
fn iter(blk: fn(&&int)) {
|
||||
self {|i| blk(i)}
|
||||
}
|
||||
}
|
||||
|
||||
impl of iterable<uint> for fn@(fn(uint)) {
|
||||
fn iter(blk: fn(&&uint)) {
|
||||
self {|i| blk(i)}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> of iterable<A> for [A] {
|
||||
fn iter(blk: fn(A)) {
|
||||
vec::iter(self, blk)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> of iterable<A> for option<A> {
|
||||
fn iter(blk: fn(A)) {
|
||||
option::may(self, blk)
|
||||
}
|
||||
}
|
||||
|
||||
fn enumerate<A,IA:iterable<A>>(self: IA, blk: fn(uint, A)) {
|
||||
let i = 0u;
|
||||
self.iter {|a|
|
||||
blk(i, a);
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
|
||||
// Here: we have to use fn@ for predicates and map functions, because
|
||||
// we will be binding them up into a closure. Disappointing. A true
|
||||
// region type system might be able to do better than this.
|
||||
|
||||
fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
|
||||
self.iter {|a|
|
||||
if prd(a) { blk(a) }
|
||||
}
|
||||
}
|
||||
|
||||
fn map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) {
|
||||
self.iter {|a|
|
||||
let b = cnv(a);
|
||||
blk(b);
|
||||
}
|
||||
}
|
||||
|
||||
fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>(
|
||||
self: IA, cnv: fn@(A) -> IB, blk: fn(B)) {
|
||||
self.iter {|a|
|
||||
cnv(a).iter(blk)
|
||||
}
|
||||
}
|
||||
|
||||
fn foldl<A,B:copy,IA:iterable<A>>(self: IA, b0: B, blk: fn(B, A) -> B) -> B {
|
||||
let b = b0;
|
||||
self.iter {|a|
|
||||
b = blk(b, a);
|
||||
}
|
||||
ret b;
|
||||
}
|
||||
|
||||
fn to_list<A:copy,IA:iterable<A>>(self: IA) -> [A] {
|
||||
foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
|
||||
}
|
||||
|
||||
fn repeat(times: uint, blk: fn()) {
|
||||
let i = 0u;
|
||||
while i < times {
|
||||
blk();
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_enumerate() {
|
||||
enumerate(["0", "1", "2"]) {|i,j|
|
||||
assert #fmt["%u",i] == j;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map_and_to_list() {
|
||||
let a = bind vec::iter([0, 1, 2], _);
|
||||
let b = bind map(a, {|i| i*2}, _);
|
||||
let c = to_list(b);
|
||||
assert c == [0, 2, 4];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map_directly_on_vec() {
|
||||
let b = bind map([0, 1, 2], {|i| i*2}, _);
|
||||
let c = to_list(b);
|
||||
assert c == [0, 2, 4];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_on_int_range() {
|
||||
fn is_even(&&i: int) -> bool {
|
||||
ret (i % 2) == 0;
|
||||
}
|
||||
|
||||
let l = to_list(bind filter(bind int::range(0, 10, _), is_even, _));
|
||||
assert l == [0, 2, 4, 6, 8];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_on_uint_range() {
|
||||
fn is_even(&&i: uint) -> bool {
|
||||
ret (i % 2u) == 0u;
|
||||
}
|
||||
|
||||
let l = to_list(bind filter(bind uint::range(0u, 10u, _), is_even, _));
|
||||
assert l == [0u, 2u, 4u, 6u, 8u];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flat_map_with_option() {
|
||||
fn if_even(&&i: int) -> option<int> {
|
||||
if (i % 2) == 0 { some(i) }
|
||||
else { none }
|
||||
}
|
||||
|
||||
let a = bind vec::iter([0, 1, 2], _);
|
||||
let b = bind flat_map(a, if_even, _);
|
||||
let c = to_list(b);
|
||||
assert c == [0, 2];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flat_map_with_list() {
|
||||
fn repeat(&&i: int) -> [int] {
|
||||
let r = [];
|
||||
int::range(0, i) {|_j| r += [i]; }
|
||||
r
|
||||
}
|
||||
|
||||
let a = bind vec::iter([0, 1, 2, 3], _);
|
||||
let b = bind flat_map(a, repeat, _);
|
||||
let c = to_list(b);
|
||||
#debug["c = %?", c];
|
||||
assert c == [1, 2, 2, 3, 3, 3];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeat() {
|
||||
let c = [],
|
||||
i = 0u;
|
||||
repeat(5u) {||
|
||||
c += [(i * i)];
|
||||
i += 1u;
|
||||
};
|
||||
#debug["c = %?", c];
|
||||
assert c == [0u, 1u, 4u, 9u, 16u];
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,10 @@ import core::tuple;
|
||||
|
||||
export crate_attrs, mod_attrs, fn_attrs, arg_attrs,
|
||||
const_attrs, enum_attrs, variant_attrs, res_attrs,
|
||||
iface_attrs, method_attrs;
|
||||
iface_attrs, method_attrs, impl_attrs;
|
||||
export parse_crate, parse_mod, parse_fn, parse_const,
|
||||
parse_enum, parse_variant, parse_res,
|
||||
parse_iface, parse_method;
|
||||
parse_iface, parse_method, parse_impl;
|
||||
|
||||
type crate_attrs = {
|
||||
name: option<str>
|
||||
@ -63,6 +63,11 @@ type iface_attrs = {
|
||||
desc: option<str>
|
||||
};
|
||||
|
||||
type impl_attrs = {
|
||||
brief: option<str>,
|
||||
desc: option<str>
|
||||
};
|
||||
|
||||
type method_attrs = fn_attrs;
|
||||
|
||||
#[cfg(test)]
|
||||
@ -499,3 +504,7 @@ fn parse_iface(attrs: [ast::attribute]) -> iface_attrs {
|
||||
fn parse_method(attrs: [ast::attribute]) -> method_attrs {
|
||||
parse_fn(attrs)
|
||||
}
|
||||
|
||||
fn parse_impl(attrs: [ast::attribute]) -> impl_attrs {
|
||||
parse_basic(attrs)
|
||||
}
|
@ -26,7 +26,8 @@ fn run(
|
||||
fold_const: fold_const,
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
with *fold::default_seq_fold(srv)
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -55,11 +56,7 @@ fn fold_crate(
|
||||
|
||||
#[test]
|
||||
fn should_replace_top_module_name_with_crate_name() {
|
||||
let source = "#[link(name = \"bond\")];";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_crate(fold, doc);
|
||||
let doc = test::mk_doc("#[link(name = \"bond\")];");
|
||||
assert doc.topmod.name == "bond";
|
||||
}
|
||||
|
||||
@ -105,22 +102,14 @@ fn fold_mod(fold: fold::fold<astsrv::srv>, doc: doc::moddoc) -> doc::moddoc {
|
||||
|
||||
#[test]
|
||||
fn fold_mod_should_extract_mod_attributes() {
|
||||
let source = "#[doc = \"test\"] mod a { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_mod(fold, doc.topmod.mods()[0]);
|
||||
assert doc.desc == some("test");
|
||||
let doc = test::mk_doc("#[doc = \"test\"] mod a { }");
|
||||
assert doc.topmod.mods()[0].desc == some("test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fold_mod_should_extract_top_mod_attributes() {
|
||||
let source = "#[doc = \"test\"];";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_mod(fold, doc.topmod);
|
||||
assert doc.desc == some("test");
|
||||
let doc = test::mk_doc("#[doc = \"test\"];");
|
||||
assert doc.topmod.desc == some("test");
|
||||
}
|
||||
|
||||
fn fold_fn(
|
||||
@ -181,22 +170,14 @@ fn merge_ret_attrs(
|
||||
|
||||
#[test]
|
||||
fn fold_fn_should_extract_fn_attributes() {
|
||||
let source = "#[doc = \"test\"] fn a() -> int { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_fn(fold, doc.topmod.fns()[0]);
|
||||
assert doc.desc == some("test");
|
||||
let doc = test::mk_doc("#[doc = \"test\"] fn a() -> int { }");
|
||||
assert doc.topmod.fns()[0].desc == some("test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fold_fn_should_extract_arg_attributes() {
|
||||
let source = "#[doc(args(a = \"b\"))] fn c(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_fn(fold, doc.topmod.fns()[0]);
|
||||
assert doc.args[0].desc == some("b");
|
||||
let doc = test::mk_doc("#[doc(args(a = \"b\"))] fn c(a: bool) { }");
|
||||
assert doc.topmod.fns()[0].args[0].desc == some("b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -223,12 +204,8 @@ fn fold_fn_should_preserve_sig() {
|
||||
|
||||
#[test]
|
||||
fn fold_fn_should_extract_failure_conditions() {
|
||||
let source = "#[doc(failure = \"what\")] fn a() { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_fn(fold, doc.topmod.fns()[0]);
|
||||
assert doc.failure == some("what");
|
||||
let doc = test::mk_doc("#[doc(failure = \"what\")] fn a() { }");
|
||||
assert doc.topmod.fns()[0].failure == some("what");
|
||||
}
|
||||
|
||||
fn fold_const(
|
||||
@ -247,14 +224,10 @@ fn fold_const(
|
||||
|
||||
#[test]
|
||||
fn fold_const_should_extract_docs() {
|
||||
let source = "#[doc(brief = \"foo\", desc = \"bar\")]\
|
||||
const a: bool = true;";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_const(fold, doc.topmod.consts()[0]);
|
||||
assert doc.brief == some("foo");
|
||||
assert doc.desc == some("bar");
|
||||
let doc = test::mk_doc("#[doc(brief = \"foo\", desc = \"bar\")]\
|
||||
const a: bool = true;");
|
||||
assert doc.topmod.consts()[0].brief == some("foo");
|
||||
assert doc.topmod.consts()[0].desc == some("bar");
|
||||
}
|
||||
|
||||
fn fold_enum(
|
||||
@ -295,24 +268,16 @@ fn fold_enum(
|
||||
|
||||
#[test]
|
||||
fn fold_enum_should_extract_docs() {
|
||||
let source = "#[doc(brief = \"a\", desc = \"b\")]\
|
||||
enum a { v }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_enum(fold, doc.topmod.enums()[0]);
|
||||
assert doc.brief == some("a");
|
||||
assert doc.desc == some("b");
|
||||
let doc = test::mk_doc("#[doc(brief = \"a\", desc = \"b\")]\
|
||||
enum a { v }");
|
||||
assert doc.topmod.enums()[0].brief == some("a");
|
||||
assert doc.topmod.enums()[0].desc == some("b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fold_enum_should_extract_variant_docs() {
|
||||
let source = "enum a { #[doc = \"c\"] v }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_enum(fold, doc.topmod.enums()[0]);
|
||||
assert doc.variants[0].desc == some("c");
|
||||
let doc = test::mk_doc("enum a { #[doc = \"c\"] v }");
|
||||
assert doc.topmod.enums()[0].variants[0].desc == some("c");
|
||||
}
|
||||
|
||||
fn fold_res(
|
||||
@ -345,26 +310,18 @@ fn fold_res(
|
||||
|
||||
#[test]
|
||||
fn fold_res_should_extract_docs() {
|
||||
let source = "#[doc(brief = \"a\", desc = \"b\")]\
|
||||
resource r(b: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_res(fold, doc.topmod.resources()[0]);
|
||||
assert doc.brief == some("a");
|
||||
assert doc.desc == some("b");
|
||||
let doc = test::mk_doc("#[doc(brief = \"a\", desc = \"b\")]\
|
||||
resource r(b: bool) { }");
|
||||
assert doc.topmod.resources()[0].brief == some("a");
|
||||
assert doc.topmod.resources()[0].desc == some("b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fold_res_should_extract_arg_docs() {
|
||||
let source = "#[doc(args(a = \"b\"))]\
|
||||
resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let fold = fold::default_seq_fold(srv);
|
||||
let doc = fold_res(fold, doc.topmod.resources()[0]);
|
||||
assert doc.args[0].name == "a";
|
||||
assert doc.args[0].desc == some("b");
|
||||
let doc = test::mk_doc("#[doc(args(a = \"b\"))]\
|
||||
resource r(a: bool) { }");
|
||||
assert doc.topmod.resources()[0].args[0].name == "a";
|
||||
assert doc.topmod.resources()[0].args[0].desc == some("b");
|
||||
}
|
||||
|
||||
fn fold_iface(
|
||||
@ -398,9 +355,14 @@ fn merge_method_attrs(
|
||||
(method.ident, attr_parser::parse_method(method.attrs))
|
||||
}
|
||||
}
|
||||
_ {
|
||||
fail "Undocumented invariant in merge_method_attrs";
|
||||
ast_map::node_item(@{
|
||||
node: ast::item_impl(_, _, _, methods), _
|
||||
}) {
|
||||
vec::map(methods) {|method|
|
||||
(method.ident, attr_parser::parse_method(method.attrs))
|
||||
}
|
||||
}
|
||||
_ { fail "unexpected item" }
|
||||
}
|
||||
};
|
||||
|
||||
@ -421,30 +383,77 @@ fn merge_method_attrs(
|
||||
|
||||
#[test]
|
||||
fn should_extract_iface_docs() {
|
||||
let source = "#[doc = \"whatever\"] iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc = \"whatever\"] iface i { fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].desc == some("whatever");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_iface_method_docs() {
|
||||
let source = "iface i {\
|
||||
#[doc(\
|
||||
brief = \"brief\",\
|
||||
desc = \"desc\",\
|
||||
args(a = \"a\"),\
|
||||
return = \"return\",\
|
||||
failure = \"failure\")]\
|
||||
fn f(a: bool) -> bool;\
|
||||
}";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"iface i {\
|
||||
#[doc(\
|
||||
brief = \"brief\",\
|
||||
desc = \"desc\",\
|
||||
args(a = \"a\"),\
|
||||
return = \"return\",\
|
||||
failure = \"failure\")]\
|
||||
fn f(a: bool) -> bool;\
|
||||
}");
|
||||
assert doc.topmod.ifaces()[0].methods[0].brief == some("brief");
|
||||
assert doc.topmod.ifaces()[0].methods[0].desc == some("desc");
|
||||
assert doc.topmod.ifaces()[0].methods[0].args[0].desc == some("a");
|
||||
assert doc.topmod.ifaces()[0].methods[0].return.desc == some("return");
|
||||
assert doc.topmod.ifaces()[0].methods[0].failure == some("failure");
|
||||
}
|
||||
|
||||
|
||||
fn fold_impl(
|
||||
fold: fold::fold<astsrv::srv>,
|
||||
doc: doc::impldoc
|
||||
) -> doc::impldoc {
|
||||
let srv = fold.ctxt;
|
||||
let doc = fold::default_seq_fold_impl(fold, doc);
|
||||
let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_impl);
|
||||
|
||||
{
|
||||
brief: attrs.brief,
|
||||
desc: attrs.desc,
|
||||
methods: merge_method_attrs(srv, doc.id, doc.methods)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_impl_docs() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc = \"whatever\"] impl i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].desc == some("whatever");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_impl_method_docs() {
|
||||
let doc = test::mk_doc(
|
||||
"impl i for int {\
|
||||
#[doc(\
|
||||
brief = \"brief\",\
|
||||
desc = \"desc\",\
|
||||
args(a = \"a\"),\
|
||||
return = \"return\",\
|
||||
failure = \"failure\")]\
|
||||
fn f(a: bool) -> bool { }\
|
||||
}");
|
||||
assert doc.topmod.impls()[0].methods[0].brief == some("brief");
|
||||
assert doc.topmod.impls()[0].methods[0].desc == some("desc");
|
||||
assert doc.topmod.impls()[0].methods[0].args[0].desc == some("a");
|
||||
assert doc.topmod.impls()[0].methods[0].return.desc == some("return");
|
||||
assert doc.topmod.impls()[0].methods[0].failure == some("failure");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
run(srv, doc)
|
||||
}
|
||||
}
|
@ -167,4 +167,15 @@ iface the_shunned_house {
|
||||
failure = "Will fail if bodies are removed from premises"
|
||||
)]
|
||||
fn construct() -> bool;
|
||||
}
|
||||
|
||||
#[doc = "Whatever"]
|
||||
impl of the_shunned_house for omnomnomy {
|
||||
#[doc(args(_unkempt_yard = "Whatever"))]
|
||||
fn dingy_house(_unkempt_yard: int) {
|
||||
}
|
||||
|
||||
fn construct() -> bool {
|
||||
fail;
|
||||
}
|
||||
}
|
@ -21,7 +21,8 @@ fn run(
|
||||
fold_fn: fold_fn,
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
with *fold::default_seq_fold(op)
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -104,154 +105,181 @@ fn fold_iface(fold: fold::fold<op>, doc: doc::ifacedoc) -> doc::ifacedoc {
|
||||
{
|
||||
brief: maybe_apply_op(fold.ctxt, doc.brief),
|
||||
desc: maybe_apply_op(fold.ctxt, doc.desc),
|
||||
methods: vec::map(doc.methods) {|doc|
|
||||
{
|
||||
brief: maybe_apply_op(fold.ctxt, doc.brief),
|
||||
desc: maybe_apply_op(fold.ctxt, doc.desc),
|
||||
args: vec::map(doc.args) {|doc|
|
||||
{
|
||||
desc: maybe_apply_op(fold.ctxt, doc.desc)
|
||||
with doc
|
||||
}
|
||||
},
|
||||
return: {
|
||||
desc: maybe_apply_op(fold.ctxt, doc.return.desc)
|
||||
with doc.return
|
||||
},
|
||||
failure: maybe_apply_op(fold.ctxt, doc.failure)
|
||||
with doc
|
||||
}
|
||||
methods: apply_to_methods(fold.ctxt, doc.methods)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_to_methods(op: op, docs: [doc::methoddoc]) -> [doc::methoddoc] {
|
||||
vec::map(docs) {|doc|
|
||||
{
|
||||
brief: maybe_apply_op(op, doc.brief),
|
||||
desc: maybe_apply_op(op, doc.desc),
|
||||
args: vec::map(doc.args) {|doc|
|
||||
{
|
||||
desc: maybe_apply_op(op, doc.desc)
|
||||
with doc
|
||||
}
|
||||
},
|
||||
return: {
|
||||
desc: maybe_apply_op(op, doc.return.desc)
|
||||
with doc.return
|
||||
},
|
||||
failure: maybe_apply_op(op, doc.failure)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_impl(fold: fold::fold<op>, doc: doc::impldoc) -> doc::impldoc {
|
||||
{
|
||||
brief: maybe_apply_op(fold.ctxt, doc.brief),
|
||||
desc: maybe_apply_op(fold.ctxt, doc.desc),
|
||||
methods: apply_to_methods(fold.ctxt, doc.methods)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_enum_brief() {
|
||||
let source = "#[doc(brief = \" a \")] enum a { b }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(brief = \" a \")] enum a { b }");
|
||||
assert doc.topmod.enums()[0].brief == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_enum_desc() {
|
||||
let source = "#[doc(desc = \" a \")] enum a { b }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(desc = \" a \")] enum a { b }");
|
||||
assert doc.topmod.enums()[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_variant_desc() {
|
||||
let source = "enum a { #[doc = \" a \"] b }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc("enum a { #[doc = \" a \"] b }");
|
||||
assert doc.topmod.enums()[0].variants[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_resource_brief() {
|
||||
let source = "#[doc(brief = \" a \")] resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(brief = \" a \")] resource r(a: bool) { }");
|
||||
assert doc.topmod.resources()[0].brief == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_resource_desc() {
|
||||
let source = "#[doc(desc = \" a \")] resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(desc = \" a \")] resource r(a: bool) { }");
|
||||
assert doc.topmod.resources()[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_resource_args() {
|
||||
let source = "#[doc(args(a = \" a \"))] resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(args(a = \" a \"))] resource r(a: bool) { }");
|
||||
assert doc.topmod.resources()[0].args[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_iface_brief() {
|
||||
let source = "#[doc(brief = \" a \")] iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(brief = \" a \")] iface i { fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].brief == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_iface_desc() {
|
||||
let source = "#[doc(desc = \" a \")] iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(desc = \" a \")] iface i { fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_iface_method_brief() {
|
||||
let source = "iface i { #[doc(brief = \" a \")] fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"iface i { #[doc(brief = \" a \")] fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].brief == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_iface_method_desc() {
|
||||
let source = "iface i { #[doc(desc = \" a \")] fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"iface i { #[doc(desc = \" a \")] fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_iface_method_args() {
|
||||
let source = "iface i { #[doc(args(a = \" a \"))] fn a(a: bool); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"iface i { #[doc(args(a = \" a \"))] fn a(a: bool); }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].args[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_iface_method_return() {
|
||||
let source = "iface i { #[doc(return = \" a \")] fn a() -> int; }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"iface i { #[doc(return = \" a \")] fn a() -> int; }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].return.desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_iface_method_failure_condition() {
|
||||
let source = "iface i { #[doc(failure = \" a \")] fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass(str::trim)(srv, doc);
|
||||
let doc = test::mk_doc("iface i { #[doc(failure = \" a \")] fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].failure == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_impl_brief() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(brief = \" a \")] impl i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].brief == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_impl_desc() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(desc = \" a \")] impl i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_impl_method_brief() {
|
||||
let doc = test::mk_doc(
|
||||
"impl i for int { #[doc(brief = \" a \")] fn a() { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].brief == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_impl_method_desc() {
|
||||
let doc = test::mk_doc(
|
||||
"impl i for int { #[doc(desc = \" a \")] fn a() { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_impl_method_args() {
|
||||
let doc = test::mk_doc(
|
||||
"impl i for int { #[doc(args(a = \" a \"))] fn a(a: bool) { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].args[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_impl_method_return() {
|
||||
let doc = test::mk_doc(
|
||||
"impl i for int { #[doc(return = \" a \")] fn a() -> int { fail } }");
|
||||
assert doc.topmod.impls()[0].methods[0].return.desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_impl_method_failure_condition() {
|
||||
let doc = test::mk_doc(
|
||||
"impl i for int { #[doc(failure = \" a \")] fn a() { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].failure == some("a");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
mk_pass(str::trim)(srv, doc)
|
||||
}
|
||||
}
|
@ -23,7 +23,8 @@ fn run(
|
||||
fold_fn: fold_fn,
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
with *fold::default_seq_fold(())
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -104,83 +105,102 @@ fn fold_iface(fold: fold::fold<()>, doc: doc::ifacedoc) -> doc::ifacedoc {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_impl(fold: fold::fold<()>, doc: doc::impldoc) -> doc::impldoc {
|
||||
let doc =fold::default_seq_fold_impl(fold, doc);
|
||||
let (brief, desc) = modify(doc.brief, doc.desc);
|
||||
|
||||
{
|
||||
brief: brief,
|
||||
desc: desc,
|
||||
methods: vec::map(doc.methods) {|doc|
|
||||
let (brief, desc) = modify(doc.brief, doc.desc);
|
||||
|
||||
{
|
||||
brief: brief,
|
||||
desc: desc
|
||||
with doc
|
||||
}
|
||||
}
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_mod_desc() {
|
||||
let source = "#[doc(desc = \"desc\")] mod m { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(desc = \"desc\")] mod m { }");
|
||||
assert doc.topmod.mods()[0].brief == some("desc");
|
||||
assert doc.topmod.mods()[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_const_desc() {
|
||||
let source = "#[doc(desc = \"desc\")] const a: bool = true;";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(desc = \"desc\")] const a: bool = true;");
|
||||
assert doc.topmod.consts()[0].brief == some("desc");
|
||||
assert doc.topmod.consts()[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_fn_desc() {
|
||||
let source = "#[doc(desc = \"desc\")] fn a() { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(desc = \"desc\")] fn a() { }");
|
||||
assert doc.topmod.fns()[0].brief == some("desc");
|
||||
assert doc.topmod.fns()[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_enum_desc() {
|
||||
let source = "#[doc(desc = \"desc\")] enum a { b }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(desc = \"desc\")] enum a { b }");
|
||||
assert doc.topmod.enums()[0].brief == some("desc");
|
||||
assert doc.topmod.enums()[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_resource_desc() {
|
||||
let source = "#[doc(desc = \"desc\")] resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(desc = \"desc\")] resource r(a: bool) { }");
|
||||
assert doc.topmod.resources()[0].brief == some("desc");
|
||||
assert doc.topmod.resources()[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_iface_desc() {
|
||||
let source = "#[doc(desc = \"desc\")] iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(desc = \"desc\")] iface i { fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].brief == some("desc");
|
||||
assert doc.topmod.ifaces()[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_iface_method_desc() {
|
||||
let source = "iface i { #[doc(desc = \"desc\")] fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("iface i { #[doc(desc = \"desc\")] fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].brief == some("desc");
|
||||
assert doc.topmod.ifaces()[0].methods[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_impl_desc() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(desc = \"desc\")] impl i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].brief == some("desc");
|
||||
assert doc.topmod.impls()[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_impl_method_desc() {
|
||||
let doc = test::mk_doc(
|
||||
"impl i for int { #[doc(desc = \"desc\")] fn a() { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].brief == some("desc");
|
||||
assert doc.topmod.impls()[0].methods[0].desc == none;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
run(srv, doc)
|
||||
}
|
||||
}
|
||||
|
||||
fn modify(
|
||||
brief: option<str>,
|
||||
desc: option<str>
|
||||
|
@ -12,7 +12,8 @@ enum itemtag {
|
||||
fntag(fndoc),
|
||||
enumtag(enumdoc),
|
||||
restag(resdoc),
|
||||
ifacetag(ifacedoc)
|
||||
ifacetag(ifacedoc),
|
||||
impltag(impldoc)
|
||||
}
|
||||
|
||||
type moddoc = {
|
||||
@ -96,6 +97,16 @@ type methoddoc = {
|
||||
sig: option<str>
|
||||
};
|
||||
|
||||
type impldoc = {
|
||||
id: ast_id,
|
||||
name: str,
|
||||
brief: option<str>,
|
||||
desc: option<str>,
|
||||
iface_ty: option<str>,
|
||||
self_ty: option<str>,
|
||||
methods: [methoddoc]
|
||||
};
|
||||
|
||||
#[doc = "Some helper methods on moddoc, mostly for testing"]
|
||||
impl util for moddoc {
|
||||
|
||||
@ -152,6 +163,15 @@ impl util for moddoc {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn impls() -> [impldoc] {
|
||||
vec::filter_map(*self.items) {|itemtag|
|
||||
alt itemtag {
|
||||
impltag(impldoc) { some(impldoc) }
|
||||
_ { none }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Helper methods on itemtag"]
|
||||
@ -164,6 +184,7 @@ impl util for itemtag {
|
||||
doc::enumtag({name, _}) { name }
|
||||
doc::restag({name, _}) { name }
|
||||
doc::ifacetag({name, _}) { name }
|
||||
doc::impltag({name, _}) { name }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,11 @@ fn moddoc_from_mod(
|
||||
ifacedoc_from_iface(methods, item.ident, item.id)
|
||||
))
|
||||
}
|
||||
ast::item_impl(_, _, _, methods) {
|
||||
some(doc::impltag(
|
||||
impldoc_from_impl(methods, item.ident, item.id)
|
||||
))
|
||||
}
|
||||
_ {
|
||||
none
|
||||
}
|
||||
@ -140,9 +145,7 @@ fn constdoc_from_const(
|
||||
|
||||
#[test]
|
||||
fn should_extract_const_name_and_id() {
|
||||
let source = "const a: int = 0;";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = test::mk_doc("const a: int = 0;");
|
||||
assert doc.topmod.consts()[0].id != 0;
|
||||
assert doc.topmod.consts()[0].name == "a";
|
||||
}
|
||||
@ -177,18 +180,14 @@ fn variantdoc_from_variant(variant: ast::variant) -> doc::variantdoc {
|
||||
|
||||
#[test]
|
||||
fn should_extract_enums() {
|
||||
let source = "enum e { v }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = test::mk_doc("enum e { v }");
|
||||
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, "");
|
||||
let doc = test::mk_doc("enum e { v }");
|
||||
assert doc.topmod.enums()[0].variants[0].name == "v";
|
||||
}
|
||||
|
||||
@ -209,18 +208,14 @@ fn resdoc_from_resource(
|
||||
|
||||
#[test]
|
||||
fn should_extract_resources() {
|
||||
let source = "resource r(b: bool) { }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = test::mk_doc("resource r(b: bool) { }");
|
||||
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, "");
|
||||
let doc = test::mk_doc("resource r(b: bool) { }");
|
||||
assert doc.topmod.resources()[0].args[0].name == "b";
|
||||
}
|
||||
|
||||
@ -253,45 +248,93 @@ fn ifacedoc_from_iface(
|
||||
|
||||
#[test]
|
||||
fn should_extract_ifaces() {
|
||||
let source = "iface i { fn f(); }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = test::mk_doc("iface i { fn f(); }");
|
||||
assert doc.topmod.ifaces()[0].name == "i";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_iface_methods() {
|
||||
let source = "iface i { fn f(); }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = test::mk_doc("iface i { fn f(); }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].name == "f";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_iface_method_args() {
|
||||
let source = "iface i { fn f(a: bool); }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = test::mk_doc("iface i { fn f(a: bool); }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].args[0].name == "a";
|
||||
}
|
||||
|
||||
fn impldoc_from_impl(
|
||||
methods: [@ast::method],
|
||||
name: str,
|
||||
id: ast::node_id
|
||||
) -> doc::impldoc {
|
||||
{
|
||||
id: id,
|
||||
name: name,
|
||||
brief: none,
|
||||
desc: none,
|
||||
iface_ty: none,
|
||||
self_ty: none,
|
||||
methods: vec::map(methods) {|method|
|
||||
{
|
||||
name: method.ident,
|
||||
brief: none,
|
||||
desc: none,
|
||||
args: argdocs_from_args(method.decl.inputs),
|
||||
return: {
|
||||
desc: none,
|
||||
ty: none
|
||||
},
|
||||
failure: none,
|
||||
sig: none
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_impls_with_names() {
|
||||
let doc = test::mk_doc("impl i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].name == "i";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_impls_without_names() {
|
||||
let doc = test::mk_doc("impl of i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].name == "i";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_impl_methods() {
|
||||
let doc = test::mk_doc("impl i for int { fn f() { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].name == "f";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_impl_method_args() {
|
||||
let doc = test::mk_doc("impl i for int { fn f(a: bool) { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].args[0].name == "a";
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
mod test {
|
||||
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let ast = parse::from_str(source);
|
||||
extract(ast, "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_empty_crate() {
|
||||
let source = ""; // empty crate
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = mk_doc("");
|
||||
assert vec::is_empty(doc.topmod.mods());
|
||||
assert vec::is_empty(doc.topmod.fns());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_mods() {
|
||||
let source = "mod a { mod b { } mod c { } }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = mk_doc("mod a { mod b { } mod c { } }");
|
||||
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";
|
||||
@ -299,36 +342,28 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn extract_mods_deep() {
|
||||
let source = "mod a { mod b { mod c { } } }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = mk_doc("mod a { mod b { mod c { } } }");
|
||||
assert doc.topmod.mods()[0].mods()[0].mods()[0].name == "c";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_should_set_mod_ast_id() {
|
||||
let source = "mod a { }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
let doc = mk_doc("mod a { }");
|
||||
assert doc.topmod.mods()[0].id != 0;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_fns() {
|
||||
let source =
|
||||
let doc = mk_doc(
|
||||
"fn a() { } \
|
||||
mod b { fn c() { } }";
|
||||
let ast = parse::from_str(source);
|
||||
let doc = extract(ast, "");
|
||||
mod b { fn c() { } }");
|
||||
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, "");
|
||||
let doc = mk_doc("fn a() { }");
|
||||
assert doc.topmod.fns()[0].id != 0;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ export default_seq_fold_const;
|
||||
export default_seq_fold_enum;
|
||||
export default_seq_fold_res;
|
||||
export default_seq_fold_iface;
|
||||
export default_seq_fold_impl;
|
||||
|
||||
enum fold<T> = t<T>;
|
||||
|
||||
@ -21,6 +22,7 @@ type fold_const<T> = fn~(fold: fold<T>, doc: doc::constdoc) -> doc::constdoc;
|
||||
type fold_enum<T> = fn~(fold: fold<T>, doc: doc::enumdoc) -> doc::enumdoc;
|
||||
type fold_res<T> = fn~(fold: fold<T>, doc: doc::resdoc) -> doc::resdoc;
|
||||
type fold_iface<T> = fn~(fold: fold<T>, doc: doc::ifacedoc) -> doc::ifacedoc;
|
||||
type fold_impl<T> = fn~(fold: fold<T>, doc: doc::impldoc) -> doc::impldoc;
|
||||
|
||||
type t<T> = {
|
||||
ctxt: T,
|
||||
@ -30,7 +32,8 @@ type t<T> = {
|
||||
fold_const: fold_const<T>,
|
||||
fold_enum: fold_enum<T>,
|
||||
fold_res: fold_res<T>,
|
||||
fold_iface: fold_iface<T>
|
||||
fold_iface: fold_iface<T>,
|
||||
fold_impl: fold_impl<T>
|
||||
};
|
||||
|
||||
|
||||
@ -44,7 +47,8 @@ fn mk_fold<T:copy>(
|
||||
fold_const: fold_const<T>,
|
||||
fold_enum: fold_enum<T>,
|
||||
fold_res: fold_res<T>,
|
||||
fold_iface: fold_iface<T>
|
||||
fold_iface: fold_iface<T>,
|
||||
fold_impl: fold_impl<T>
|
||||
) -> fold<T> {
|
||||
fold({
|
||||
ctxt: ctxt,
|
||||
@ -54,7 +58,8 @@ fn mk_fold<T:copy>(
|
||||
fold_const: fold_const,
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
})
|
||||
}
|
||||
|
||||
@ -67,7 +72,8 @@ fn default_seq_fold<T:copy>(ctxt: T) -> fold<T> {
|
||||
{|f, d| default_seq_fold_const(f, d)},
|
||||
{|f, d| default_seq_fold_enum(f, d)},
|
||||
{|f, d| default_seq_fold_res(f, d)},
|
||||
{|f, d| default_seq_fold_iface(f, d)}
|
||||
{|f, d| default_seq_fold_iface(f, d)},
|
||||
{|f, d| default_seq_fold_impl(f, d)}
|
||||
)
|
||||
}
|
||||
|
||||
@ -105,6 +111,9 @@ fn default_seq_fold_mod<T>(
|
||||
doc::ifacetag(ifacedoc) {
|
||||
doc::ifacetag(fold.fold_iface(fold, ifacedoc))
|
||||
}
|
||||
doc::impltag(impldoc) {
|
||||
doc::impltag(fold.fold_impl(fold, impldoc))
|
||||
}
|
||||
}
|
||||
}
|
||||
with doc
|
||||
@ -146,6 +155,13 @@ fn default_seq_fold_iface<T>(
|
||||
doc
|
||||
}
|
||||
|
||||
fn default_seq_fold_impl<T>(
|
||||
_fold: fold<T>,
|
||||
doc: doc::impldoc
|
||||
) -> doc::impldoc {
|
||||
doc
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_fold_should_produce_same_doc() {
|
||||
let source = "mod a { fn b() { } mod c { fn d() { } } }";
|
||||
|
@ -138,6 +138,7 @@ fn write_mod_contents(
|
||||
doc::enumtag(enumdoc) { write_enum(ctxt, enumdoc) }
|
||||
doc::restag(resdoc) { write_res(ctxt, resdoc) }
|
||||
doc::ifacetag(ifacedoc) { write_iface(ctxt, ifacedoc) }
|
||||
doc::impltag(impldoc) { write_impl(ctxt, impldoc) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -647,6 +648,101 @@ fn should_write_iface_method_failure_conditions() {
|
||||
assert str::contains(markdown, "Failure conditions: nuked");
|
||||
}
|
||||
|
||||
fn write_impl(ctxt: ctxt, doc: doc::impldoc) {
|
||||
assert option::is_some(doc.self_ty);
|
||||
let self_ty = option::get(doc.self_ty);
|
||||
alt doc.iface_ty {
|
||||
some(iface_ty) {
|
||||
write_header(ctxt, h2,
|
||||
#fmt("Implementation `%s` of `%s` for `%s`",
|
||||
doc.name, iface_ty, self_ty));
|
||||
}
|
||||
none {
|
||||
write_header(ctxt, h2,
|
||||
#fmt("Implementation `%s` for `%s`",
|
||||
doc.name, self_ty));
|
||||
}
|
||||
}
|
||||
write_brief(ctxt, doc.brief);
|
||||
write_desc(ctxt, doc.desc);
|
||||
write_methods(ctxt, doc.methods);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_header() {
|
||||
let markdown = test::render("impl i for int { fn a() { } }");
|
||||
assert str::contains(markdown, "## Implementation `i` for `int`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_header_with_iface() {
|
||||
let markdown = test::render("impl i of j for int { fn a() { } }");
|
||||
assert str::contains(markdown, "## Implementation `i` of `j` for `int`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_brief() {
|
||||
let markdown = test::render(
|
||||
"#[doc(brief = \"brief\")] impl i for int { fn a() { } }");
|
||||
assert str::contains(markdown, "brief");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_desc() {
|
||||
let markdown = test::render(
|
||||
"#[doc(desc = \"desc\")] impl i for int { fn a() { } }");
|
||||
assert str::contains(markdown, "desc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_method_header() {
|
||||
let markdown = test::render(
|
||||
"impl i for int { fn a() { } }");
|
||||
assert str::contains(markdown, "### Method `a`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_method_signature() {
|
||||
let markdown = test::render(
|
||||
"impl i for int { fn a() { } }");
|
||||
assert str::contains(markdown, "\n fn a()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_method_argument_header() {
|
||||
let markdown = test::render(
|
||||
"impl a for int { fn a(b: int) { } }");
|
||||
assert str::contains(markdown, "\n\nArguments:\n\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_method_arguments() {
|
||||
let markdown = test::render(
|
||||
"impl a for int { fn a(b: int) { } }");
|
||||
assert str::contains(markdown, "* `b`: `int`\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_write_impl_method_arguments_if_none() {
|
||||
let markdown = test::render(
|
||||
"impl a for int { fn a() { } }");
|
||||
assert !str::contains(markdown, "Arguments");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_method_return_info() {
|
||||
let markdown = test::render(
|
||||
"impl a for int { fn a() -> int { } }");
|
||||
assert str::contains(markdown, "Returns `int`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_impl_method_failure_conditions() {
|
||||
let markdown = test::render(
|
||||
"impl a for int { #[doc(failure = \"nuked\")] fn a() { } }");
|
||||
assert str::contains(markdown, "Failure conditions: nuked");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn render(source: str) -> str {
|
||||
|
@ -23,7 +23,8 @@ fn run(
|
||||
fold_const: fold_const,
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
with *fold::default_seq_fold(ctxt)
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -84,6 +85,14 @@ fn fold_mod(
|
||||
none
|
||||
}
|
||||
}
|
||||
doc::impltag(impldoc) {
|
||||
let doc = fold.fold_impl(fold, impldoc);
|
||||
if fold.ctxt.have_docs {
|
||||
some(doc::impltag(doc))
|
||||
} else {
|
||||
none
|
||||
}
|
||||
}
|
||||
_ { some(itemtag) }
|
||||
}
|
||||
}
|
||||
@ -138,21 +147,13 @@ fn prune_return(doc: doc::retdoc) -> doc::retdoc {
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_arguments() {
|
||||
let source = "#[doc = \"hey\"] fn a(b: int) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] fn a(b: int) { }");
|
||||
assert vec::is_empty(doc.topmod.fns()[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_fns_with_documented_arguments() {
|
||||
let source = "#[doc(args(a = \"b\"))] fn a(a: int) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(args(a = \"b\"))] fn a(a: int) { }");
|
||||
assert vec::is_not_empty(doc.topmod.fns());
|
||||
}
|
||||
|
||||
@ -169,49 +170,31 @@ fn should_elide_undocumented_return_values() {
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_fns_with_documented_failure_conditions() {
|
||||
let source = "#[doc(failure = \"yup\")] fn a() { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(failure = \"yup\")] fn a() { }");
|
||||
assert vec::is_not_empty(doc.topmod.fns());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_mods() {
|
||||
let source = "mod a { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("mod a { }");
|
||||
assert vec::is_empty(doc.topmod.mods());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_undocument_mods_with_documented_mods() {
|
||||
let source = "mod a { #[doc = \"b\"] mod b { } }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("mod a { #[doc = \"b\"] mod b { } }");
|
||||
assert vec::is_not_empty(doc.topmod.mods());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_undocument_mods_with_documented_fns() {
|
||||
let source = "mod a { #[doc = \"b\"] fn b() { } }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("mod a { #[doc = \"b\"] fn b() { } }");
|
||||
assert vec::is_not_empty(doc.topmod.mods());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_fns() {
|
||||
let source = "fn a() { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("fn a() { }");
|
||||
assert vec::is_empty(doc.topmod.fns());
|
||||
}
|
||||
|
||||
@ -228,10 +211,7 @@ fn fold_const(
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_consts() {
|
||||
let source = "const a: bool = true;";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("const a: bool = true;");
|
||||
assert vec::is_empty(doc.topmod.consts());
|
||||
}
|
||||
|
||||
@ -255,31 +235,19 @@ fn fold_enum(fold: fold::fold<ctxt>, doc: doc::enumdoc) -> doc::enumdoc {
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_enums() {
|
||||
let source = "enum a { b }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("enum a { b }");
|
||||
assert vec::is_empty(doc.topmod.enums());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_variants() {
|
||||
let source = "#[doc = \"a\"] enum a { b }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc = \"a\"] enum a { b }");
|
||||
assert vec::is_empty(doc.topmod.enums()[0].variants);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_enums_with_documented_variants() {
|
||||
let source = "enum a { #[doc = \"a\"] b }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("enum a { #[doc = \"a\"] b }");
|
||||
assert vec::is_not_empty(doc.topmod.enums());
|
||||
}
|
||||
|
||||
@ -303,32 +271,21 @@ fn fold_res(fold: fold::fold<ctxt>, doc: doc::resdoc) -> doc::resdoc {
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_resources() {
|
||||
let source = "resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("resource r(a: bool) { }");
|
||||
assert vec::is_empty(doc.topmod.resources());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_resource_args() {
|
||||
let source = "#[doc = \"drunk\"]\
|
||||
resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc = \"drunk\"]\
|
||||
resource r(a: bool) { }");
|
||||
assert vec::is_empty(doc.topmod.resources()[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_resources_with_documented_args() {
|
||||
let source = "#[doc(args(a = \"drunk\"))]\
|
||||
resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(args(a = \"drunk\"))]\
|
||||
resource r(a: bool) { }");
|
||||
assert vec::is_not_empty(doc.topmod.resources());
|
||||
}
|
||||
|
||||
@ -338,86 +295,133 @@ fn fold_iface(
|
||||
) -> doc::ifacedoc {
|
||||
let doc = fold::default_seq_fold_iface(fold, doc);
|
||||
let doc = {
|
||||
methods: vec::map(doc.methods) {|doc|
|
||||
{
|
||||
args: prune_args(doc.args),
|
||||
return: prune_return(doc.return)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
methods: prune_methods(doc.methods)
|
||||
with doc
|
||||
};
|
||||
let methods_have_docs = vec::foldl(false, doc.methods) {|accum, doc|
|
||||
fold.ctxt.have_docs =
|
||||
doc.brief != none
|
||||
|| doc.desc != none
|
||||
|| methods_have_docs(doc.methods);
|
||||
ret doc;
|
||||
}
|
||||
|
||||
fn prune_methods(docs: [doc::methoddoc]) -> [doc::methoddoc] {
|
||||
vec::map(docs) {|doc|
|
||||
{
|
||||
args: prune_args(doc.args),
|
||||
return: prune_return(doc.return)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn methods_have_docs(docs: [doc::methoddoc]) -> bool {
|
||||
vec::foldl(false, docs) {|accum, doc|
|
||||
accum
|
||||
|| doc.brief != none
|
||||
|| doc.desc != none
|
||||
|| vec::is_not_empty(doc.args)
|
||||
|| doc.return.desc != none
|
||||
|| doc.failure != none
|
||||
};
|
||||
fold.ctxt.have_docs =
|
||||
doc.brief != none
|
||||
|| doc.desc != none
|
||||
|| methods_have_docs;
|
||||
ret doc;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_ifaces() {
|
||||
let source = "iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("iface i { fn a(); }");
|
||||
assert vec::is_empty(doc.topmod.ifaces());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_documented_ifaces() {
|
||||
let source = "#[doc = \"hey\"] iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] iface i { fn a(); }");
|
||||
assert vec::is_not_empty(doc.topmod.ifaces());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_ifaces_with_documented_methods() {
|
||||
let source = "iface i { #[doc = \"hey\"] fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("iface i { #[doc = \"hey\"] fn a(); }");
|
||||
assert vec::is_not_empty(doc.topmod.ifaces());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_undocumented_methods() {
|
||||
let source = "#[doc = \"hey\"] iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
fn should_not_elide_undocumented_iface_methods() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] iface i { fn a(); }");
|
||||
assert vec::is_not_empty(doc.topmod.ifaces()[0].methods);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_method_args() {
|
||||
let source = "#[doc = \"hey\"] iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
fn should_elide_undocumented_iface_method_args() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] iface i { fn a(); }");
|
||||
assert vec::is_empty(doc.topmod.ifaces()[0].methods[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_method_return_values() {
|
||||
let source = "#[doc = \"hey\"] iface i { fn a() -> int; }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
fn should_elide_undocumented_iface_method_return_values() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] iface i { fn a() -> int; }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].return.ty == none;
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_impl(
|
||||
fold: fold::fold<ctxt>,
|
||||
doc: doc::impldoc
|
||||
) -> doc::impldoc {
|
||||
let doc = fold::default_seq_fold_impl(fold, doc);
|
||||
let doc = {
|
||||
methods: prune_methods(doc.methods)
|
||||
with doc
|
||||
};
|
||||
fold.ctxt.have_docs =
|
||||
doc.brief != none
|
||||
|| doc.desc != none
|
||||
|| methods_have_docs(doc.methods);
|
||||
ret doc;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_impls() {
|
||||
let doc = test::mk_doc("impl i for int { fn a() { } }");
|
||||
assert vec::is_empty(doc.topmod.impls());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_documented_impls() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] impl i for int { fn a() { } }");
|
||||
assert vec::is_not_empty(doc.topmod.impls());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_impls_with_documented_methods() {
|
||||
let doc = test::mk_doc("impl i for int { #[doc = \"hey\"] fn a() { } }");
|
||||
assert vec::is_not_empty(doc.topmod.impls());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_undocumented_impl_methods() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] impl i for int { fn a() { } }");
|
||||
assert vec::is_not_empty(doc.topmod.impls()[0].methods);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_impl_method_args() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc = \"hey\"] impl i for int { fn a(b: bool) { } }");
|
||||
assert vec::is_empty(doc.topmod.impls()[0].methods[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_impl_method_return_values() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc = \"hey\"] impl i for int { fn a() -> int { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].return.ty == none;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
run(srv, doc)
|
||||
}
|
||||
}
|
||||
|
@ -132,119 +132,99 @@ fn is_exported_from_crate(
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_fns() {
|
||||
let source = "mod b { export a; fn a() { } fn b() { } }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("mod b { export a; fn a() { } fn b() { } }");
|
||||
assert vec::len(doc.topmod.mods()[0].fns()) == 1u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_fns_from_top_mod() {
|
||||
let source = "export a; fn a() { } fn b() { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("export a; fn a() { } fn b() { }");
|
||||
assert vec::len(doc.topmod.fns()) == 1u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_modules() {
|
||||
let source = "mod a { export a; mod a { } mod b { } }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("mod a { export a; mod a { } mod b { } }");
|
||||
assert vec::len(doc.topmod.mods()[0].mods()) == 1u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_modules_from_top_mod() {
|
||||
let source = "export a; mod a { } mod b { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("export a; mod a { } mod b { }");
|
||||
assert vec::len(doc.topmod.mods()) == 1u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_consts() {
|
||||
let source = "mod a { export a; \
|
||||
const a: bool = true; \
|
||||
const b: bool = true; }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"mod a { export a; \
|
||||
const a: bool = true; \
|
||||
const b: bool = true; }");
|
||||
assert vec::len(doc.topmod.mods()[0].consts()) == 1u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_consts_from_top_mod() {
|
||||
let source = "export a; const a: bool = true; const b: bool = true;";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"export a; const a: bool = true; const b: bool = true;");
|
||||
assert vec::len(doc.topmod.consts()) == 1u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_enums_from_top_mod() {
|
||||
let source = "export a; mod a { } enum b { c }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("export a; mod a { } enum b { c }");
|
||||
assert vec::len(doc.topmod.enums()) == 0u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_enums() {
|
||||
let source = "mod a { export a; mod a { } enum b { c } }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("mod a { export a; mod a { } enum b { c } }");
|
||||
assert vec::len(doc.topmod.mods()[0].enums()) == 0u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_variants_from_top_mod() {
|
||||
let source = "export b::{}; enum b { c }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("export b::{}; enum b { c }");
|
||||
assert vec::len(doc.topmod.enums()[0].variants) == 0u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_variants() {
|
||||
let source = "mod a { export b::{}; enum b { c } }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("mod a { export b::{}; enum b { c } }");
|
||||
assert vec::len(doc.topmod.mods()[0].enums()[0].variants) == 0u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_resources_from_top_mod() {
|
||||
let source = "export a; mod a { } resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("export a; mod a { } resource r(a: bool) { }");
|
||||
assert vec::is_empty(doc.topmod.resources());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_resources() {
|
||||
let source = "mod a { export a; mod a { } resource r(a: bool) { } }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc(
|
||||
"mod a { export a; mod a { } resource r(a: bool) { } }");
|
||||
assert vec::is_empty(doc.topmod.mods()[0].resources());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_ifaces_from_top_mod() {
|
||||
let source = "export a; mod a { } iface b { fn c(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("export a; mod a { } iface b { fn c(); }");
|
||||
assert vec::is_empty(doc.topmod.ifaces());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_impls_from_top_mod() {
|
||||
let doc = test::mk_doc(
|
||||
"export a; mod a { } impl b for int { fn c() { } }");
|
||||
assert vec::is_empty(doc.topmod.impls())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
run(srv, doc)
|
||||
}
|
||||
}
|
@ -15,69 +15,55 @@ fn mk_pass() -> pass {
|
||||
|
||||
#[test]
|
||||
fn should_trim_mod() {
|
||||
let source = "#[doc(brief = \"\nbrief\n\", \
|
||||
desc = \"\ndesc\n\")] \
|
||||
mod m { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass()(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(brief = \"\nbrief\n\", \
|
||||
desc = \"\ndesc\n\")] \
|
||||
mod m { }");
|
||||
assert doc.topmod.mods()[0].brief == some("brief");
|
||||
assert doc.topmod.mods()[0].desc == some("desc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_trim_const() {
|
||||
let source = "#[doc(brief = \"\nbrief\n\", \
|
||||
desc = \"\ndesc\n\")] \
|
||||
const a: bool = true;";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass()(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(brief = \"\nbrief\n\", \
|
||||
desc = \"\ndesc\n\")] \
|
||||
const a: bool = true;");
|
||||
assert doc.topmod.consts()[0].brief == some("brief");
|
||||
assert doc.topmod.consts()[0].desc == some("desc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_trim_fn() {
|
||||
let source = "#[doc(brief = \"\nbrief\n\", \
|
||||
desc = \"\ndesc\n\")] \
|
||||
fn a() { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass()(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(brief = \"\nbrief\n\", \
|
||||
desc = \"\ndesc\n\")] \
|
||||
fn a() { }");
|
||||
assert doc.topmod.fns()[0].brief == some("brief");
|
||||
assert doc.topmod.fns()[0].desc == some("desc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_trim_args() {
|
||||
let source = "#[doc(args(a = \"\na\n\"))] fn a(a: int) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass()(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(args(a = \"\na\n\"))] fn a(a: int) { }");
|
||||
assert doc.topmod.fns()[0].args[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_trim_ret() {
|
||||
let source = "#[doc(return = \"\na\n\")] fn a() -> int { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass()(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(return = \"\na\n\")] fn a() -> int { }");
|
||||
assert doc.topmod.fns()[0].return.desc == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_trim_failure_conditions() {
|
||||
let source = "#[doc(failure = \"\na\n\")] fn a() -> int { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = mk_pass()(srv, doc);
|
||||
let doc = test::mk_doc("#[doc(failure = \"\na\n\")] fn a() -> int { }");
|
||||
assert doc.topmod.fns()[0].failure == some("a");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
mk_pass()(srv, doc)
|
||||
}
|
||||
}
|
@ -20,7 +20,8 @@ fn run(
|
||||
fold_const: fold_const,
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
with *fold::default_seq_fold(srv)
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -59,10 +60,7 @@ fn get_fn_sig(srv: astsrv::srv, fn_id: doc::ast_id) -> option<str> {
|
||||
|
||||
#[test]
|
||||
fn should_add_fn_sig() {
|
||||
let source = "fn a() -> int { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("fn a() -> int { }");
|
||||
assert doc.topmod.fns()[0].sig == some("fn a() -> int");
|
||||
}
|
||||
|
||||
@ -106,19 +104,13 @@ fn ret_ty_to_str(decl: ast::fn_decl) -> option<str> {
|
||||
|
||||
#[test]
|
||||
fn should_add_fn_ret_types() {
|
||||
let source = "fn a() -> int { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("fn a() -> int { }");
|
||||
assert doc.topmod.fns()[0].return.ty == some("int");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_add_nil_ret_type() {
|
||||
let source = "fn a() { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("fn a() { }");
|
||||
assert doc.topmod.fns()[0].return.ty == none;
|
||||
}
|
||||
|
||||
@ -164,10 +156,7 @@ fn decl_arg_tys(decl: ast::fn_decl) -> [(str, str)] {
|
||||
|
||||
#[test]
|
||||
fn should_add_arg_types() {
|
||||
let source = "fn a(b: int, c: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("fn a(b: int, c: bool) { }");
|
||||
let fn_ = doc.topmod.fns()[0];
|
||||
assert fn_.args[0].ty == some("int");
|
||||
assert fn_.args[1].ty == some("bool");
|
||||
@ -198,10 +187,7 @@ fn fold_const(
|
||||
|
||||
#[test]
|
||||
fn should_add_const_types() {
|
||||
let source = "const a: bool = true;";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("const a: bool = true;");
|
||||
assert doc.topmod.consts()[0].ty == some("bool");
|
||||
}
|
||||
|
||||
@ -240,10 +226,7 @@ fn fold_enum(
|
||||
|
||||
#[test]
|
||||
fn should_add_variant_sigs() {
|
||||
let source = "enum a { b(int) }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("enum a { b(int) }");
|
||||
assert doc.topmod.enums()[0].variants[0].sig == some("b(int)");
|
||||
}
|
||||
|
||||
@ -271,19 +254,13 @@ fn fold_res(
|
||||
|
||||
#[test]
|
||||
fn should_add_resource_sigs() {
|
||||
let source = "resource r(b: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("resource r(b: bool) { }");
|
||||
assert doc.topmod.resources()[0].sig == some("resource r(b: bool)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_resource_arg_tys() {
|
||||
let source = "resource r(a: bool) { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("resource r(a: bool) { }");
|
||||
assert doc.topmod.resources()[0].args[0].ty == some("bool");
|
||||
}
|
||||
|
||||
@ -291,30 +268,35 @@ fn fold_iface(
|
||||
fold: fold::fold<astsrv::srv>,
|
||||
doc: doc::ifacedoc
|
||||
) -> doc::ifacedoc {
|
||||
|
||||
let srv = fold.ctxt;
|
||||
|
||||
{
|
||||
methods: vec::map(doc.methods) {|methoddoc|
|
||||
{
|
||||
args: merge_method_arg_tys(
|
||||
srv,
|
||||
doc.id,
|
||||
methoddoc.args,
|
||||
methoddoc.name),
|
||||
return: merge_method_ret_ty(
|
||||
srv,
|
||||
doc.id,
|
||||
methoddoc.return,
|
||||
methoddoc.name),
|
||||
sig: get_method_sig(srv, doc.id, methoddoc.name)
|
||||
with methoddoc
|
||||
}
|
||||
}
|
||||
methods: merge_methods(fold.ctxt, doc.id, doc.methods)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_methods(
|
||||
srv: astsrv::srv,
|
||||
item_id: doc::ast_id,
|
||||
docs: [doc::methoddoc]
|
||||
) -> [doc::methoddoc] {
|
||||
vec::map(docs) {|doc|
|
||||
{
|
||||
args: merge_method_arg_tys(
|
||||
srv,
|
||||
item_id,
|
||||
doc.args,
|
||||
doc.name),
|
||||
return: merge_method_ret_ty(
|
||||
srv,
|
||||
item_id,
|
||||
doc.return,
|
||||
doc.name),
|
||||
sig: get_method_sig(srv, item_id, doc.name)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_method_ret_ty(
|
||||
srv: astsrv::srv,
|
||||
item_id: doc::ast_id,
|
||||
@ -351,7 +333,19 @@ fn get_method_ret_ty(
|
||||
_ { fail "get_method_ret_ty: undocumented invariant"; }
|
||||
}
|
||||
}
|
||||
_ { fail "get_method_ret_ty: undocumented invariant"; }
|
||||
ast_map::node_item(@{
|
||||
node: ast::item_impl(_, _, _, methods), _
|
||||
}) {
|
||||
alt vec::find(methods) {|method|
|
||||
method.ident == method_name
|
||||
} {
|
||||
some(method) {
|
||||
ret_ty_to_str(method.decl)
|
||||
}
|
||||
_ { fail "get_method_ret_ty: undocumented invariant"; }
|
||||
}
|
||||
}
|
||||
_ { fail }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -372,10 +366,22 @@ fn get_method_sig(
|
||||
some(method) {
|
||||
some(pprust::fun_to_str(method.decl, method.ident, []))
|
||||
}
|
||||
_ { fail "get_method_ret_sig: undocumented invariant"; }
|
||||
_ { fail "get_method_sig: undocumented invariant"; }
|
||||
}
|
||||
}
|
||||
_ { fail "get_method_ret_sig: undocumented invariant"; }
|
||||
ast_map::node_item(@{
|
||||
node: ast::item_impl(_, _, _, methods), _
|
||||
}) {
|
||||
alt vec::find(methods) {|method|
|
||||
method.ident == method_name
|
||||
} {
|
||||
some(method) {
|
||||
some(pprust::fun_to_str(method.decl, method.ident, []))
|
||||
}
|
||||
_ { fail "get_method_sig: undocumented invariant"; }
|
||||
}
|
||||
}
|
||||
_ { fail "get_method_sig: undocumented invariant"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -412,48 +418,130 @@ fn get_method_arg_tys(
|
||||
some(method) {
|
||||
decl_arg_tys(method.decl)
|
||||
}
|
||||
_ { fail "get_method_arg_tys: undocumented invariant"; }
|
||||
_ { fail "get_method_arg_tys: expected method"; }
|
||||
}
|
||||
}
|
||||
_ { fail "get_method_arg_tys: undocumented invariant"; }
|
||||
ast_map::node_item(@{
|
||||
node: ast::item_impl(_, _, _, methods), _
|
||||
}) {
|
||||
alt vec::find(methods) {|method|
|
||||
method.ident == method_name
|
||||
} {
|
||||
some(method) {
|
||||
decl_arg_tys(method.decl)
|
||||
}
|
||||
_ { fail "get_method_arg_tys: expected method"; }
|
||||
}
|
||||
}
|
||||
_ { fail }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_iface_method_sigs() {
|
||||
let source = "iface i { fn a() -> int; }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("iface i { fn a() -> int; }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].sig == some("fn a() -> int");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_iface_method_ret_types() {
|
||||
let source = "iface i { fn a() -> int; }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("iface i { fn a() -> int; }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].return.ty == some("int");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_add_iface_method_nil_ret_type() {
|
||||
let source = "iface i { fn a(); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("iface i { fn a(); }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].return.ty == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_iface_method_arg_types() {
|
||||
let source = "iface i { fn a(b: int, c: bool); }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = run(srv, doc);
|
||||
let doc = test::mk_doc("iface i { fn a(b: int, c: bool); }");
|
||||
let fn_ = doc.topmod.ifaces()[0].methods[0];
|
||||
assert fn_.args[0].ty == some("int");
|
||||
assert fn_.args[1].ty == some("bool");
|
||||
}
|
||||
|
||||
fn fold_impl(
|
||||
fold: fold::fold<astsrv::srv>,
|
||||
doc: doc::impldoc
|
||||
) -> doc::impldoc {
|
||||
|
||||
let srv = fold.ctxt;
|
||||
|
||||
let (iface_ty, self_ty) = astsrv::exec(srv) {|ctxt|
|
||||
alt ctxt.ast_map.get(doc.id) {
|
||||
ast_map::node_item(@{
|
||||
node: ast::item_impl(_, iface_ty, self_ty, _), _
|
||||
}) {
|
||||
let iface_ty = option::map(iface_ty) {|iface_ty|
|
||||
pprust::ty_to_str(iface_ty)
|
||||
};
|
||||
(iface_ty, some(pprust::ty_to_str(self_ty)))
|
||||
}
|
||||
_ { fail "expected impl" }
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
iface_ty: iface_ty,
|
||||
self_ty: self_ty,
|
||||
methods: merge_methods(fold.ctxt, doc.id, doc.methods)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_impl_iface_ty() {
|
||||
let doc = test::mk_doc("impl i of j for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].iface_ty == some("j");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_add_impl_iface_ty_if_none() {
|
||||
let doc = test::mk_doc("impl i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].iface_ty == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_impl_self_ty() {
|
||||
let doc = test::mk_doc("impl i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].self_ty == some("int");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_impl_method_sigs() {
|
||||
let doc = test::mk_doc("impl i for int { fn a() -> int { fail } }");
|
||||
assert doc.topmod.impls()[0].methods[0].sig == some("fn a() -> int");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_impl_method_ret_types() {
|
||||
let doc = test::mk_doc("impl i for int { fn a() -> int { fail } }");
|
||||
assert doc.topmod.impls()[0].methods[0].return.ty == some("int");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_add_impl_method_nil_ret_type() {
|
||||
let doc = test::mk_doc("impl i for int { fn a() { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].return.ty == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_impl_method_arg_types() {
|
||||
let doc = test::mk_doc("impl i for int { fn a(b: int, c: bool) { } }");
|
||||
let fn_ = doc.topmod.impls()[0].methods[0];
|
||||
assert fn_.args[0].ty == some("int");
|
||||
assert fn_.args[1].ty == some("bool");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
run(srv, doc)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user