diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-09-29 08:10:47 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-09-29 08:10:47 -0700 |
| commit | 6c23789ad1f62e39220e5e178928ecdad9db2a38 (patch) | |
| tree | 571b63ca082e79600f9403d18f14ca5b959c88aa | |
| parent | 655b7269c865b8ff446296bdb7640c6ad5c4f965 (diff) | |
| parent | 54831f128fac3ad92bd7244aafaf52763452e51b (diff) | |
| download | rust-6c23789ad1f62e39220e5e178928ecdad9db2a38.tar.gz rust-6c23789ad1f62e39220e5e178928ecdad9db2a38.zip | |
rollup merge of #17531 : tomjakubowski/rustdoc-where-clauses
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 24 | ||||
| -rw-r--r-- | src/librustdoc/html/format.rs | 45 | ||||
| -rw-r--r-- | src/librustdoc/html/render.rs | 28 | ||||
| -rw-r--r-- | src/test/run-make/rustdoc-where/Makefile | 6 | ||||
| -rw-r--r-- | src/test/run-make/rustdoc-where/foo.rs | 26 | ||||
| -rwxr-xr-x | src/test/run-make/rustdoc-where/verify.sh | 23 |
6 files changed, 131 insertions, 21 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5ac7baaa6d1..666be2debda 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -641,11 +641,27 @@ impl Clean<Option<Lifetime>> for ty::Region { } } +#[deriving(Clone, Encodable, Decodable, PartialEq)] +pub struct WherePredicate { + pub name: String, + pub bounds: Vec<TyParamBound> +} + +impl Clean<WherePredicate> for ast::WherePredicate { + fn clean(&self, cx: &DocContext) -> WherePredicate { + WherePredicate { + name: self.ident.clean(cx), + bounds: self.bounds.clean(cx) + } + } +} + // maybe use a Generic enum and use ~[Generic]? #[deriving(Clone, Encodable, Decodable, PartialEq)] pub struct Generics { pub lifetimes: Vec<Lifetime>, pub type_params: Vec<TyParam>, + pub where_predicates: Vec<WherePredicate> } impl Clean<Generics> for ast::Generics { @@ -653,6 +669,7 @@ impl Clean<Generics> for ast::Generics { Generics { lifetimes: self.lifetimes.clean(cx), type_params: self.ty_params.clean(cx), + where_predicates: self.where_clause.predicates.clean(cx) } } } @@ -663,6 +680,7 @@ impl<'a> Clean<Generics> for (&'a ty::Generics, subst::ParamSpace) { Generics { type_params: me.types.get_slice(space).to_vec().clean(cx), lifetimes: me.regions.get_slice(space).to_vec().clean(cx), + where_predicates: vec![] } } } @@ -1260,7 +1278,9 @@ impl Clean<Type> for ty::t { ty::ty_bare_fn(ref fty) => BareFunction(box BareFunctionDecl { fn_style: fty.fn_style, generics: Generics { - lifetimes: Vec::new(), type_params: Vec::new() + lifetimes: Vec::new(), + type_params: Vec::new(), + where_predicates: Vec::new() }, decl: (ast_util::local_def(0), &fty.sig).clean(cx), abi: fty.abi.to_string(), @@ -1670,6 +1690,7 @@ impl Clean<BareFunctionDecl> for ast::BareFnTy { generics: Generics { lifetimes: self.lifetimes.clean(cx), type_params: Vec::new(), + where_predicates: Vec::new() }, decl: self.decl.clean(cx), abi: self.abi.to_string(), @@ -2172,6 +2193,7 @@ impl Clean<Item> for ast::Typedef { generics: Generics { lifetimes: Vec::new(), type_params: Vec::new(), + where_predicates: Vec::new() }, }), visibility: None, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index c807c180e64..947d9f05ae2 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -44,6 +44,11 @@ pub struct RawMutableSpace(pub clean::Mutability); pub struct Stability<'a>(pub &'a Option<clean::Stability>); /// Wrapper struct for emitting the stability level concisely. pub struct ConciseStability<'a>(pub &'a Option<clean::Stability>); +/// Wrapper struct for emitting a where clause from Generics. +pub struct WhereClause<'a>(pub &'a clean::Generics); + +/// Wrapper struct for emitting type parameter bounds. +struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]); impl VisSpace { pub fn get(&self) -> Option<ast::Visibility> { @@ -57,6 +62,19 @@ impl FnStyleSpace { } } +impl<'a> fmt::Show for TyParamBounds<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let &TyParamBounds(bounds) = self; + for (i, bound) in bounds.iter().enumerate() { + if i > 0 { + try!(f.write(" + ".as_bytes())); + } + try!(write!(f, "{}", *bound)); + } + Ok(()) + } +} + impl fmt::Show for clean::Generics { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) } @@ -73,7 +91,6 @@ impl fmt::Show for clean::Generics { if self.lifetimes.len() > 0 { try!(f.write(", ".as_bytes())); } - for (i, tp) in self.type_params.iter().enumerate() { if i > 0 { try!(f.write(", ".as_bytes())) @@ -81,13 +98,7 @@ impl fmt::Show for clean::Generics { try!(f.write(tp.name.as_bytes())); if tp.bounds.len() > 0 { - try!(f.write(": ".as_bytes())); - for (i, bound) in tp.bounds.iter().enumerate() { - if i > 0 { - try!(f.write(" + ".as_bytes())); - } - try!(write!(f, "{}", *bound)); - } + try!(write!(f, ": {}", TyParamBounds(tp.bounds.as_slice()))); } match tp.default { @@ -101,6 +112,24 @@ impl fmt::Show for clean::Generics { } } +impl<'a> fmt::Show for WhereClause<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let &WhereClause(gens) = self; + if gens.where_predicates.len() == 0 { + return Ok(()); + } + try!(f.write(" where ".as_bytes())); + for (i, pred) in gens.where_predicates.iter().enumerate() { + if i > 0 { + try!(f.write(", ".as_bytes())); + } + let bounds = pred.bounds.as_slice(); + try!(write!(f, "{}: {}", pred.name, TyParamBounds(bounds))); + } + Ok(()) + } +} + impl fmt::Show for clean::Lifetime { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(f.write(self.get_ref().as_bytes())); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 3cd3fe3053a..8668e684c2d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -56,7 +56,7 @@ use clean; use doctree; use fold::DocFolder; use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace, Stability}; -use html::format::{ConciseStability}; +use html::format::{ConciseStability, WhereClause}; use html::highlight; use html::item_type::{ItemType, shortty}; use html::item_type; @@ -1610,11 +1610,12 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, fn item_function(w: &mut fmt::Formatter, it: &clean::Item, f: &clean::Function) -> fmt::Result { try!(write!(w, "<pre class='rust fn'>{vis}{fn_style}fn \ - {name}{generics}{decl}</pre>", + {name}{generics}{decl}{where_clause}</pre>", vis = VisSpace(it.visibility), fn_style = FnStyleSpace(f.fn_style), name = it.name.get_ref().as_slice(), generics = f.generics, + where_clause = WhereClause(&f.generics), decl = f.decl)); document(w, it) } @@ -1631,11 +1632,12 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } // Output the trait definition - try!(write!(w, "<pre class='rust trait'>{}trait {}{}{} ", + try!(write!(w, "<pre class='rust trait'>{}trait {}{}{}{} ", VisSpace(it.visibility), it.name.get_ref().as_slice(), t.generics, - bounds)); + bounds, + WhereClause(&t.generics))); let required = t.items.iter() .filter(|m| { match **m { @@ -1719,9 +1721,9 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, match cache.implementors.find(&it.def_id) { Some(implementors) => { for i in implementors.iter() { - try!(writeln!(w, "<li>{}<code>impl{} {} for {}</code></li>", + try!(writeln!(w, "<li>{}<code>impl{} {} for {}{}</code></li>", ConciseStability(&i.stability), - i.generics, i.trait_, i.for_)); + i.generics, i.trait_, i.for_, WhereClause(&i.generics))); } } None => {} @@ -1747,7 +1749,7 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result { g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl) -> fmt::Result { write!(w, "{}fn <a href='#{ty}.{name}' class='fnname'>{name}</a>\ - {generics}{decl}", + {generics}{decl}{where_clause}", match fn_style { ast::UnsafeFn => "unsafe ", _ => "", @@ -1755,7 +1757,8 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result { ty = shortty(it), name = it.name.get_ref().as_slice(), generics = *g, - decl = Method(selfty, d)) + decl = Method(selfty, d), + where_clause = WhereClause(g)) } match meth.inner { clean::TyMethodItem(ref m) => { @@ -1810,10 +1813,11 @@ fn item_struct(w: &mut fmt::Formatter, it: &clean::Item, fn item_enum(w: &mut fmt::Formatter, it: &clean::Item, e: &clean::Enum) -> fmt::Result { - try!(write!(w, "<pre class='rust enum'>{}enum {}{}", + try!(write!(w, "<pre class='rust enum'>{}enum {}{}{}", VisSpace(it.visibility), it.name.get_ref().as_slice(), - e.generics)); + e.generics, + WhereClause(&e.generics))); if e.variants.len() == 0 && !e.variants_stripped { try!(write!(w, " {{}}")); } else { @@ -1917,7 +1921,7 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item, if structhead {"struct "} else {""}, it.name.get_ref().as_slice())); match g { - Some(g) => try!(write!(w, "{}", *g)), + Some(g) => try!(write!(w, "{}{}", *g, WhereClause(g))), None => {} } match ty { @@ -2009,7 +2013,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result { Some(ref ty) => try!(write!(w, "{} for ", *ty)), None => {} } - try!(write!(w, "{}</code></h3>", i.impl_.for_)); + try!(write!(w, "{}{}</code></h3>", i.impl_.for_, WhereClause(&i.impl_.generics))); match i.dox { Some(ref dox) => { try!(write!(w, "<div class='docblock'>{}</div>", diff --git a/src/test/run-make/rustdoc-where/Makefile b/src/test/run-make/rustdoc-where/Makefile new file mode 100644 index 00000000000..864d594cf99 --- /dev/null +++ b/src/test/run-make/rustdoc-where/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: verify.sh foo.rs + $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs + cp verify.sh $(TMPDIR) + $(call RUN,verify.sh) $(TMPDIR) diff --git a/src/test/run-make/rustdoc-where/foo.rs b/src/test/run-make/rustdoc-where/foo.rs new file mode 100644 index 00000000000..7e6df7f011a --- /dev/null +++ b/src/test/run-make/rustdoc-where/foo.rs @@ -0,0 +1,26 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait MyTrait {} + +pub struct Alpha<A> where A: MyTrait; +pub trait Bravo<B> where B: MyTrait {} +pub fn charlie<C>() where C: MyTrait {} + +pub struct Delta<D>; +impl<D> Delta<D> where D: MyTrait { + pub fn delta() {} +} + +pub struct Echo<E>; +impl<E> MyTrait for Echo<E> where E: MyTrait {} + +pub enum Foxtrot<F> {} +impl<F> MyTrait for Foxtrot<F> where F: MyTrait {} diff --git a/src/test/run-make/rustdoc-where/verify.sh b/src/test/run-make/rustdoc-where/verify.sh new file mode 100755 index 00000000000..5d424da02ad --- /dev/null +++ b/src/test/run-make/rustdoc-where/verify.sh @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +# $1 is the TMPDIR +DOC=$1/doc/foo + +grep "Alpha.*where.*A:.*MyTrait" $DOC/struct.Alpha.html > /dev/null +echo "Alpha" +grep "Bravo.*where.*B:.*MyTrait" $DOC/trait.Bravo.html > /dev/null +echo "Bravo" +grep "charlie.*where.*C:.*MyTrait" $DOC/fn.charlie.html > /dev/null +echo "Charlie" +grep "impl.*Delta.*where.*D:.*MyTrait" $DOC/struct.Delta.html > /dev/null +echo "Delta" +grep "impl.*MyTrait.*for.*Echo.*where.*E:.*MyTrait" $DOC/struct.Echo.html > /dev/null +echo "Echo" +grep "impl.*MyTrait.*for.*Foxtrot.*where.*F:.*MyTrait" $DOC/enum.Foxtrot.html > /dev/null +echo "Foxtrot" + +# check "Implementors" section of MyTrait +grep "impl.*MyTrait.*for.*Echo.*where.*E:.*MyTrait" $DOC/trait.MyTrait.html > /dev/null +grep "impl.*MyTrait.*for.*Foxtrot.*where.*F:.*MyTrait" $DOC/trait.MyTrait.html > /dev/null +echo "Implementors OK" |
