rustdoc: Add type bounds to impls

This commit is contained in:
Brian Anderson 2013-03-25 16:11:02 -07:00
parent 0a0d3c7bd9
commit 34392ad5b4
4 changed files with 37 additions and 7 deletions

View File

@ -135,6 +135,7 @@ pub struct MethodDoc {
#[deriving(Eq)]
pub struct ImplDoc {
item: ItemDoc,
bounds_str: Option<~str>,
trait_types: ~[~str],
self_ty: Option<~str>,
methods: ~[MethodDoc]

View File

@ -277,6 +277,7 @@ fn impldoc_from_impl(
) -> doc::ImplDoc {
doc::ImplDoc {
item: itemdoc,
bounds_str: None,
trait_types: ~[],
self_ty: None,
methods: do vec::map(methods) |method| {

View File

@ -249,6 +249,11 @@ pub fn header_name(doc: doc::ItemTag) -> ~str {
}
&doc::ImplTag(ref doc) => {
fail_unless!(doc.self_ty.is_some());
let bounds = if (&doc.bounds_str).is_some() {
fmt!(" where %s", (&doc.bounds_str).get())
} else {
~""
};
let self_ty = (&doc.self_ty).get();
let mut trait_part = ~"";
for doc.trait_types.eachi |i, trait_type| {
@ -259,7 +264,7 @@ pub fn header_name(doc: doc::ItemTag) -> ~str {
}
trait_part += *trait_type;
}
fmt!("%s for %s", trait_part, self_ty)
fmt!("%s for %s%s", trait_part, self_ty, bounds)
}
_ => {
doc.name()
@ -271,11 +276,18 @@ pub fn header_text(doc: doc::ItemTag) -> ~str {
match &doc {
&doc::ImplTag(ref ImplDoc) => {
let header_kind = header_kind(copy doc);
let bounds = if (&ImplDoc.bounds_str).is_some() {
fmt!(" where `%s`", (&ImplDoc.bounds_str).get())
} else {
~""
};
let desc = if ImplDoc.trait_types.is_empty() {
fmt!("for `%s`", (&ImplDoc.self_ty).get())
fmt!("for `%s`%s", (&ImplDoc.self_ty).get(), bounds)
} else {
fmt!("of `%s` for `%s`", ImplDoc.trait_types[0],
(&ImplDoc.self_ty).get())
fmt!("of `%s` for `%s`%s",
ImplDoc.trait_types[0],
(&ImplDoc.self_ty).get(),
bounds)
};
return fmt!("%s %s", header_kind, desc);
}
@ -749,6 +761,12 @@ fn should_write_impl_header() {
fail_unless!(str::contains(markdown, ~"## Implementation for `int`"));
}
#[test]
fn should_write_impl_header_with_bounds() {
let markdown = test::render(~"impl <T> int<T> { }");
fail_unless!(str::contains(markdown, ~"## Implementation for `int<T>` where `<T>`"));
}
#[test]
fn should_write_impl_header_with_trait() {
let markdown = test::render(~"impl j for int { fn a() { } }");

View File

@ -271,17 +271,20 @@ fn fold_impl(
let srv = fold.ctxt.clone();
let (trait_types, self_ty) = {
let (bounds, trait_types, self_ty) = {
let doc = copy doc;
do astsrv::exec(srv) |ctxt| {
match ctxt.ast_map.get(&doc.id()) {
ast_map::node_item(@ast::item {
node: ast::item_impl(_, opt_trait_type, self_ty, _), _
node: ast::item_impl(ref generics, opt_trait_type, self_ty, _), _
}, _) => {
let bounds = pprust::generics_to_str(generics, extract::interner());
let bounds = if bounds.is_empty() { None } else { Some(bounds) };
let trait_types = opt_trait_type.map_default(~[], |p| {
~[pprust::path_to_str(p.path, extract::interner())]
});
(trait_types,
(bounds,
trait_types,
Some(pprust::ty_to_str(
self_ty, extract::interner())))
}
@ -291,6 +294,7 @@ fn fold_impl(
};
doc::ImplDoc {
bounds_str: bounds,
trait_types: trait_types,
self_ty: self_ty,
methods: merge_methods(fold.ctxt.clone(), doc.id(), copy doc.methods),
@ -298,6 +302,12 @@ fn fold_impl(
}
}
#[test]
fn should_add_impl_bounds() {
let doc = test::mk_doc(~"impl<T, U: Copy, V: Copy + Clone> Option<T, U, V> { }");
fail_unless!(doc.cratemod().impls()[0].bounds_str == Some(~"<T, U: Copy, V: Copy + Clone>"));
}
#[test]
fn should_add_impl_trait_types() {
let doc = test::mk_doc(~"impl j for int { fn a<T>() { } }");