Merge remote-tracking branch 'rust-lang/master'
Conflicts: mk/tests.mk src/liballoc/arc.rs src/liballoc/boxed.rs src/liballoc/rc.rs src/libcollections/bit.rs src/libcollections/btree/map.rs src/libcollections/btree/set.rs src/libcollections/dlist.rs src/libcollections/ring_buf.rs src/libcollections/slice.rs src/libcollections/str.rs src/libcollections/string.rs src/libcollections/vec.rs src/libcollections/vec_map.rs src/libcore/any.rs src/libcore/array.rs src/libcore/borrow.rs src/libcore/error.rs src/libcore/fmt/mod.rs src/libcore/iter.rs src/libcore/marker.rs src/libcore/ops.rs src/libcore/result.rs src/libcore/slice.rs src/libcore/str/mod.rs src/libregex/lib.rs src/libregex/re.rs src/librustc/lint/builtin.rs src/libstd/collections/hash/map.rs src/libstd/collections/hash/set.rs src/libstd/sync/mpsc/mod.rs src/libstd/sync/mutex.rs src/libstd/sync/poison.rs src/libstd/sync/rwlock.rs src/libsyntax/feature_gate.rs src/libsyntax/test.rs
This commit is contained in:
commit
63fcbcf3ce
433 changed files with 7348 additions and 12011 deletions
|
|
@ -147,14 +147,22 @@ pub fn record_extern_fqn(cx: &DocContext, did: ast::DefId, kind: clean::TypeKind
|
|||
|
||||
pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
|
||||
did: ast::DefId) -> clean::Trait {
|
||||
use clean::TraitMethod;
|
||||
|
||||
let def = ty::lookup_trait_def(tcx, did);
|
||||
let trait_items = ty::trait_items(tcx, did).clean(cx);
|
||||
let provided = ty::provided_trait_methods(tcx, did);
|
||||
let items = trait_items.into_iter().map(|trait_item| {
|
||||
if provided.iter().any(|a| a.def_id == trait_item.def_id) {
|
||||
clean::ProvidedMethod(trait_item)
|
||||
} else {
|
||||
clean::RequiredMethod(trait_item)
|
||||
match trait_item.inner {
|
||||
clean::TyMethodItem(_) => {
|
||||
if provided.iter().any(|a| a.def_id == trait_item.def_id) {
|
||||
TraitMethod::ProvidedMethod(trait_item)
|
||||
} else {
|
||||
TraitMethod::RequiredMethod(trait_item)
|
||||
}
|
||||
},
|
||||
clean::AssociatedTypeItem(_) => TraitMethod::TypeTraitItem(trait_item),
|
||||
_ => unreachable!()
|
||||
}
|
||||
});
|
||||
let trait_def = ty::lookup_trait_def(tcx, did);
|
||||
|
|
@ -311,12 +319,25 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
|
|||
};
|
||||
Some(item)
|
||||
}
|
||||
ty::TypeTraitItem(_) => {
|
||||
// FIXME(pcwalton): Implement.
|
||||
None
|
||||
ty::TypeTraitItem(ref assoc_ty) => {
|
||||
let did = assoc_ty.def_id;
|
||||
let type_scheme = ty::lookup_item_type(tcx, did);
|
||||
// Not sure the choice of ParamSpace actually matters here, because an
|
||||
// associated type won't have generics on the LHS
|
||||
let typedef = (type_scheme, subst::ParamSpace::TypeSpace).clean(cx);
|
||||
Some(clean::Item {
|
||||
name: Some(assoc_ty.name.clean(cx)),
|
||||
inner: clean::TypedefItem(typedef),
|
||||
source: clean::Span::empty(),
|
||||
attrs: vec![],
|
||||
visibility: None,
|
||||
stability: stability::lookup(tcx, did).clean(cx),
|
||||
def_id: did
|
||||
})
|
||||
}
|
||||
}
|
||||
}).collect();
|
||||
let polarity = csearch::get_impl_polarity(tcx, did);
|
||||
return Some(clean::Item {
|
||||
inner: clean::ImplItem(clean::Impl {
|
||||
derived: clean::detect_derived(attrs.as_slice()),
|
||||
|
|
@ -329,6 +350,7 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
|
|||
for_: ty.ty.clean(cx),
|
||||
generics: (&ty.generics, subst::TypeSpace).clean(cx),
|
||||
items: trait_items,
|
||||
polarity: polarity.map(|p| { p.clean(cx) }),
|
||||
}),
|
||||
source: clean::Span::empty(),
|
||||
name: None,
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ pub use self::TypeKind::*;
|
|||
pub use self::StructField::*;
|
||||
pub use self::VariantKind::*;
|
||||
pub use self::Mutability::*;
|
||||
pub use self::ViewItemInner::*;
|
||||
pub use self::ViewPath::*;
|
||||
pub use self::Import::*;
|
||||
pub use self::ItemEnum::*;
|
||||
pub use self::Attribute::*;
|
||||
pub use self::TyParamBound::*;
|
||||
|
|
@ -46,7 +45,6 @@ use rustc::middle::def;
|
|||
use rustc::middle::subst::{self, ParamSpace, VecPerParamSpace};
|
||||
use rustc::middle::ty;
|
||||
use rustc::middle::stability;
|
||||
use rustc::session::config;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::u32;
|
||||
|
|
@ -117,7 +115,7 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for syntax::owned_slice::OwnedSlice<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Crate {
|
||||
pub name: String,
|
||||
pub src: FsPath,
|
||||
|
|
@ -128,6 +126,8 @@ pub struct Crate {
|
|||
|
||||
impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
||||
fn clean(&self, cx: &DocContext) -> Crate {
|
||||
use rustc::session::config::Input;
|
||||
|
||||
let mut externs = Vec::new();
|
||||
cx.sess().cstore.iter_crate_data(|n, meta| {
|
||||
externs.push((n, meta.clean(cx)));
|
||||
|
|
@ -135,8 +135,8 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
|||
externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
|
||||
|
||||
// Figure out the name of this crate
|
||||
let input = config::Input::File(cx.src.clone());
|
||||
let name = link::find_crate_name(None, self.attrs.as_slice(), &input);
|
||||
let input = &cx.input;
|
||||
let name = link::find_crate_name(None, self.attrs.as_slice(), input);
|
||||
|
||||
// Clean the crate, translating the entire libsyntax AST to one that is
|
||||
// understood by rustdoc.
|
||||
|
|
@ -189,9 +189,14 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
|||
m.items.extend(tmp.into_iter());
|
||||
}
|
||||
|
||||
let src = match cx.input {
|
||||
Input::File(ref path) => path.clone(),
|
||||
Input::Str(_) => FsPath::new("") // FIXME: this is wrong
|
||||
};
|
||||
|
||||
Crate {
|
||||
name: name.to_string(),
|
||||
src: cx.src.clone(),
|
||||
src: src,
|
||||
module: Some(module),
|
||||
externs: externs,
|
||||
primitives: primitives,
|
||||
|
|
@ -199,7 +204,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct ExternalCrate {
|
||||
pub name: String,
|
||||
pub attrs: Vec<Attribute>,
|
||||
|
|
@ -232,7 +237,7 @@ impl Clean<ExternalCrate> for cstore::crate_metadata {
|
|||
/// Anything with a source location and set of attributes and, optionally, a
|
||||
/// name. That is, anything that can be documented. This doesn't correspond
|
||||
/// directly to the AST's concept of an item; it's a strict superset.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Item {
|
||||
/// Stringified span
|
||||
pub source: Span,
|
||||
|
|
@ -308,8 +313,10 @@ impl Item {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum ItemEnum {
|
||||
ExternCrateItem(String, Option<String>),
|
||||
ImportItem(Import),
|
||||
StructItem(Struct),
|
||||
EnumItem(Enum),
|
||||
FunctionItem(Function),
|
||||
|
|
@ -319,8 +326,6 @@ pub enum ItemEnum {
|
|||
ConstantItem(Constant),
|
||||
TraitItem(Trait),
|
||||
ImplItem(Impl),
|
||||
/// `use` and `extern crate`
|
||||
ViewItemItem(ViewItem),
|
||||
/// A method signature only. Used for required methods in traits (ie,
|
||||
/// non-default-methods).
|
||||
TyMethodItem(TyMethod),
|
||||
|
|
@ -337,7 +342,7 @@ pub enum ItemEnum {
|
|||
AssociatedTypeItem(TyParam),
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Module {
|
||||
pub items: Vec<Item>,
|
||||
pub is_crate: bool,
|
||||
|
|
@ -350,27 +355,21 @@ impl Clean<Item> for doctree::Module {
|
|||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let mut foreigns = Vec::new();
|
||||
for subforeigns in self.foreigns.clean(cx).into_iter() {
|
||||
for foreign in subforeigns.into_iter() {
|
||||
foreigns.push(foreign)
|
||||
}
|
||||
}
|
||||
let items: Vec<Vec<Item> > = vec!(
|
||||
self.structs.clean(cx),
|
||||
self.enums.clean(cx),
|
||||
self.fns.clean(cx),
|
||||
foreigns,
|
||||
self.mods.clean(cx),
|
||||
self.typedefs.clean(cx),
|
||||
self.statics.clean(cx),
|
||||
self.constants.clean(cx),
|
||||
self.traits.clean(cx),
|
||||
self.impls.clean(cx),
|
||||
self.view_items.clean(cx).into_iter()
|
||||
.flat_map(|s| s.into_iter()).collect(),
|
||||
self.macros.clean(cx),
|
||||
);
|
||||
let items: Vec<Item> =
|
||||
self.extern_crates.iter().map(|x| x.clean(cx))
|
||||
.chain(self.imports.iter().flat_map(|x| x.clean(cx).into_iter()))
|
||||
.chain(self.structs.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.enums.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.fns.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.foreigns.iter().flat_map(|x| x.clean(cx).into_iter()))
|
||||
.chain(self.mods.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.typedefs.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.statics.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.constants.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.traits.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.impls.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.macros.iter().map(|x| x.clean(cx)))
|
||||
.collect();
|
||||
|
||||
// determine if we should display the inner contents or
|
||||
// the outer `mod` item for the source code.
|
||||
|
|
@ -396,9 +395,7 @@ impl Clean<Item> for doctree::Module {
|
|||
def_id: ast_util::local_def(self.id),
|
||||
inner: ModuleItem(Module {
|
||||
is_crate: self.is_crate,
|
||||
items: items.iter()
|
||||
.flat_map(|x| x.iter().map(|x| (*x).clone()))
|
||||
.collect(),
|
||||
items: items
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -941,7 +938,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>, subst::ParamSpace) {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Method {
|
||||
pub generics: Generics,
|
||||
pub self_: SelfTy,
|
||||
|
|
@ -980,7 +977,7 @@ impl Clean<Item> for ast::Method {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct TyMethod {
|
||||
pub unsafety: ast::Unsafety,
|
||||
pub decl: FnDecl,
|
||||
|
|
@ -1018,7 +1015,7 @@ impl Clean<Item> for ast::TypeMethod {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Show)]
|
||||
pub enum SelfTy {
|
||||
SelfStatic,
|
||||
SelfValue,
|
||||
|
|
@ -1039,7 +1036,7 @@ impl Clean<SelfTy> for ast::ExplicitSelf_ {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Function {
|
||||
pub decl: FnDecl,
|
||||
pub generics: Generics,
|
||||
|
|
@ -1158,7 +1155,7 @@ impl Clean<FunctionRetTy> for ast::FunctionRetTy {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Trait {
|
||||
pub unsafety: ast::Unsafety,
|
||||
pub items: Vec<TraitMethod>,
|
||||
|
|
@ -1202,11 +1199,11 @@ impl Clean<PolyTrait> for ast::PolyTraitRef {
|
|||
|
||||
/// An item belonging to a trait, whether a method or associated. Could be named
|
||||
/// TraitItem except that's already taken by an exported enum variant.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum TraitMethod {
|
||||
RequiredMethod(Item),
|
||||
ProvidedMethod(Item),
|
||||
TypeTraitItem(Item),
|
||||
TypeTraitItem(Item), // an associated type
|
||||
}
|
||||
|
||||
impl TraitMethod {
|
||||
|
|
@ -1247,7 +1244,7 @@ impl Clean<TraitMethod> for ast::TraitItem {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum ImplMethod {
|
||||
MethodImplItem(Item),
|
||||
TypeImplItem(Item),
|
||||
|
|
@ -1383,7 +1380,7 @@ pub enum PrimitiveType {
|
|||
PrimitiveTuple,
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Show)]
|
||||
pub enum TypeKind {
|
||||
TypeEnum,
|
||||
TypeFunction,
|
||||
|
|
@ -1626,7 +1623,7 @@ impl Clean<Type> for ast::QPath {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum StructField {
|
||||
HiddenStructField, // inserted later by strip passes
|
||||
TypedStructField(Type),
|
||||
|
|
@ -1685,7 +1682,7 @@ impl Clean<Option<Visibility>> for ast::Visibility {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Struct {
|
||||
pub struct_type: doctree::StructType,
|
||||
pub generics: Generics,
|
||||
|
|
@ -1715,7 +1712,7 @@ impl Clean<Item> for doctree::Struct {
|
|||
/// This is a more limited form of the standard Struct, different in that
|
||||
/// it lacks the things most items have (name, id, parameterization). Found
|
||||
/// only as a variant in an enum.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct VariantStruct {
|
||||
pub struct_type: doctree::StructType,
|
||||
pub fields: Vec<Item>,
|
||||
|
|
@ -1732,7 +1729,7 @@ impl Clean<VariantStruct> for syntax::ast::StructDef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Enum {
|
||||
pub variants: Vec<Item>,
|
||||
pub generics: Generics,
|
||||
|
|
@ -1757,7 +1754,7 @@ impl Clean<Item> for doctree::Enum {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Variant {
|
||||
pub kind: VariantKind,
|
||||
}
|
||||
|
|
@ -1825,7 +1822,7 @@ impl<'tcx> Clean<Item> for ty::VariantInfo<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum VariantKind {
|
||||
CLikeVariant,
|
||||
TupleVariant(Vec<Type>),
|
||||
|
|
@ -1875,9 +1872,9 @@ impl Clean<Span> for syntax::codemap::Span {
|
|||
Span {
|
||||
filename: filename.to_string(),
|
||||
loline: lo.line,
|
||||
locol: lo.col.to_uint(),
|
||||
locol: lo.col.to_usize(),
|
||||
hiline: hi.line,
|
||||
hicol: hi.col.to_uint(),
|
||||
hicol: hi.col.to_usize(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1972,7 +1969,7 @@ impl Clean<String> for ast::Name {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Typedef {
|
||||
pub type_: Type,
|
||||
pub generics: Generics,
|
||||
|
|
@ -2085,13 +2082,29 @@ impl Clean<Mutability> for ast::Mutability {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Copy, Show)]
|
||||
pub enum ImplPolarity {
|
||||
Positive,
|
||||
Negative,
|
||||
}
|
||||
|
||||
impl Clean<ImplPolarity> for ast::ImplPolarity {
|
||||
fn clean(&self, _: &DocContext) -> ImplPolarity {
|
||||
match self {
|
||||
&ast::ImplPolarity::Positive => ImplPolarity::Positive,
|
||||
&ast::ImplPolarity::Negative => ImplPolarity::Negative,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Impl {
|
||||
pub generics: Generics,
|
||||
pub trait_: Option<Type>,
|
||||
pub for_: Type,
|
||||
pub items: Vec<Item>,
|
||||
pub derived: bool,
|
||||
pub polarity: Option<ImplPolarity>,
|
||||
}
|
||||
|
||||
fn detect_derived<M: AttrMetaMethods>(attrs: &[M]) -> bool {
|
||||
|
|
@ -2118,17 +2131,27 @@ impl Clean<Item> for doctree::Impl {
|
|||
}
|
||||
}).collect(),
|
||||
derived: detect_derived(self.attrs.as_slice()),
|
||||
polarity: Some(self.polarity.clean(cx)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
pub struct ViewItem {
|
||||
pub inner: ViewItemInner,
|
||||
impl Clean<Item> for doctree::ExternCrate {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
Item {
|
||||
name: None,
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.whence.clean(cx),
|
||||
def_id: ast_util::local_def(0),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Vec<Item>> for ast::ViewItem {
|
||||
impl Clean<Vec<Item>> for doctree::Import {
|
||||
fn clean(&self, cx: &DocContext) -> Vec<Item> {
|
||||
// We consider inlining the documentation of `pub use` statements, but we
|
||||
// forcefully don't inline if this is not public or if the
|
||||
|
|
@ -2139,81 +2162,63 @@ impl Clean<Vec<Item>> for ast::ViewItem {
|
|||
None => false,
|
||||
}
|
||||
});
|
||||
let convert = |&: node: &ast::ViewItem_| {
|
||||
Item {
|
||||
name: None,
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.span.clean(cx),
|
||||
def_id: ast_util::local_def(0),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
inner: ViewItemItem(ViewItem { inner: node.clean(cx) }),
|
||||
let (mut ret, inner) = match self.node {
|
||||
ast::ViewPathGlob(ref p) => {
|
||||
(vec![], GlobImport(resolve_use_source(cx, p.clean(cx), self.id)))
|
||||
}
|
||||
};
|
||||
let mut ret = Vec::new();
|
||||
match self.node {
|
||||
ast::ViewItemUse(ref path) if !denied => {
|
||||
match path.node {
|
||||
ast::ViewPathGlob(..) => ret.push(convert(&self.node)),
|
||||
ast::ViewPathList(ref a, ref list, ref b) => {
|
||||
// Attempt to inline all reexported items, but be sure
|
||||
// to keep any non-inlineable reexports so they can be
|
||||
// listed in the documentation.
|
||||
let remaining = list.iter().filter(|path| {
|
||||
match inline::try_inline(cx, path.node.id(), None) {
|
||||
Some(items) => {
|
||||
ret.extend(items.into_iter()); false
|
||||
}
|
||||
None => true,
|
||||
ast::ViewPathList(ref p, ref list) => {
|
||||
// Attempt to inline all reexported items, but be sure
|
||||
// to keep any non-inlineable reexports so they can be
|
||||
// listed in the documentation.
|
||||
let mut ret = vec![];
|
||||
let remaining = if !denied {
|
||||
let mut remaining = vec![];
|
||||
for path in list.iter() {
|
||||
match inline::try_inline(cx, path.node.id(), None) {
|
||||
Some(items) => {
|
||||
ret.extend(items.into_iter());
|
||||
}
|
||||
None => {
|
||||
remaining.push(path.clean(cx));
|
||||
}
|
||||
}).map(|a| a.clone()).collect::<Vec<ast::PathListItem>>();
|
||||
if remaining.len() > 0 {
|
||||
let path = ast::ViewPathList(a.clone(),
|
||||
remaining,
|
||||
b.clone());
|
||||
let path = syntax::codemap::dummy_spanned(path);
|
||||
ret.push(convert(&ast::ViewItemUse(P(path))));
|
||||
}
|
||||
}
|
||||
ast::ViewPathSimple(ident, _, id) => {
|
||||
match inline::try_inline(cx, id, Some(ident)) {
|
||||
Some(items) => ret.extend(items.into_iter()),
|
||||
None => ret.push(convert(&self.node)),
|
||||
}
|
||||
remaining
|
||||
} else {
|
||||
list.clean(cx)
|
||||
};
|
||||
if remaining.is_empty() {
|
||||
return ret;
|
||||
}
|
||||
(ret, ImportList(resolve_use_source(cx, p.clean(cx), self.id),
|
||||
remaining))
|
||||
}
|
||||
ast::ViewPathSimple(i, ref p) => {
|
||||
if !denied {
|
||||
match inline::try_inline(cx, self.id, Some(i)) {
|
||||
Some(items) => return items,
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
(vec![], SimpleImport(i.clean(cx),
|
||||
resolve_use_source(cx, p.clean(cx), self.id)))
|
||||
}
|
||||
ref n => ret.push(convert(n)),
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
ret.push(Item {
|
||||
name: None,
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.whence.clean(cx),
|
||||
def_id: ast_util::local_def(0),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
inner: ImportItem(inner)
|
||||
});
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
pub enum ViewItemInner {
|
||||
ExternCrate(String, Option<String>, ast::NodeId),
|
||||
Import(ViewPath)
|
||||
}
|
||||
|
||||
impl Clean<ViewItemInner> for ast::ViewItem_ {
|
||||
fn clean(&self, cx: &DocContext) -> ViewItemInner {
|
||||
match self {
|
||||
&ast::ViewItemExternCrate(ref i, ref p, ref id) => {
|
||||
let string = match *p {
|
||||
None => None,
|
||||
Some((ref x, _)) => Some(x.get().to_string()),
|
||||
};
|
||||
ExternCrate(i.clean(cx), string, *id)
|
||||
}
|
||||
&ast::ViewItemUse(ref vp) => {
|
||||
Import(vp.clean(cx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
pub enum ViewPath {
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum Import {
|
||||
// use source as str;
|
||||
SimpleImport(String, ImportSource),
|
||||
// use source::*;
|
||||
|
|
@ -2222,28 +2227,13 @@ pub enum ViewPath {
|
|||
ImportList(ImportSource, Vec<ViewListIdent>),
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct ImportSource {
|
||||
pub path: Path,
|
||||
pub did: Option<ast::DefId>,
|
||||
}
|
||||
|
||||
impl Clean<ViewPath> for ast::ViewPath {
|
||||
fn clean(&self, cx: &DocContext) -> ViewPath {
|
||||
match self.node {
|
||||
ast::ViewPathSimple(ref i, ref p, id) =>
|
||||
SimpleImport(i.clean(cx), resolve_use_source(cx, p.clean(cx), id)),
|
||||
ast::ViewPathGlob(ref p, id) =>
|
||||
GlobImport(resolve_use_source(cx, p.clean(cx), id)),
|
||||
ast::ViewPathList(ref p, ref pl, id) => {
|
||||
ImportList(resolve_use_source(cx, p.clean(cx), id),
|
||||
pl.clean(cx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct ViewListIdent {
|
||||
pub name: String,
|
||||
pub source: Option<ast::DefId>,
|
||||
|
|
@ -2462,7 +2452,7 @@ fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<ast::DefId> {
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Macro {
|
||||
pub source: String,
|
||||
}
|
||||
|
|
@ -2483,7 +2473,7 @@ impl Clean<Item> for doctree::Macro {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct Stability {
|
||||
pub level: attr::StabilityLevel,
|
||||
pub feature: String,
|
||||
|
|
@ -2524,14 +2514,14 @@ impl Clean<Item> for ty::AssociatedType {
|
|||
source: DUMMY_SP.clean(cx),
|
||||
name: Some(self.name.clean(cx)),
|
||||
attrs: Vec::new(),
|
||||
// FIXME(#18048): this is wrong, but cross-crate associated types are broken
|
||||
// anyway, for the time being.
|
||||
inner: AssociatedTypeItem(TyParam {
|
||||
name: self.name.clean(cx),
|
||||
did: ast::DefId {
|
||||
krate: 0,
|
||||
node: ast::DUMMY_NODE_ID
|
||||
},
|
||||
// FIXME(#20727): bounds are missing and need to be filled in from the
|
||||
// predicates on the trait itself
|
||||
bounds: vec![],
|
||||
default: None,
|
||||
}),
|
||||
|
|
@ -2563,6 +2553,16 @@ impl Clean<Item> for ast::Typedef {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ParamSpace) {
|
||||
fn clean(&self, cx: &DocContext) -> Typedef {
|
||||
let (ref ty_scheme, ps) = *self;
|
||||
Typedef {
|
||||
type_: ty_scheme.ty.clean(cx),
|
||||
generics: (&ty_scheme.generics, ps).clean(cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lang_struct(cx: &DocContext, did: Option<ast::DefId>,
|
||||
t: ty::Ty, name: &str,
|
||||
fallback: fn(Box<Type>) -> Type) -> Type {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ pub use self::MaybeTyped::*;
|
|||
use rustc_driver::driver;
|
||||
use rustc::session::{self, config};
|
||||
use rustc::session::config::UnstableFeatures;
|
||||
use rustc::session::search_paths::SearchPaths;
|
||||
use rustc::middle::{privacy, ty};
|
||||
use rustc::lint;
|
||||
use rustc_trans::back::link;
|
||||
|
|
@ -27,6 +26,9 @@ use visit_ast::RustdocVisitor;
|
|||
use clean;
|
||||
use clean::Clean;
|
||||
|
||||
pub use rustc::session::config::Input;
|
||||
pub use rustc::session::search_paths::SearchPaths;
|
||||
|
||||
/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
|
||||
pub enum MaybeTyped<'tcx> {
|
||||
Typed(ty::ctxt<'tcx>),
|
||||
|
|
@ -39,7 +41,7 @@ pub type ExternalPaths = RefCell<Option<HashMap<ast::DefId,
|
|||
pub struct DocContext<'tcx> {
|
||||
pub krate: &'tcx ast::Crate,
|
||||
pub maybe_typed: MaybeTyped<'tcx>,
|
||||
pub src: Path,
|
||||
pub input: Input,
|
||||
pub external_paths: ExternalPaths,
|
||||
pub external_traits: RefCell<Option<HashMap<ast::DefId, clean::Trait>>>,
|
||||
pub external_typarams: RefCell<Option<HashMap<ast::DefId, String>>>,
|
||||
|
|
@ -80,12 +82,15 @@ pub struct CrateAnalysis {
|
|||
pub type Externs = HashMap<String, Vec<String>>;
|
||||
|
||||
pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
|
||||
cpath: &Path, triple: Option<String>)
|
||||
input: Input, triple: Option<String>)
|
||||
-> (clean::Crate, CrateAnalysis) {
|
||||
|
||||
// Parse, resolve, and typecheck the given crate.
|
||||
|
||||
let input = config::Input::File(cpath.clone());
|
||||
let cpath = match input {
|
||||
Input::File(ref p) => Some(p.clone()),
|
||||
_ => None
|
||||
};
|
||||
|
||||
let warning_lint = lint::builtin::WARNINGS.name_lower();
|
||||
|
||||
|
|
@ -107,8 +112,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
|
|||
let span_diagnostic_handler =
|
||||
diagnostic::mk_span_handler(diagnostic_handler, codemap);
|
||||
|
||||
let sess = session::build_session_(sessopts,
|
||||
Some(cpath.clone()),
|
||||
let sess = session::build_session_(sessopts, cpath,
|
||||
span_diagnostic_handler);
|
||||
|
||||
let cfg = config::build_configuration(&sess);
|
||||
|
|
@ -136,7 +140,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
|
|||
let ctxt = DocContext {
|
||||
krate: ty_cx.map.krate(),
|
||||
maybe_typed: Typed(ty_cx),
|
||||
src: cpath.clone(),
|
||||
input: input,
|
||||
external_traits: RefCell::new(Some(HashMap::new())),
|
||||
external_typarams: RefCell::new(Some(HashMap::new())),
|
||||
external_paths: RefCell::new(Some(HashMap::new())),
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ pub struct Module {
|
|||
pub attrs: Vec<ast::Attribute>,
|
||||
pub where_outer: Span,
|
||||
pub where_inner: Span,
|
||||
pub extern_crates: Vec<ExternCrate>,
|
||||
pub imports: Vec<Import>,
|
||||
pub structs: Vec<Struct>,
|
||||
pub enums: Vec<Enum>,
|
||||
pub fns: Vec<Function>,
|
||||
|
|
@ -38,7 +40,6 @@ pub struct Module {
|
|||
pub stab: Option<attr::Stability>,
|
||||
pub impls: Vec<Impl>,
|
||||
pub foreigns: Vec<ast::ForeignMod>,
|
||||
pub view_items: Vec<ast::ViewItem>,
|
||||
pub macros: Vec<Macro>,
|
||||
pub is_crate: bool,
|
||||
}
|
||||
|
|
@ -53,6 +54,8 @@ impl Module {
|
|||
where_outer: syntax::codemap::DUMMY_SP,
|
||||
where_inner: syntax::codemap::DUMMY_SP,
|
||||
attrs : Vec::new(),
|
||||
extern_crates: Vec::new(),
|
||||
imports : Vec::new(),
|
||||
structs : Vec::new(),
|
||||
enums : Vec::new(),
|
||||
fns : Vec::new(),
|
||||
|
|
@ -62,7 +65,6 @@ impl Module {
|
|||
constants : Vec::new(),
|
||||
traits : Vec::new(),
|
||||
impls : Vec::new(),
|
||||
view_items : Vec::new(),
|
||||
foreigns : Vec::new(),
|
||||
macros : Vec::new(),
|
||||
is_crate : false,
|
||||
|
|
@ -202,6 +204,22 @@ pub struct Macro {
|
|||
pub stab: Option<attr::Stability>,
|
||||
}
|
||||
|
||||
pub struct ExternCrate {
|
||||
pub name: Ident,
|
||||
pub path: Option<String>,
|
||||
pub vis: ast::Visibility,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub whence: Span,
|
||||
}
|
||||
|
||||
pub struct Import {
|
||||
pub id: NodeId,
|
||||
pub vis: ast::Visibility,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub node: ast::ViewPath_,
|
||||
pub whence: Span,
|
||||
}
|
||||
|
||||
pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType {
|
||||
if sd.ctor_id.is_some() {
|
||||
// We are in a tuple-struct
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use std::fmt;
|
|||
/// string when passed to a format string.
|
||||
pub struct Escape<'a>(pub &'a str);
|
||||
|
||||
impl<'a> fmt::String for Escape<'a> {
|
||||
impl<'a> fmt::Display for Escape<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Because the internet is always right, turns out there's not that many
|
||||
// characters to escape: http://stackoverflow.com/questions/7381974
|
||||
|
|
@ -29,7 +29,7 @@ impl<'a> fmt::String for Escape<'a> {
|
|||
for (i, ch) in s.bytes().enumerate() {
|
||||
match ch as char {
|
||||
'<' | '>' | '&' | '\'' | '"' => {
|
||||
try!(fmt.write_str(pile_o_bits.slice(last, i)));
|
||||
try!(fmt.write_str(&pile_o_bits[last.. i]));
|
||||
let s = match ch as char {
|
||||
'>' => ">",
|
||||
'<' => "<",
|
||||
|
|
@ -46,7 +46,7 @@ impl<'a> fmt::String for Escape<'a> {
|
|||
}
|
||||
|
||||
if last < s.len() {
|
||||
try!(fmt.write_str(pile_o_bits.slice_from(last)));
|
||||
try!(fmt.write_str(&pile_o_bits[last..]));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ impl UnsafetySpace {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: fmt::String> fmt::String for CommaSep<'a, T> {
|
||||
impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, item) in self.0.iter().enumerate() {
|
||||
if i != 0 { try!(write!(f, ", ")); }
|
||||
|
|
@ -76,7 +76,7 @@ impl<'a, T: fmt::String> fmt::String for CommaSep<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for TyParamBounds<'a> {
|
||||
impl<'a> fmt::Display for TyParamBounds<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let &TyParamBounds(bounds) = self;
|
||||
for (i, bound) in bounds.iter().enumerate() {
|
||||
|
|
@ -89,7 +89,7 @@ impl<'a> fmt::String for TyParamBounds<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::Generics {
|
||||
impl fmt::Display for clean::Generics {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) }
|
||||
try!(f.write_str("<"));
|
||||
|
|
@ -126,7 +126,7 @@ impl fmt::String for clean::Generics {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for WhereClause<'a> {
|
||||
impl<'a> fmt::Display for WhereClause<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let &WhereClause(gens) = self;
|
||||
if gens.where_predicates.len() == 0 {
|
||||
|
|
@ -163,14 +163,14 @@ impl<'a> fmt::String for WhereClause<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::Lifetime {
|
||||
impl fmt::Display for clean::Lifetime {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(f.write_str(self.get_ref()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::PolyTrait {
|
||||
impl fmt::Display for clean::PolyTrait {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.lifetimes.len() > 0 {
|
||||
try!(f.write_str("for<"));
|
||||
|
|
@ -186,7 +186,7 @@ impl fmt::String for clean::PolyTrait {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::TyParamBound {
|
||||
impl fmt::Display for clean::TyParamBound {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::RegionBound(ref lt) => {
|
||||
|
|
@ -203,7 +203,7 @@ impl fmt::String for clean::TyParamBound {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::PathParameters {
|
||||
impl fmt::Display for clean::PathParameters {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::PathParameters::AngleBracketed {
|
||||
|
|
@ -257,14 +257,14 @@ impl fmt::String for clean::PathParameters {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::PathSegment {
|
||||
impl fmt::Display for clean::PathSegment {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(f.write_str(self.name.as_slice()));
|
||||
write!(f, "{}", self.params)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::Path {
|
||||
impl fmt::Display for clean::Path {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.global {
|
||||
try!(f.write_str("::"))
|
||||
|
|
@ -358,7 +358,7 @@ fn path<F, G>(w: &mut fmt::Formatter,
|
|||
// This is a documented path, link to it!
|
||||
Some((ref fqp, shortty)) if abs_root.is_some() => {
|
||||
let mut url = String::from_str(abs_root.unwrap().as_slice());
|
||||
let to_link = &fqp[..(fqp.len() - 1)];
|
||||
let to_link = &fqp[..fqp.len() - 1];
|
||||
for component in to_link.iter() {
|
||||
url.push_str(component.as_slice());
|
||||
url.push_str("/");
|
||||
|
|
@ -450,7 +450,7 @@ fn tybounds(w: &mut fmt::Formatter,
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::Type {
|
||||
impl fmt::Display for clean::Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::TyParamBinder(id) => {
|
||||
|
|
@ -539,7 +539,7 @@ impl fmt::String for clean::Type {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::Arguments {
|
||||
impl fmt::Display for clean::Arguments {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, input) in self.values.iter().enumerate() {
|
||||
if i > 0 { try!(write!(f, ", ")); }
|
||||
|
|
@ -552,7 +552,7 @@ impl fmt::String for clean::Arguments {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::FunctionRetTy {
|
||||
impl fmt::Display for clean::FunctionRetTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::Return(clean::Tuple(ref tys)) if tys.is_empty() => Ok(()),
|
||||
|
|
@ -563,13 +563,13 @@ impl fmt::String for clean::FunctionRetTy {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::FnDecl {
|
||||
impl fmt::Display for clean::FnDecl {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for Method<'a> {
|
||||
impl<'a> fmt::Display for Method<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Method(selfty, d) = *self;
|
||||
let mut args = String::new();
|
||||
|
|
@ -599,7 +599,7 @@ impl<'a> fmt::String for Method<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for VisSpace {
|
||||
impl fmt::Display for VisSpace {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.get() {
|
||||
Some(ast::Public) => write!(f, "pub "),
|
||||
|
|
@ -608,7 +608,7 @@ impl fmt::String for VisSpace {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for UnsafetySpace {
|
||||
impl fmt::Display for UnsafetySpace {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.get() {
|
||||
ast::Unsafety::Unsafe => write!(f, "unsafe "),
|
||||
|
|
@ -617,7 +617,7 @@ impl fmt::String for UnsafetySpace {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::ViewPath {
|
||||
impl fmt::Display for clean::Import {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::SimpleImport(ref name, ref src) => {
|
||||
|
|
@ -644,7 +644,7 @@ impl fmt::String for clean::ViewPath {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::ImportSource {
|
||||
impl fmt::Display for clean::ImportSource {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.did {
|
||||
Some(did) => resolved_path(f, did, &self.path, true),
|
||||
|
|
@ -661,7 +661,7 @@ impl fmt::String for clean::ImportSource {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::ViewListIdent {
|
||||
impl fmt::Display for clean::ViewListIdent {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.source {
|
||||
Some(did) => {
|
||||
|
|
@ -683,13 +683,13 @@ impl fmt::String for clean::ViewListIdent {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for clean::TypeBinding {
|
||||
impl fmt::Display for clean::TypeBinding {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}={}", self.name, self.ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::String for MutableSpace {
|
||||
impl fmt::Display for MutableSpace {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
MutableSpace(clean::Immutable) => Ok(()),
|
||||
|
|
@ -698,7 +698,7 @@ impl fmt::String for MutableSpace {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for RawMutableSpace {
|
||||
impl fmt::Display for RawMutableSpace {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
RawMutableSpace(clean::Immutable) => write!(f, "const "),
|
||||
|
|
@ -707,7 +707,7 @@ impl fmt::String for RawMutableSpace {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for Stability<'a> {
|
||||
impl<'a> fmt::Display for Stability<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Stability(stab) = *self;
|
||||
match *stab {
|
||||
|
|
@ -721,7 +721,7 @@ impl<'a> fmt::String for Stability<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for ConciseStability<'a> {
|
||||
impl<'a> fmt::Display for ConciseStability<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let ConciseStability(stab) = *self;
|
||||
match *stab {
|
||||
|
|
@ -738,7 +738,7 @@ impl<'a> fmt::String for ConciseStability<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for ModuleSummary {
|
||||
impl fmt::Display for ModuleSummary {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt_inner<'a>(f: &mut fmt::Formatter,
|
||||
context: &mut Vec<&'a str>,
|
||||
|
|
|
|||
|
|
@ -22,29 +22,31 @@ use clean;
|
|||
#[derive(Copy, PartialEq, Clone)]
|
||||
pub enum ItemType {
|
||||
Module = 0,
|
||||
Struct = 1,
|
||||
Enum = 2,
|
||||
Function = 3,
|
||||
Typedef = 4,
|
||||
Static = 5,
|
||||
Trait = 6,
|
||||
Impl = 7,
|
||||
ViewItem = 8,
|
||||
TyMethod = 9,
|
||||
Method = 10,
|
||||
StructField = 11,
|
||||
Variant = 12,
|
||||
// we used to have ForeignFunction and ForeignStatic. they are retired now.
|
||||
Macro = 15,
|
||||
Primitive = 16,
|
||||
AssociatedType = 17,
|
||||
Constant = 18,
|
||||
ExternCrate = 1,
|
||||
Import = 2,
|
||||
Struct = 3,
|
||||
Enum = 4,
|
||||
Function = 5,
|
||||
Typedef = 6,
|
||||
Static = 7,
|
||||
Trait = 8,
|
||||
Impl = 9,
|
||||
TyMethod = 10,
|
||||
Method = 11,
|
||||
StructField = 12,
|
||||
Variant = 13,
|
||||
Macro = 14,
|
||||
Primitive = 15,
|
||||
AssociatedType = 16,
|
||||
Constant = 17,
|
||||
}
|
||||
|
||||
impl ItemType {
|
||||
pub fn from_item(item: &clean::Item) -> ItemType {
|
||||
match item.inner {
|
||||
clean::ModuleItem(..) => ItemType::Module,
|
||||
clean::ExternCrateItem(..) => ItemType::ExternCrate,
|
||||
clean::ImportItem(..) => ItemType::Import,
|
||||
clean::StructItem(..) => ItemType::Struct,
|
||||
clean::EnumItem(..) => ItemType::Enum,
|
||||
clean::FunctionItem(..) => ItemType::Function,
|
||||
|
|
@ -53,7 +55,6 @@ impl ItemType {
|
|||
clean::ConstantItem(..) => ItemType::Constant,
|
||||
clean::TraitItem(..) => ItemType::Trait,
|
||||
clean::ImplItem(..) => ItemType::Impl,
|
||||
clean::ViewItemItem(..) => ItemType::ViewItem,
|
||||
clean::TyMethodItem(..) => ItemType::TyMethod,
|
||||
clean::MethodItem(..) => ItemType::Method,
|
||||
clean::StructFieldItem(..) => ItemType::StructField,
|
||||
|
|
@ -83,6 +84,8 @@ impl ItemType {
|
|||
pub fn to_static_str(&self) -> &'static str {
|
||||
match *self {
|
||||
ItemType::Module => "mod",
|
||||
ItemType::ExternCrate => "externcrate",
|
||||
ItemType::Import => "import",
|
||||
ItemType::Struct => "struct",
|
||||
ItemType::Enum => "enum",
|
||||
ItemType::Function => "fn",
|
||||
|
|
@ -90,7 +93,6 @@ impl ItemType {
|
|||
ItemType::Static => "static",
|
||||
ItemType::Trait => "trait",
|
||||
ItemType::Impl => "impl",
|
||||
ItemType::ViewItem => "viewitem",
|
||||
ItemType::TyMethod => "tymethod",
|
||||
ItemType::Method => "method",
|
||||
ItemType::StructField => "structfield",
|
||||
|
|
@ -103,7 +105,7 @@ impl ItemType {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::String for ItemType {
|
||||
impl fmt::Display for ItemType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.to_static_str().fmt(f)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ pub struct Page<'a> {
|
|||
pub keywords: &'a str
|
||||
}
|
||||
|
||||
pub fn render<T: fmt::String, S: fmt::String>(
|
||||
pub fn render<T: fmt::Display, S: fmt::Display>(
|
||||
dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
|
||||
-> io::IoResult<()>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -72,16 +72,40 @@ type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
|||
type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
libc::c_int, *mut libc::c_void);
|
||||
|
||||
type linkfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*const hoedown_buffer, *const hoedown_buffer,
|
||||
*mut libc::c_void) -> libc::c_int;
|
||||
|
||||
type normaltextfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*mut libc::c_void);
|
||||
|
||||
#[repr(C)]
|
||||
struct hoedown_renderer {
|
||||
opaque: *mut hoedown_html_renderer_state,
|
||||
opaque: *mut libc::c_void,
|
||||
|
||||
blockcode: Option<blockcodefn>,
|
||||
blockquote: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*mut libc::c_void)>,
|
||||
blockhtml: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*mut libc::c_void)>,
|
||||
header: Option<headerfn>,
|
||||
other: [libc::size_t; 28],
|
||||
|
||||
other_block_level_callbacks: [libc::size_t; 9],
|
||||
|
||||
/* span level callbacks - NULL or return 0 prints the span verbatim */
|
||||
other_span_level_callbacks_1: [libc::size_t; 9],
|
||||
link: Option<linkfn>,
|
||||
other_span_level_callbacks_2: [libc::size_t; 5],
|
||||
// hoedown will add `math` callback here, but we use an old version of it.
|
||||
|
||||
/* low level callbacks - NULL copies input directly into the output */
|
||||
entity: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*mut libc::c_void)>,
|
||||
normal_text: Option<normaltextfn>,
|
||||
|
||||
/* header and footer */
|
||||
doc_header: Option<extern "C" fn(*mut hoedown_buffer, *mut libc::c_void)>,
|
||||
doc_footer: Option<extern "C" fn(*mut hoedown_buffer, *mut libc::c_void)>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -134,6 +158,8 @@ extern {
|
|||
fn hoedown_document_free(md: *mut hoedown_document);
|
||||
|
||||
fn hoedown_buffer_new(unit: libc::size_t) -> *mut hoedown_buffer;
|
||||
fn hoedown_buffer_put(b: *mut hoedown_buffer, c: *const libc::c_char,
|
||||
n: libc::size_t);
|
||||
fn hoedown_buffer_puts(b: *mut hoedown_buffer, c: *const libc::c_char);
|
||||
fn hoedown_buffer_free(b: *mut hoedown_buffer);
|
||||
|
||||
|
|
@ -146,7 +172,7 @@ extern {
|
|||
fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
|
||||
let trimmed = s.trim();
|
||||
if trimmed.starts_with("# ") {
|
||||
Some(trimmed.slice_from(2))
|
||||
Some(&trimmed[2..])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -279,7 +305,8 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
|
|||
dfltblk: (*renderer).blockcode.unwrap(),
|
||||
toc_builder: if print_toc {Some(TocBuilder::new())} else {None}
|
||||
};
|
||||
(*(*renderer).opaque).opaque = &mut opaque as *mut _ as *mut libc::c_void;
|
||||
(*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
|
||||
= &mut opaque as *mut _ as *mut libc::c_void;
|
||||
(*renderer).blockcode = Some(block as blockcodefn);
|
||||
(*renderer).header = Some(header as headerfn);
|
||||
|
||||
|
|
@ -355,7 +382,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
|
|||
let renderer = hoedown_html_renderer_new(0, 0);
|
||||
(*renderer).blockcode = Some(block as blockcodefn);
|
||||
(*renderer).header = Some(header as headerfn);
|
||||
(*(*renderer).opaque).opaque = tests as *mut _ as *mut libc::c_void;
|
||||
(*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
|
||||
= tests as *mut _ as *mut libc::c_void;
|
||||
|
||||
let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
|
||||
hoedown_document_render(document, ob, doc.as_ptr(),
|
||||
|
|
@ -426,7 +454,7 @@ pub fn reset_headers() {
|
|||
USED_HEADER_MAP.with(|s| s.borrow_mut().clear());
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for Markdown<'a> {
|
||||
impl<'a> fmt::Display for Markdown<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Markdown(md) = *self;
|
||||
// This is actually common enough to special-case
|
||||
|
|
@ -435,16 +463,67 @@ impl<'a> fmt::String for Markdown<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for MarkdownWithToc<'a> {
|
||||
impl<'a> fmt::Display for MarkdownWithToc<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let MarkdownWithToc(md) = *self;
|
||||
render(fmt, md.as_slice(), true)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn plain_summary_line(md: &str) -> String {
|
||||
extern fn link(_ob: *mut hoedown_buffer,
|
||||
_link: *const hoedown_buffer,
|
||||
_title: *const hoedown_buffer,
|
||||
content: *const hoedown_buffer,
|
||||
opaque: *mut libc::c_void) -> libc::c_int
|
||||
{
|
||||
unsafe {
|
||||
if !content.is_null() && (*content).size > 0 {
|
||||
let ob = opaque as *mut hoedown_buffer;
|
||||
hoedown_buffer_put(ob, (*content).data as *const libc::c_char,
|
||||
(*content).size);
|
||||
}
|
||||
}
|
||||
1
|
||||
}
|
||||
|
||||
extern fn normal_text(_ob: *mut hoedown_buffer,
|
||||
text: *const hoedown_buffer,
|
||||
opaque: *mut libc::c_void)
|
||||
{
|
||||
unsafe {
|
||||
let ob = opaque as *mut hoedown_buffer;
|
||||
hoedown_buffer_put(ob, (*text).data as *const libc::c_char,
|
||||
(*text).size);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let ob = hoedown_buffer_new(DEF_OUNIT);
|
||||
let mut plain_renderer: hoedown_renderer = ::std::mem::zeroed();
|
||||
let renderer = &mut plain_renderer as *mut hoedown_renderer;
|
||||
(*renderer).opaque = ob as *mut libc::c_void;
|
||||
(*renderer).link = Some(link as linkfn);
|
||||
(*renderer).normal_text = Some(normal_text as normaltextfn);
|
||||
|
||||
let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
|
||||
hoedown_document_render(document, ob, md.as_ptr(),
|
||||
md.len() as libc::size_t);
|
||||
hoedown_document_free(document);
|
||||
let plain_slice = slice::from_raw_buf(&(*ob).data, (*ob).size as uint);
|
||||
let plain = match str::from_utf8(plain_slice) {
|
||||
Ok(s) => s.to_string(),
|
||||
Err(_) => "".to_string(),
|
||||
};
|
||||
hoedown_buffer_free(ob);
|
||||
plain
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{LangString, Markdown};
|
||||
use super::plain_summary_line;
|
||||
|
||||
#[test]
|
||||
fn test_lang_string_parse() {
|
||||
|
|
@ -478,4 +557,18 @@ mod tests {
|
|||
let markdown = "# title";
|
||||
format!("{}", Markdown(markdown.as_slice()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_plain_summary_line() {
|
||||
fn t(input: &str, expect: &str) {
|
||||
let output = plain_summary_line(input);
|
||||
assert_eq!(output, expect);
|
||||
}
|
||||
|
||||
t("hello [Rust](http://rust-lang.org) :)", "hello Rust :)");
|
||||
t("code `let x = i32;` ...", "code `let x = i32;` ...");
|
||||
t("type `Type<'static>` ...", "type `Type<'static>` ...");
|
||||
t("# top header", "top header");
|
||||
t("## header", "header");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
pub use self::ExternalLocation::*;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering::{self, Less, Greater, Equal};
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::default::Default;
|
||||
use std::fmt;
|
||||
|
|
@ -64,8 +64,13 @@ use html::item_type::ItemType;
|
|||
use html::layout;
|
||||
use html::markdown::Markdown;
|
||||
use html::markdown;
|
||||
use html::escape::Escape;
|
||||
use stability_summary;
|
||||
|
||||
/// A pair of name and its optional document.
|
||||
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct NameDoc(String, Option<String>);
|
||||
|
||||
/// Major driving force in all rustdoc rendering. This contains information
|
||||
/// about where in the tree-like hierarchy rendering is occurring and controls
|
||||
/// how the current page is being rendered.
|
||||
|
|
@ -95,7 +100,7 @@ pub struct Context {
|
|||
/// functions), and the value is the list of containers belonging to this
|
||||
/// header. This map will change depending on the surrounding context of the
|
||||
/// page.
|
||||
pub sidebar: HashMap<String, Vec<String>>,
|
||||
pub sidebar: HashMap<String, Vec<NameDoc>>,
|
||||
/// This flag indicates whether [src] links should be generated or not. If
|
||||
/// the source files are present in the html rendering, then this will be
|
||||
/// `true`.
|
||||
|
|
@ -404,7 +409,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult<String>
|
|||
search_index.push(IndexItem {
|
||||
ty: shortty(item),
|
||||
name: item.name.clone().unwrap(),
|
||||
path: fqp[..(fqp.len() - 1)].connect("::"),
|
||||
path: fqp[..fqp.len() - 1].connect("::"),
|
||||
desc: shorter(item.doc_value()).to_string(),
|
||||
parent: Some(did),
|
||||
});
|
||||
|
|
@ -559,7 +564,7 @@ fn write_shared(cx: &Context,
|
|||
};
|
||||
|
||||
let mut mydst = dst.clone();
|
||||
for part in remote_path[..(remote_path.len() - 1)].iter() {
|
||||
for part in remote_path[..remote_path.len() - 1].iter() {
|
||||
mydst.push(part.as_slice());
|
||||
try!(mkdir(&mydst));
|
||||
}
|
||||
|
|
@ -749,7 +754,7 @@ impl<'a> SourceCollector<'a> {
|
|||
|
||||
// Remove the utf-8 BOM if any
|
||||
let contents = if contents.starts_with("\u{feff}") {
|
||||
contents.slice_from(3)
|
||||
&contents[3..]
|
||||
} else {
|
||||
contents
|
||||
};
|
||||
|
|
@ -842,7 +847,7 @@ impl DocFolder for Cache {
|
|||
clean::StructFieldItem(..) |
|
||||
clean::VariantItem(..) => {
|
||||
((Some(*self.parent_stack.last().unwrap()),
|
||||
Some(&self.stack[..(self.stack.len() - 1)])),
|
||||
Some(&self.stack[..self.stack.len() - 1])),
|
||||
false)
|
||||
}
|
||||
clean::MethodItem(..) => {
|
||||
|
|
@ -853,13 +858,13 @@ impl DocFolder for Cache {
|
|||
let did = *last;
|
||||
let path = match self.paths.get(&did) {
|
||||
Some(&(_, ItemType::Trait)) =>
|
||||
Some(&self.stack[..(self.stack.len() - 1)]),
|
||||
Some(&self.stack[..self.stack.len() - 1]),
|
||||
// The current stack not necessarily has correlation for
|
||||
// where the type was defined. On the other hand,
|
||||
// `paths` always has the right information if present.
|
||||
Some(&(ref fqp, ItemType::Struct)) |
|
||||
Some(&(ref fqp, ItemType::Enum)) =>
|
||||
Some(&fqp[..(fqp.len() - 1)]),
|
||||
Some(&fqp[..fqp.len() - 1]),
|
||||
Some(..) => Some(self.stack.as_slice()),
|
||||
None => None
|
||||
};
|
||||
|
|
@ -1185,7 +1190,7 @@ impl Context {
|
|||
.collect::<String>();
|
||||
match cache().paths.get(&it.def_id) {
|
||||
Some(&(ref names, _)) => {
|
||||
for name in (&names[..(names.len() - 1)]).iter() {
|
||||
for name in (&names[..names.len() - 1]).iter() {
|
||||
url.push_str(name.as_slice());
|
||||
url.push_str("/");
|
||||
}
|
||||
|
|
@ -1245,7 +1250,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<String>> {
|
||||
fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> {
|
||||
let mut map = HashMap::new();
|
||||
for item in m.items.iter() {
|
||||
if self.ignore_private_item(item) { continue }
|
||||
|
|
@ -1262,7 +1267,7 @@ impl Context {
|
|||
let short = short.to_string();
|
||||
let v = map.entry(short).get().unwrap_or_else(
|
||||
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
||||
v.push(myname);
|
||||
v.push(NameDoc(myname, Some(shorter_line(item.doc_value()))));
|
||||
}
|
||||
|
||||
for (_, items) in map.iter_mut() {
|
||||
|
|
@ -1351,7 +1356,7 @@ impl<'a> Item<'a> {
|
|||
}
|
||||
|
||||
|
||||
impl<'a> fmt::String for Item<'a> {
|
||||
impl<'a> fmt::Display for Item<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Write the breadcrumb trail header for the top
|
||||
try!(write!(fmt, "\n<h1 class='fqn'><span class='in-band'>"));
|
||||
|
|
@ -1469,13 +1474,18 @@ fn full_path(cx: &Context, item: &clean::Item) -> String {
|
|||
fn shorter<'a>(s: Option<&'a str>) -> &'a str {
|
||||
match s {
|
||||
Some(s) => match s.find_str("\n\n") {
|
||||
Some(pos) => s.slice_to(pos),
|
||||
Some(pos) => &s[..pos],
|
||||
None => s,
|
||||
},
|
||||
None => ""
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn shorter_line(s: Option<&str>) -> String {
|
||||
shorter(s).replace("\n", " ")
|
||||
}
|
||||
|
||||
fn document(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
|
||||
match item.doc_value() {
|
||||
Some(s) => {
|
||||
|
|
@ -1497,18 +1507,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
// the order of item types in the listing
|
||||
fn reorder(ty: ItemType) -> u8 {
|
||||
match ty {
|
||||
ItemType::ViewItem => 0,
|
||||
ItemType::Primitive => 1,
|
||||
ItemType::Module => 2,
|
||||
ItemType::Macro => 3,
|
||||
ItemType::Struct => 4,
|
||||
ItemType::Enum => 5,
|
||||
ItemType::Constant => 6,
|
||||
ItemType::Static => 7,
|
||||
ItemType::Trait => 8,
|
||||
ItemType::Function => 9,
|
||||
ItemType::Typedef => 10,
|
||||
_ => 11 + ty as u8,
|
||||
ItemType::ExternCrate => 0,
|
||||
ItemType::Import => 1,
|
||||
ItemType::Primitive => 2,
|
||||
ItemType::Module => 3,
|
||||
ItemType::Macro => 4,
|
||||
ItemType::Struct => 5,
|
||||
ItemType::Enum => 6,
|
||||
ItemType::Constant => 7,
|
||||
ItemType::Static => 8,
|
||||
ItemType::Trait => 9,
|
||||
ItemType::Function => 10,
|
||||
ItemType::Typedef => 12,
|
||||
_ => 13 + ty as u8,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1518,25 +1529,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
if ty1 == ty2 {
|
||||
return i1.name.cmp(&i2.name);
|
||||
}
|
||||
|
||||
let tycmp = reorder(ty1).cmp(&reorder(ty2));
|
||||
if let Equal = tycmp {
|
||||
// for reexports, `extern crate` takes precedence.
|
||||
match (&i1.inner, &i2.inner) {
|
||||
(&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => {
|
||||
match (&a.inner, &b.inner) {
|
||||
(&clean::ExternCrate(..), _) => return Less,
|
||||
(_, &clean::ExternCrate(..)) => return Greater,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
(_, _) => {}
|
||||
}
|
||||
|
||||
idx1.cmp(&idx2)
|
||||
} else {
|
||||
tycmp
|
||||
}
|
||||
(reorder(ty1), idx1).cmp(&(reorder(ty2), idx2))
|
||||
}
|
||||
|
||||
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
|
||||
|
|
@ -1547,12 +1540,17 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
let myitem = &items[idx];
|
||||
|
||||
let myty = Some(shortty(myitem));
|
||||
if myty != curty {
|
||||
if curty == Some(ItemType::ExternCrate) && myty == Some(ItemType::Import) {
|
||||
// Put `extern crate` and `use` re-exports in the same section.
|
||||
curty = myty;
|
||||
} else if myty != curty {
|
||||
if curty.is_some() {
|
||||
try!(write!(w, "</table>"));
|
||||
}
|
||||
curty = myty;
|
||||
let (short, name) = match myty.unwrap() {
|
||||
ItemType::ExternCrate |
|
||||
ItemType::Import => ("reexports", "Reexports"),
|
||||
ItemType::Module => ("modules", "Modules"),
|
||||
ItemType::Struct => ("structs", "Structs"),
|
||||
ItemType::Enum => ("enums", "Enums"),
|
||||
|
|
@ -1562,7 +1560,6 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
ItemType::Constant => ("constants", "Constants"),
|
||||
ItemType::Trait => ("traits", "Traits"),
|
||||
ItemType::Impl => ("impls", "Implementations"),
|
||||
ItemType::ViewItem => ("reexports", "Reexports"),
|
||||
ItemType::TyMethod => ("tymethods", "Type Methods"),
|
||||
ItemType::Method => ("methods", "Methods"),
|
||||
ItemType::StructField => ("fields", "Struct Fields"),
|
||||
|
|
@ -1578,28 +1575,25 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
}
|
||||
|
||||
match myitem.inner {
|
||||
clean::ViewItemItem(ref item) => {
|
||||
match item.inner {
|
||||
clean::ExternCrate(ref name, ref src, _) => {
|
||||
match *src {
|
||||
Some(ref src) =>
|
||||
try!(write!(w, "<tr><td><code>extern crate \"{}\" as {}",
|
||||
src.as_slice(),
|
||||
name.as_slice())),
|
||||
None =>
|
||||
try!(write!(w, "<tr><td><code>extern crate {}",
|
||||
name.as_slice())),
|
||||
}
|
||||
try!(write!(w, ";</code></td></tr>"));
|
||||
clean::ExternCrateItem(ref name, ref src) => {
|
||||
match *src {
|
||||
Some(ref src) => {
|
||||
try!(write!(w, "<tr><td><code>{}extern crate \"{}\" as {};",
|
||||
VisSpace(myitem.visibility),
|
||||
src.as_slice(),
|
||||
name.as_slice()))
|
||||
}
|
||||
|
||||
clean::Import(ref import) => {
|
||||
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
|
||||
VisSpace(myitem.visibility),
|
||||
*import));
|
||||
None => {
|
||||
try!(write!(w, "<tr><td><code>{}extern crate {};",
|
||||
VisSpace(myitem.visibility), name.as_slice()))
|
||||
}
|
||||
}
|
||||
try!(write!(w, "</code></td></tr>"));
|
||||
}
|
||||
|
||||
clean::ImportItem(ref import) => {
|
||||
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
|
||||
VisSpace(myitem.visibility), *import));
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
|
@ -1626,7 +1620,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
|
||||
struct Initializer<'a>(&'a str);
|
||||
|
||||
impl<'a> fmt::String for Initializer<'a> {
|
||||
impl<'a> fmt::Display for Initializer<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Initializer(s) = *self;
|
||||
if s.len() == 0 { return Ok(()); }
|
||||
|
|
@ -2085,6 +2079,10 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
|
|||
try!(write!(w, "<h3 class='impl'>{}<code>impl{} ",
|
||||
ConciseStability(&i.stability),
|
||||
i.impl_.generics));
|
||||
match i.impl_.polarity {
|
||||
Some(clean::ImplPolarity::Negative) => try!(write!(w, "!")),
|
||||
_ => {}
|
||||
}
|
||||
match i.impl_.trait_ {
|
||||
Some(ref ty) => try!(write!(w, "{} for ", *ty)),
|
||||
None => {}
|
||||
|
|
@ -2188,7 +2186,7 @@ fn item_typedef(w: &mut fmt::Formatter, it: &clean::Item,
|
|||
document(w, it)
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for Sidebar<'a> {
|
||||
impl<'a> fmt::Display for Sidebar<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let cx = self.cx;
|
||||
let it = self.item;
|
||||
|
|
@ -2213,21 +2211,22 @@ impl<'a> fmt::String for Sidebar<'a> {
|
|||
None => return Ok(())
|
||||
};
|
||||
try!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty));
|
||||
for item in items.iter() {
|
||||
for &NameDoc(ref name, ref doc) in items.iter() {
|
||||
let curty = shortty(cur).to_static_str();
|
||||
let class = if cur.name.as_ref().unwrap() == item &&
|
||||
let class = if cur.name.as_ref().unwrap() == name &&
|
||||
short == curty { "current" } else { "" };
|
||||
try!(write!(w, "<a class='{ty} {class}' href='{href}{path}'>\
|
||||
{name}</a>",
|
||||
try!(write!(w, "<a class='{ty} {class}' href='{href}{path}' \
|
||||
title='{title}'>{name}</a>",
|
||||
ty = short,
|
||||
class = class,
|
||||
href = if curty == "mod" {"../"} else {""},
|
||||
path = if short == "mod" {
|
||||
format!("{}/index.html", item.as_slice())
|
||||
format!("{}/index.html", name.as_slice())
|
||||
} else {
|
||||
format!("{}.{}.html", short, item.as_slice())
|
||||
format!("{}.{}.html", short, name.as_slice())
|
||||
},
|
||||
name = item.as_slice()));
|
||||
title = Escape(doc.as_ref().unwrap().as_slice()),
|
||||
name = name.as_slice()));
|
||||
}
|
||||
try!(write!(w, "</div>"));
|
||||
Ok(())
|
||||
|
|
@ -2243,7 +2242,7 @@ impl<'a> fmt::String for Sidebar<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::String for Source<'a> {
|
||||
impl<'a> fmt::Display for Source<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Source(s) = *self;
|
||||
let lines = s.lines().count();
|
||||
|
|
|
|||
|
|
@ -245,7 +245,6 @@ nav.sub {
|
|||
.content .highlighted.method { background-color: #c6afb3; }
|
||||
.content .highlighted.tymethod { background-color: #c6afb3; }
|
||||
.content .highlighted.type { background-color: #c6afb3; }
|
||||
.content .highlighted.ffi { background-color: #c6afb3; }
|
||||
|
||||
.docblock.short.nowrap {
|
||||
display: block;
|
||||
|
|
@ -365,7 +364,6 @@ p a:hover { text-decoration: underline; }
|
|||
.content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; }
|
||||
.content span.method, .content a.method, .block a.current.method { color: #8c6067; }
|
||||
.content span.tymethod, .content a.tymethod, .block a.current.tymethod { color: #8c6067; }
|
||||
.content span.ffi, .content a.ffi, .block a.current.ffi { color: #8c6067; }
|
||||
.content .fnname { color: #8c6067; }
|
||||
|
||||
.search-input {
|
||||
|
|
|
|||
|
|
@ -555,6 +555,8 @@
|
|||
// This mapping table should match the discriminants of
|
||||
// `rustdoc::html::item_type::ItemType` type in Rust.
|
||||
var itemTypes = ["mod",
|
||||
"externcrate",
|
||||
"import",
|
||||
"struct",
|
||||
"enum",
|
||||
"fn",
|
||||
|
|
@ -562,13 +564,10 @@
|
|||
"static",
|
||||
"trait",
|
||||
"impl",
|
||||
"viewitem",
|
||||
"tymethod",
|
||||
"method",
|
||||
"structfield",
|
||||
"variant",
|
||||
"ffi", // retained for backward compatibility
|
||||
"ffs", // retained for backward compatibility
|
||||
"macro",
|
||||
"primitive",
|
||||
"associatedtype",
|
||||
|
|
@ -669,6 +668,15 @@
|
|||
search();
|
||||
}
|
||||
|
||||
function plainSummaryLine(markdown) {
|
||||
var str = markdown.replace(/\n/g, ' ')
|
||||
str = str.replace(/'/g, "\'")
|
||||
str = str.replace(/^#+? (.+?)/, "$1")
|
||||
str = str.replace(/\[(.*?)\]\(.*?\)/g, "$1")
|
||||
str = str.replace(/\[(.*?)\]\[.*?\]/g, "$1")
|
||||
return str;
|
||||
}
|
||||
|
||||
index = buildIndex(rawSearchIndex);
|
||||
startSearch();
|
||||
|
||||
|
|
@ -689,8 +697,10 @@
|
|||
if (crates[i] == window.currentCrate) {
|
||||
klass += ' current';
|
||||
}
|
||||
var desc = rawSearchIndex[crates[i]].items[0][3];
|
||||
div.append($('<a>', {'href': '../' + crates[i] + '/index.html',
|
||||
'class': klass}).text(crates[i]));
|
||||
'title': plainSummaryLine(desc),
|
||||
'class': klass}).text(crates[i]));
|
||||
}
|
||||
sidebar.append(div);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,13 +176,13 @@ impl TocBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for Toc {
|
||||
impl fmt::Debug for Toc {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::String::fmt(self, f)
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::String for Toc {
|
||||
impl fmt::Display for Toc {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(fmt, "<ul>"));
|
||||
for entry in self.entries.iter() {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#![feature(std_misc)]
|
||||
#![feature(test)]
|
||||
#![feature(unicode)]
|
||||
#![feature(hash)]
|
||||
|
||||
extern crate arena;
|
||||
extern crate getopts;
|
||||
|
|
@ -121,7 +122,7 @@ pub fn main() {
|
|||
let res = std::thread::Builder::new().stack_size(STACK_SIZE).scoped(move || {
|
||||
main_args(std::os::args().as_slice())
|
||||
}).join();
|
||||
std::os::set_exit_status(res.map_err(|_| ()).unwrap());
|
||||
std::os::set_exit_status(res.ok().unwrap());
|
||||
}
|
||||
|
||||
pub fn opts() -> Vec<getopts::OptGroup> {
|
||||
|
|
@ -361,8 +362,10 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
|
|||
info!("starting to run rustc");
|
||||
|
||||
let (mut krate, analysis) = std::thread::Thread::scoped(move |:| {
|
||||
use rustc::session::config::Input;
|
||||
|
||||
let cr = cr;
|
||||
core::run_core(paths, cfgs, externs, &cr, triple)
|
||||
core::run_core(paths, cfgs, externs, Input::File(cr), triple)
|
||||
}).join().map_err(|_| "rustc failed").unwrap();
|
||||
info!("finished with rustc");
|
||||
let mut analysis = Some(analysis);
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
|
|||
for line in s.lines() {
|
||||
if line.starts_with("%") {
|
||||
// remove %<whitespace>
|
||||
metadata.push(line.slice_from(1).trim_left())
|
||||
metadata.push(line[1..].trim_left())
|
||||
} else {
|
||||
let line_start_byte = s.subslice_offset(line);
|
||||
return (metadata, s.slice_from(line_start_byte));
|
||||
return (metadata, &s[line_start_byte..]);
|
||||
}
|
||||
}
|
||||
// if we're here, then all lines were metadata % lines.
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
clean::ViewItemItem(..) => {
|
||||
clean::ExternCrateItem(..) | clean::ImportItem(_) => {
|
||||
if i.visibility != Some(ast::Public) {
|
||||
return None
|
||||
}
|
||||
|
|
@ -357,7 +357,7 @@ pub fn unindent(s: &str) -> String {
|
|||
line.to_string()
|
||||
} else {
|
||||
assert!(line.len() >= min_indent);
|
||||
line.slice_from(min_indent).to_string()
|
||||
line[min_indent..].to_string()
|
||||
}
|
||||
}).collect::<Vec<_>>().as_slice());
|
||||
unindented.connect("\n")
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use syntax::ast::Public;
|
|||
|
||||
use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
|
||||
use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
|
||||
use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem, Stability};
|
||||
use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability};
|
||||
|
||||
use html::render::cache;
|
||||
|
||||
|
|
@ -182,7 +182,8 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
|
|||
}))
|
||||
}
|
||||
// no stability information for the following items:
|
||||
ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None),
|
||||
ExternCrateItem(..) | ImportItem(_) |
|
||||
PrimitiveItem(_) => (Counts::zero(), None),
|
||||
_ => (item_counts, None)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ pub fn run(input: &str,
|
|||
let ctx = core::DocContext {
|
||||
krate: &krate,
|
||||
maybe_typed: core::NotTyped(sess),
|
||||
src: input_path,
|
||||
input: input,
|
||||
external_paths: RefCell::new(Some(HashMap::new())),
|
||||
external_traits: RefCell::new(None),
|
||||
external_typarams: RefCell::new(None),
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ use syntax::ast_map;
|
|||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ptr::P;
|
||||
|
||||
use rustc::middle::stability;
|
||||
|
||||
|
|
@ -142,9 +141,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
m: &ast::Mod,
|
||||
name: Option<ast::Ident>) -> Module {
|
||||
let mut om = Module::new(name);
|
||||
for item in m.view_items.iter() {
|
||||
self.visit_view_item(item, &mut om);
|
||||
}
|
||||
om.where_outer = span;
|
||||
om.where_inner = m.inner;
|
||||
om.attrs = attrs;
|
||||
|
|
@ -157,68 +153,41 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
om
|
||||
}
|
||||
|
||||
pub fn visit_view_item(&mut self, item: &ast::ViewItem, om: &mut Module) {
|
||||
if item.vis != ast::Public {
|
||||
return om.view_items.push(item.clone());
|
||||
}
|
||||
let please_inline = item.attrs.iter().any(|item| {
|
||||
match item.meta_item_list() {
|
||||
Some(list) => {
|
||||
list.iter().any(|i| i.name().get() == "inline")
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
});
|
||||
let item = match item.node {
|
||||
ast::ViewItemUse(ref vpath) => {
|
||||
match self.visit_view_path(&**vpath, om, please_inline) {
|
||||
None => return,
|
||||
Some(path) => {
|
||||
ast::ViewItem {
|
||||
node: ast::ViewItemUse(path),
|
||||
.. item.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ViewItemExternCrate(..) => item.clone()
|
||||
};
|
||||
om.view_items.push(item);
|
||||
}
|
||||
|
||||
fn visit_view_path(&mut self, path: &ast::ViewPath,
|
||||
fn visit_view_path(&mut self, path: ast::ViewPath_,
|
||||
om: &mut Module,
|
||||
please_inline: bool) -> Option<P<ast::ViewPath>> {
|
||||
match path.node {
|
||||
ast::ViewPathSimple(dst, _, id) => {
|
||||
id: ast::NodeId,
|
||||
please_inline: bool) -> Option<ast::ViewPath_> {
|
||||
match path {
|
||||
ast::ViewPathSimple(dst, base) => {
|
||||
if self.resolve_id(id, Some(dst), false, om, please_inline) {
|
||||
return None
|
||||
None
|
||||
} else {
|
||||
Some(ast::ViewPathSimple(dst, base))
|
||||
}
|
||||
}
|
||||
ast::ViewPathList(ref p, ref paths, ref b) => {
|
||||
let mut mine = Vec::new();
|
||||
for path in paths.iter() {
|
||||
if !self.resolve_id(path.node.id(), None, false, om,
|
||||
please_inline) {
|
||||
mine.push(path.clone());
|
||||
}
|
||||
}
|
||||
ast::ViewPathList(p, paths) => {
|
||||
let mine = paths.into_iter().filter(|path| {
|
||||
!self.resolve_id(path.node.id(), None, false, om,
|
||||
please_inline)
|
||||
}).collect::<Vec<ast::PathListItem>>();
|
||||
|
||||
if mine.len() == 0 { return None }
|
||||
return Some(P(::syntax::codemap::Spanned {
|
||||
node: ast::ViewPathList(p.clone(), mine, b.clone()),
|
||||
span: path.span,
|
||||
}))
|
||||
if mine.len() == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(ast::ViewPathList(p, mine))
|
||||
}
|
||||
}
|
||||
|
||||
// these are feature gated anyway
|
||||
ast::ViewPathGlob(_, id) => {
|
||||
ast::ViewPathGlob(base) => {
|
||||
if self.resolve_id(id, None, true, om, please_inline) {
|
||||
return None
|
||||
None
|
||||
} else {
|
||||
Some(ast::ViewPathGlob(base))
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(P(path.clone()))
|
||||
|
||||
}
|
||||
|
||||
fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
|
||||
|
|
@ -242,9 +211,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
if glob {
|
||||
match it.node {
|
||||
ast::ItemMod(ref m) => {
|
||||
for vi in m.view_items.iter() {
|
||||
self.visit_view_item(vi, om);
|
||||
}
|
||||
for i in m.items.iter() {
|
||||
self.visit_item(&**i, None, om);
|
||||
}
|
||||
|
|
@ -268,6 +234,45 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
debug!("Visiting item {:?}", item);
|
||||
let name = renamed.unwrap_or(item.ident);
|
||||
match item.node {
|
||||
ast::ItemExternCrate(ref p) => {
|
||||
let path = match *p {
|
||||
None => None,
|
||||
Some((ref x, _)) => Some(x.get().to_string()),
|
||||
};
|
||||
om.extern_crates.push(ExternCrate {
|
||||
name: name,
|
||||
path: path,
|
||||
vis: item.vis,
|
||||
attrs: item.attrs.clone(),
|
||||
whence: item.span,
|
||||
})
|
||||
}
|
||||
ast::ItemUse(ref vpath) => {
|
||||
let node = vpath.node.clone();
|
||||
let node = if item.vis == ast::Public {
|
||||
let please_inline = item.attrs.iter().any(|item| {
|
||||
match item.meta_item_list() {
|
||||
Some(list) => {
|
||||
list.iter().any(|i| i.name().get() == "inline")
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
});
|
||||
match self.visit_view_path(node, om, item.id, please_inline) {
|
||||
None => return,
|
||||
Some(p) => p
|
||||
}
|
||||
} else {
|
||||
node
|
||||
};
|
||||
om.imports.push(Import {
|
||||
id: item.id,
|
||||
vis: item.vis,
|
||||
attrs: item.attrs.clone(),
|
||||
node: node,
|
||||
whence: item.span,
|
||||
});
|
||||
}
|
||||
ast::ItemMod(ref m) => {
|
||||
om.mods.push(self.visit_mod_contents(item.span,
|
||||
item.attrs.clone(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue