rustdoc: Add support for type items
This commit is contained in:
parent
ae0d49aa06
commit
2b67de06c8
@ -90,6 +90,10 @@ fn stmt_to_str(s: ast::stmt) -> str { be to_str(s, print_stmt); }
|
||||
|
||||
fn item_to_str(i: @ast::item) -> str { be to_str(i, print_item); }
|
||||
|
||||
fn typarams_to_str(tps: [ast::ty_param]) -> str {
|
||||
be to_str(tps, print_type_params)
|
||||
}
|
||||
|
||||
fn path_to_str(&&p: @ast::path) -> str {
|
||||
be to_str(p, bind print_path(_, _, false));
|
||||
}
|
||||
@ -1253,7 +1257,7 @@ fn print_bounds(s: ps, bounds: @[ast::ty_param_bound]) {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_type_params(s: ps, params: [ast::ty_param]) {
|
||||
fn print_type_params(s: ps, &¶ms: [ast::ty_param]) {
|
||||
if vec::len(params) > 0u {
|
||||
word(s.s, "<");
|
||||
fn printParam(s: ps, param: ast::ty_param) {
|
||||
|
@ -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, impl_attrs;
|
||||
iface_attrs, method_attrs, impl_attrs, type_attrs;
|
||||
export parse_crate, parse_mod, parse_fn, parse_const,
|
||||
parse_enum, parse_variant, parse_res,
|
||||
parse_iface, parse_method, parse_impl;
|
||||
parse_iface, parse_method, parse_impl, parse_type;
|
||||
|
||||
type crate_attrs = {
|
||||
name: option<str>
|
||||
@ -70,6 +70,11 @@ type impl_attrs = {
|
||||
|
||||
type method_attrs = fn_attrs;
|
||||
|
||||
type type_attrs = {
|
||||
brief: option<str>,
|
||||
desc: option<str>
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
@ -507,4 +512,8 @@ fn parse_method(attrs: [ast::attribute]) -> method_attrs {
|
||||
|
||||
fn parse_impl(attrs: [ast::attribute]) -> impl_attrs {
|
||||
parse_basic(attrs)
|
||||
}
|
||||
|
||||
fn parse_type(attrs: [ast::attribute]) -> type_attrs {
|
||||
parse_basic(attrs)
|
||||
}
|
@ -27,7 +27,8 @@ fn run(
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
fold_impl: fold_impl,
|
||||
fold_type: fold_type
|
||||
with *fold::default_seq_fold(srv)
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -449,6 +450,30 @@ fn should_extract_impl_method_docs() {
|
||||
assert doc.topmod.impls()[0].methods[0].failure == some("failure");
|
||||
}
|
||||
|
||||
fn fold_type(
|
||||
fold: fold::fold<astsrv::srv>,
|
||||
doc: doc::tydoc
|
||||
) -> doc::tydoc {
|
||||
let srv = fold.ctxt;
|
||||
let doc = fold::default_seq_fold_type(fold, doc);
|
||||
let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_type);
|
||||
|
||||
{
|
||||
brief: attrs.brief,
|
||||
desc: attrs.desc
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_type_docs() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(brief = \"brief\", desc = \"desc\")]\
|
||||
type t = int;");
|
||||
assert doc.topmod.types()[0].brief == some("brief");
|
||||
assert doc.topmod.types()[0].desc == some("desc");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
|
@ -22,7 +22,8 @@ fn run(
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
fold_impl: fold_impl,
|
||||
fold_type: fold_type
|
||||
with *fold::default_seq_fold(op)
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -140,6 +141,14 @@ fn fold_impl(fold: fold::fold<op>, doc: doc::impldoc) -> doc::impldoc {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_type(fold: fold::fold<op>, doc: doc::tydoc) -> doc::tydoc {
|
||||
{
|
||||
brief: maybe_apply_op(fold.ctxt, doc.brief),
|
||||
desc: maybe_apply_op(fold.ctxt, doc.desc)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_enum_brief() {
|
||||
let doc = test::mk_doc("#[doc(brief = \" a \")] enum a { b }");
|
||||
@ -274,6 +283,21 @@ fn should_execute_op_on_impl_method_failure_condition() {
|
||||
assert doc.topmod.impls()[0].methods[0].failure == some("a");
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_type_brief() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(brief = \" a \")] type t = int;");
|
||||
assert doc.topmod.types()[0].brief == some("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_execute_op_on_type_desc() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc(desc = \" a \")] type t = int;");
|
||||
assert doc.topmod.types()[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
|
@ -24,7 +24,8 @@ fn run(
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
fold_impl: fold_impl,
|
||||
fold_type: fold_type
|
||||
with *fold::default_seq_fold(())
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -125,6 +126,17 @@ fn fold_impl(fold: fold::fold<()>, doc: doc::impldoc) -> doc::impldoc {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_type(fold: fold::fold<()>, doc: doc::tydoc) -> doc::tydoc {
|
||||
let doc = fold::default_seq_fold_type(fold, doc);
|
||||
let (brief, desc) = modify(doc.brief, doc.desc);
|
||||
|
||||
{
|
||||
brief: brief,
|
||||
desc: desc
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_mod_desc() {
|
||||
let doc = test::mk_doc("#[doc(desc = \"desc\")] mod m { }");
|
||||
@ -191,6 +203,13 @@ fn should_promote_impl_method_desc() {
|
||||
assert doc.topmod.impls()[0].methods[0].desc == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_promote_type_desc() {
|
||||
let doc = test::mk_doc("#[doc(desc = \"desc\")] type t = int;");
|
||||
assert doc.topmod.types()[0].brief == some("desc");
|
||||
assert doc.topmod.types()[0].desc == none;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
|
@ -13,7 +13,8 @@ enum itemtag {
|
||||
enumtag(enumdoc),
|
||||
restag(resdoc),
|
||||
ifacetag(ifacedoc),
|
||||
impltag(impldoc)
|
||||
impltag(impldoc),
|
||||
tytag(tydoc)
|
||||
}
|
||||
|
||||
type moddoc = {
|
||||
@ -107,6 +108,14 @@ type impldoc = {
|
||||
methods: [methoddoc]
|
||||
};
|
||||
|
||||
type tydoc = {
|
||||
id: ast_id,
|
||||
name: str,
|
||||
brief: option<str>,
|
||||
desc: option<str>,
|
||||
sig: option<str>
|
||||
};
|
||||
|
||||
#[doc = "Some helper methods on moddoc, mostly for testing"]
|
||||
impl util for moddoc {
|
||||
|
||||
@ -172,6 +181,15 @@ impl util for moddoc {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn types() -> [tydoc] {
|
||||
vec::filter_map(*self.items) {|itemtag|
|
||||
alt itemtag {
|
||||
tytag(tydoc) { some(tydoc) }
|
||||
_ { none }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Helper methods on itemtag"]
|
||||
@ -185,6 +203,7 @@ impl util for itemtag {
|
||||
doc::restag({name, _}) { name }
|
||||
doc::ifacetag({name, _}) { name }
|
||||
doc::impltag({name, _}) { name }
|
||||
doc::tytag({name, _}) { name }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,11 @@ fn moddoc_from_mod(
|
||||
impldoc_from_impl(methods, item.ident, item.id)
|
||||
))
|
||||
}
|
||||
ast::item_ty(_, _) {
|
||||
some(doc::tytag(
|
||||
tydoc_from_ty(item.ident, item.id)
|
||||
))
|
||||
}
|
||||
_ {
|
||||
none
|
||||
}
|
||||
@ -317,6 +322,25 @@ fn should_extract_impl_method_args() {
|
||||
assert doc.topmod.impls()[0].methods[0].args[0].name == "a";
|
||||
}
|
||||
|
||||
fn tydoc_from_ty(
|
||||
name: str,
|
||||
id: ast::node_id
|
||||
) -> doc::tydoc {
|
||||
{
|
||||
id: id,
|
||||
name: name,
|
||||
brief: none,
|
||||
desc: none,
|
||||
sig: none
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_tys() {
|
||||
let doc = test::mk_doc("type a = int;");
|
||||
assert doc.topmod.types()[0].name == "a";
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
|
@ -12,6 +12,7 @@ export default_seq_fold_enum;
|
||||
export default_seq_fold_res;
|
||||
export default_seq_fold_iface;
|
||||
export default_seq_fold_impl;
|
||||
export default_seq_fold_type;
|
||||
|
||||
enum fold<T> = t<T>;
|
||||
|
||||
@ -23,6 +24,7 @@ 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 fold_type<T> = fn~(fold: fold<T>, doc: doc::tydoc) -> doc::tydoc;
|
||||
|
||||
type t<T> = {
|
||||
ctxt: T,
|
||||
@ -33,7 +35,8 @@ type t<T> = {
|
||||
fold_enum: fold_enum<T>,
|
||||
fold_res: fold_res<T>,
|
||||
fold_iface: fold_iface<T>,
|
||||
fold_impl: fold_impl<T>
|
||||
fold_impl: fold_impl<T>,
|
||||
fold_type: fold_type<T>
|
||||
};
|
||||
|
||||
|
||||
@ -48,7 +51,8 @@ fn mk_fold<T:copy>(
|
||||
fold_enum: fold_enum<T>,
|
||||
fold_res: fold_res<T>,
|
||||
fold_iface: fold_iface<T>,
|
||||
fold_impl: fold_impl<T>
|
||||
fold_impl: fold_impl<T>,
|
||||
fold_type: fold_type<T>
|
||||
) -> fold<T> {
|
||||
fold({
|
||||
ctxt: ctxt,
|
||||
@ -59,7 +63,8 @@ fn mk_fold<T:copy>(
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
fold_impl: fold_impl,
|
||||
fold_type: fold_type
|
||||
})
|
||||
}
|
||||
|
||||
@ -73,7 +78,8 @@ fn default_seq_fold<T:copy>(ctxt: T) -> fold<T> {
|
||||
{|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_impl(f, d)}
|
||||
{|f, d| default_seq_fold_impl(f, d)},
|
||||
{|f, d| default_seq_fold_type(f, d)}
|
||||
)
|
||||
}
|
||||
|
||||
@ -114,6 +120,9 @@ fn default_seq_fold_mod<T>(
|
||||
doc::impltag(impldoc) {
|
||||
doc::impltag(fold.fold_impl(fold, impldoc))
|
||||
}
|
||||
doc::tytag(tydoc) {
|
||||
doc::tytag(fold.fold_type(fold, tydoc))
|
||||
}
|
||||
}
|
||||
}
|
||||
with doc
|
||||
@ -162,6 +171,13 @@ fn default_seq_fold_impl<T>(
|
||||
doc
|
||||
}
|
||||
|
||||
fn default_seq_fold_type<T>(
|
||||
_fold: fold<T>,
|
||||
doc: doc::tydoc
|
||||
) -> doc::tydoc {
|
||||
doc
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_fold_should_produce_same_doc() {
|
||||
let source = "mod a { fn b() { } mod c { fn d() { } } }";
|
||||
|
@ -139,6 +139,7 @@ fn write_mod_contents(
|
||||
doc::restag(resdoc) { write_res(ctxt, resdoc) }
|
||||
doc::ifacetag(ifacedoc) { write_iface(ctxt, ifacedoc) }
|
||||
doc::impltag(impldoc) { write_impl(ctxt, impldoc) }
|
||||
doc::tytag(tydoc) { write_type(ctxt, tydoc) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -743,6 +744,42 @@ fn should_write_impl_method_failure_conditions() {
|
||||
assert str::contains(markdown, "Failure conditions: nuked");
|
||||
}
|
||||
|
||||
fn write_type(
|
||||
ctxt: ctxt,
|
||||
doc: doc::tydoc
|
||||
) {
|
||||
write_header(ctxt, h2, #fmt("Type `%s`", doc.name));
|
||||
write_sig(ctxt, doc.sig);
|
||||
write_brief(ctxt, doc.brief);
|
||||
write_desc(ctxt, doc.desc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_type_header() {
|
||||
let markdown = test::render("type t = int;");
|
||||
assert str::contains(markdown, "## Type `t`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_type_brief() {
|
||||
let markdown = test::render(
|
||||
"#[doc(brief = \"brief\")] type t = int;");
|
||||
assert str::contains(markdown, "\n\nbrief\n\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_type_desc() {
|
||||
let markdown = test::render(
|
||||
"#[doc(desc = \"desc\")] type t = int;");
|
||||
assert str::contains(markdown, "\n\ndesc\n\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_write_type_signature() {
|
||||
let markdown = test::render("type t = int;");
|
||||
assert str::contains(markdown, "\n\n type t = int\n\n");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn render(source: str) -> str {
|
||||
|
@ -24,7 +24,8 @@ fn run(
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
fold_impl: fold_impl,
|
||||
fold_type: fold_type
|
||||
with *fold::default_seq_fold(ctxt)
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -93,6 +94,14 @@ fn fold_mod(
|
||||
none
|
||||
}
|
||||
}
|
||||
doc::tytag(tydoc) {
|
||||
let doc = fold.fold_type(fold, tydoc);
|
||||
if fold.ctxt.have_docs {
|
||||
some(doc::tytag(doc))
|
||||
} else {
|
||||
none
|
||||
}
|
||||
}
|
||||
_ { some(itemtag) }
|
||||
}
|
||||
}
|
||||
@ -335,6 +344,24 @@ fn should_not_elide_undocumented_impl_methods() {
|
||||
assert vec::is_not_empty(doc.topmod.impls()[0].methods);
|
||||
}
|
||||
|
||||
fn fold_type(
|
||||
fold: fold::fold<ctxt>,
|
||||
doc: doc::tydoc
|
||||
) -> doc::tydoc {
|
||||
let doc = fold::default_seq_fold_type(fold, doc);
|
||||
|
||||
fold.ctxt.have_docs =
|
||||
doc.brief != none
|
||||
|| doc.desc != none;
|
||||
ret doc;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_types() {
|
||||
let doc = test::mk_doc("type t = int;");
|
||||
assert vec::is_empty(doc.topmod.types());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
|
@ -220,6 +220,12 @@ fn should_prune_unexported_impls_from_top_mod() {
|
||||
assert vec::is_empty(doc.topmod.impls())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_prune_unexported_types() {
|
||||
let doc = test::mk_doc("export a; mod a { } type b = int;");
|
||||
assert vec::is_empty(doc.topmod.types());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
|
@ -21,7 +21,8 @@ fn run(
|
||||
fold_enum: fold_enum,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
fold_impl: fold_impl,
|
||||
fold_type: fold_type
|
||||
with *fold::default_seq_fold(srv)
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
@ -537,6 +538,40 @@ fn should_add_impl_method_arg_types() {
|
||||
assert fn_.args[1].ty == some("bool");
|
||||
}
|
||||
|
||||
fn fold_type(
|
||||
fold: fold::fold<astsrv::srv>,
|
||||
doc: doc::tydoc
|
||||
) -> doc::tydoc {
|
||||
|
||||
let srv = fold.ctxt;
|
||||
|
||||
{
|
||||
sig: astsrv::exec(srv) {|ctxt|
|
||||
alt ctxt.ast_map.get(doc.id) {
|
||||
ast_map::node_item(@{
|
||||
ident: ident,
|
||||
node: ast::item_ty(ty, params), _
|
||||
}) {
|
||||
some(#fmt(
|
||||
"type %s%s = %s",
|
||||
ident,
|
||||
pprust::typarams_to_str(params),
|
||||
pprust::ty_to_str(ty)
|
||||
))
|
||||
}
|
||||
_ { fail "expected type" }
|
||||
}
|
||||
}
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_add_type_signatures() {
|
||||
let doc = test::mk_doc("type t<T> = int;");
|
||||
assert doc.topmod.types()[0].sig == some("type t<T> = int");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
|
Loading…
x
Reference in New Issue
Block a user