Merge remote-tracking branch 'origin/master' into 0.11.0-release
Conflicts: src/libstd/lib.rs
This commit is contained in:
commit
ff1dd44b40
715 changed files with 10358 additions and 8207 deletions
|
|
@ -18,6 +18,7 @@ use rustc::metadata::csearch;
|
|||
use rustc::metadata::decoder;
|
||||
use rustc::middle::def;
|
||||
use rustc::middle::ty;
|
||||
use rustc::middle::stability;
|
||||
|
||||
use core;
|
||||
use doctree;
|
||||
|
|
@ -102,6 +103,7 @@ fn try_inline_def(cx: &core::DocContext,
|
|||
attrs: load_attrs(tcx, did),
|
||||
inner: inner,
|
||||
visibility: Some(ast::Public),
|
||||
stability: stability::lookup(tcx, did).clean(),
|
||||
def_id: did,
|
||||
});
|
||||
Some(ret)
|
||||
|
|
@ -317,6 +319,7 @@ fn build_impl(cx: &core::DocContext,
|
|||
name: None,
|
||||
attrs: attrs,
|
||||
visibility: Some(ast::Inherited),
|
||||
stability: stability::lookup(tcx, did).clean(),
|
||||
def_id: did,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use rustc::middle::def;
|
|||
use rustc::middle::subst;
|
||||
use rustc::middle::subst::VecPerParamSpace;
|
||||
use rustc::middle::ty;
|
||||
use rustc::middle::stability;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::u32;
|
||||
|
|
@ -44,6 +45,17 @@ pub static SCHEMA_VERSION: &'static str = "0.8.3";
|
|||
|
||||
mod inline;
|
||||
|
||||
// load the current DocContext from TLD
|
||||
fn get_cx() -> Gc<core::DocContext> {
|
||||
*super::ctxtkey.get().unwrap()
|
||||
}
|
||||
|
||||
// extract the stability index for a node from TLD, if possible
|
||||
fn get_stability(def_id: ast::DefId) -> Option<Stability> {
|
||||
get_cx().tcx_opt().and_then(|tcx| stability::lookup(tcx, def_id))
|
||||
.map(|stab| stab.clean())
|
||||
}
|
||||
|
||||
pub trait Clean<T> {
|
||||
fn clean(&self) -> T;
|
||||
}
|
||||
|
|
@ -97,7 +109,7 @@ pub struct Crate {
|
|||
|
||||
impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
|
||||
fn clean(&self) -> Crate {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let cx = get_cx();
|
||||
|
||||
let mut externs = Vec::new();
|
||||
cx.sess().cstore.iter_crate_data(|n, meta| {
|
||||
|
|
@ -158,6 +170,7 @@ impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
|
|||
name: Some(prim.to_url_str().to_string()),
|
||||
attrs: Vec::new(),
|
||||
visibility: None,
|
||||
stability: None,
|
||||
def_id: ast_util::local_def(prim.to_node_id()),
|
||||
inner: PrimitiveItem(prim),
|
||||
};
|
||||
|
|
@ -193,25 +206,18 @@ pub struct ExternalCrate {
|
|||
impl Clean<ExternalCrate> for cstore::crate_metadata {
|
||||
fn clean(&self) -> ExternalCrate {
|
||||
let mut primitives = Vec::new();
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => {
|
||||
csearch::each_top_level_item_of_crate(&tcx.sess.cstore,
|
||||
self.cnum,
|
||||
|def, _, _| {
|
||||
let did = match def {
|
||||
decoder::DlDef(def::DefMod(did)) => did,
|
||||
_ => return
|
||||
};
|
||||
let attrs = inline::load_attrs(tcx, did);
|
||||
match Primitive::find(attrs.as_slice()) {
|
||||
Some(prim) => primitives.push(prim),
|
||||
None => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
core::NotTyped(..) => {}
|
||||
}
|
||||
get_cx().tcx_opt().map(|tcx| {
|
||||
csearch::each_top_level_item_of_crate(&tcx.sess.cstore,
|
||||
self.cnum,
|
||||
|def, _, _| {
|
||||
let did = match def {
|
||||
decoder::DlDef(def::DefMod(did)) => did,
|
||||
_ => return
|
||||
};
|
||||
let attrs = inline::load_attrs(tcx, did);
|
||||
Primitive::find(attrs.as_slice()).map(|prim| primitives.push(prim));
|
||||
})
|
||||
});
|
||||
ExternalCrate {
|
||||
name: self.name.to_string(),
|
||||
attrs: decoder::get_crate_attributes(self.data()).clean(),
|
||||
|
|
@ -233,6 +239,7 @@ pub struct Item {
|
|||
pub inner: ItemEnum,
|
||||
pub visibility: Option<Visibility>,
|
||||
pub def_id: ast::DefId,
|
||||
pub stability: Option<Stability>,
|
||||
}
|
||||
|
||||
impl Item {
|
||||
|
|
@ -380,6 +387,7 @@ impl Clean<Item> for doctree::Module {
|
|||
attrs: self.attrs.clean(),
|
||||
source: where.clean(),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
inner: ModuleItem(Module {
|
||||
is_crate: self.is_crate,
|
||||
|
|
@ -465,9 +473,8 @@ impl Clean<TyParam> for ast::TyParam {
|
|||
|
||||
impl Clean<TyParam> for ty::TypeParameterDef {
|
||||
fn clean(&self) -> TyParam {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
cx.external_typarams.borrow_mut().get_mut_ref().insert(self.def_id,
|
||||
self.ident.clean());
|
||||
get_cx().external_typarams.borrow_mut().get_mut_ref()
|
||||
.insert(self.def_id, self.ident.clean());
|
||||
TyParam {
|
||||
name: self.ident.clean(),
|
||||
did: self.def_id,
|
||||
|
|
@ -515,7 +522,7 @@ fn external_path(name: &str, substs: &subst::Substs) -> Path {
|
|||
|
||||
impl Clean<TyParamBound> for ty::BuiltinBound {
|
||||
fn clean(&self) -> TyParamBound {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let cx = get_cx();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => tcx,
|
||||
core::NotTyped(_) => return RegionBound,
|
||||
|
|
@ -550,7 +557,7 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
|
|||
|
||||
impl Clean<TyParamBound> for ty::TraitRef {
|
||||
fn clean(&self) -> TyParamBound {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let cx = get_cx();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => tcx,
|
||||
core::NotTyped(_) => return RegionBound,
|
||||
|
|
@ -709,8 +716,9 @@ impl Clean<Item> for ast::Method {
|
|||
name: Some(self.ident.clean()),
|
||||
attrs: self.attrs.clean().move_iter().collect(),
|
||||
source: self.span.clean(),
|
||||
def_id: ast_util::local_def(self.id.clone()),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(),
|
||||
stability: get_stability(ast_util::local_def(self.id)),
|
||||
inner: MethodItem(Method {
|
||||
generics: self.generics.clean(),
|
||||
self_: self.explicit_self.node.clean(),
|
||||
|
|
@ -749,6 +757,7 @@ impl Clean<Item> for ast::TypeMethod {
|
|||
source: self.span.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: None,
|
||||
stability: get_stability(ast_util::local_def(self.id)),
|
||||
inner: TyMethodItem(TyMethod {
|
||||
fn_style: self.fn_style.clone(),
|
||||
decl: decl,
|
||||
|
|
@ -792,6 +801,7 @@ impl Clean<Item> for doctree::Function {
|
|||
attrs: self.attrs.clean(),
|
||||
source: self.where.clean(),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
inner: FunctionItem(Function {
|
||||
decl: self.decl.clean(),
|
||||
|
|
@ -854,14 +864,10 @@ impl Clean<FnDecl> for ast::FnDecl {
|
|||
|
||||
impl<'a> Clean<FnDecl> for (ast::DefId, &'a ty::FnSig) {
|
||||
fn clean(&self) -> FnDecl {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => tcx,
|
||||
core::NotTyped(_) => unreachable!(),
|
||||
};
|
||||
let cx = get_cx();
|
||||
let (did, sig) = *self;
|
||||
let mut names = if did.node != 0 {
|
||||
csearch::get_method_arg_names(&tcx.sess.cstore, did).move_iter()
|
||||
csearch::get_method_arg_names(&cx.tcx().sess.cstore, did).move_iter()
|
||||
} else {
|
||||
Vec::new().move_iter()
|
||||
}.peekable();
|
||||
|
|
@ -932,6 +938,7 @@ impl Clean<Item> for doctree::Trait {
|
|||
source: self.where.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
inner: TraitItem(Trait {
|
||||
methods: self.methods.clean(),
|
||||
generics: self.generics.clean(),
|
||||
|
|
@ -985,11 +992,7 @@ impl Clean<TraitMethod> for ast::TraitMethod {
|
|||
|
||||
impl Clean<Item> for ty::Method {
|
||||
fn clean(&self) -> Item {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => tcx,
|
||||
core::NotTyped(_) => unreachable!(),
|
||||
};
|
||||
let cx = get_cx();
|
||||
let (self_, sig) = match self.explicit_self {
|
||||
ast::SelfStatic => (ast::SelfStatic.clean(), self.fty.sig.clone()),
|
||||
s => {
|
||||
|
|
@ -1015,8 +1018,9 @@ impl Clean<Item> for ty::Method {
|
|||
Item {
|
||||
name: Some(self.ident.clean()),
|
||||
visibility: Some(ast::Inherited),
|
||||
stability: get_stability(self.def_id),
|
||||
def_id: self.def_id,
|
||||
attrs: inline::load_attrs(tcx, self.def_id),
|
||||
attrs: inline::load_attrs(cx.tcx(), self.def_id),
|
||||
source: Span::empty(),
|
||||
inner: TyMethodItem(TyMethod {
|
||||
fn_style: self.fty.fn_style,
|
||||
|
|
@ -1261,12 +1265,7 @@ impl Clean<Type> for ty::t {
|
|||
ty::ty_struct(did, ref substs) |
|
||||
ty::ty_enum(did, ref substs) |
|
||||
ty::ty_trait(box ty::TyTrait { def_id: did, ref substs, .. }) => {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tycx) => tycx,
|
||||
core::NotTyped(_) => unreachable!(),
|
||||
};
|
||||
let fqn = csearch::get_item_path(tcx, did);
|
||||
let fqn = csearch::get_item_path(get_cx().tcx(), did);
|
||||
let fqn: Vec<String> = fqn.move_iter().map(|i| {
|
||||
i.to_str()
|
||||
}).collect();
|
||||
|
|
@ -1277,8 +1276,8 @@ impl Clean<Type> for ty::t {
|
|||
};
|
||||
let path = external_path(fqn.last().unwrap().to_str().as_slice(),
|
||||
substs);
|
||||
cx.external_paths.borrow_mut().get_mut_ref().insert(did,
|
||||
(fqn, kind));
|
||||
get_cx().external_paths.borrow_mut().get_mut_ref()
|
||||
.insert(did, (fqn, kind));
|
||||
ResolvedPath {
|
||||
path: path,
|
||||
typarams: None,
|
||||
|
|
@ -1318,6 +1317,7 @@ impl Clean<Item> for ast::StructField {
|
|||
attrs: self.node.attrs.clean().move_iter().collect(),
|
||||
source: self.span.clean(),
|
||||
visibility: Some(vis),
|
||||
stability: get_stability(ast_util::local_def(self.node.id)),
|
||||
def_id: ast_util::local_def(self.node.id),
|
||||
inner: StructFieldItem(TypedStructField(self.node.ty.clean())),
|
||||
}
|
||||
|
|
@ -1332,17 +1332,14 @@ impl Clean<Item> for ty::field_ty {
|
|||
} else {
|
||||
Some(self.name)
|
||||
};
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tycx) => tycx,
|
||||
core::NotTyped(_) => unreachable!(),
|
||||
};
|
||||
let ty = ty::lookup_item_type(tcx, self.id);
|
||||
let cx = get_cx();
|
||||
let ty = ty::lookup_item_type(cx.tcx(), self.id);
|
||||
Item {
|
||||
name: name.clean(),
|
||||
attrs: inline::load_attrs(tcx, self.id),
|
||||
attrs: inline::load_attrs(cx.tcx(), self.id),
|
||||
source: Span::empty(),
|
||||
visibility: Some(self.vis),
|
||||
stability: get_stability(self.id),
|
||||
def_id: self.id,
|
||||
inner: StructFieldItem(TypedStructField(ty.ty.clean())),
|
||||
}
|
||||
|
|
@ -1373,6 +1370,7 @@ impl Clean<Item> for doctree::Struct {
|
|||
source: self.where.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
inner: StructItem(Struct {
|
||||
struct_type: self.struct_type,
|
||||
generics: self.generics.clean(),
|
||||
|
|
@ -1418,6 +1416,7 @@ impl Clean<Item> for doctree::Enum {
|
|||
source: self.where.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
inner: EnumItem(Enum {
|
||||
variants: self.variants.clean(),
|
||||
generics: self.generics.clean(),
|
||||
|
|
@ -1439,6 +1438,7 @@ impl Clean<Item> for doctree::Variant {
|
|||
attrs: self.attrs.clean(),
|
||||
source: self.where.clean(),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
inner: VariantItem(Variant {
|
||||
kind: self.kind.clean(),
|
||||
|
|
@ -1450,11 +1450,7 @@ impl Clean<Item> for doctree::Variant {
|
|||
impl Clean<Item> for ty::VariantInfo {
|
||||
fn clean(&self) -> Item {
|
||||
// use syntax::parse::token::special_idents::unnamed_field;
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tycx) => tycx,
|
||||
core::NotTyped(_) => fail!("tcx not present"),
|
||||
};
|
||||
let cx = get_cx();
|
||||
let kind = match self.arg_names.as_ref().map(|s| s.as_slice()) {
|
||||
None | Some([]) if self.args.len() == 0 => CLikeVariant,
|
||||
None | Some([]) => {
|
||||
|
|
@ -1470,6 +1466,7 @@ impl Clean<Item> for ty::VariantInfo {
|
|||
name: Some(name.clean()),
|
||||
attrs: Vec::new(),
|
||||
visibility: Some(ast::Public),
|
||||
stability: get_stability(self.id),
|
||||
// FIXME: this is not accurate, we need an id for
|
||||
// the specific field but we're using the id
|
||||
// for the whole variant. Nothing currently
|
||||
|
|
@ -1485,11 +1482,12 @@ impl Clean<Item> for ty::VariantInfo {
|
|||
};
|
||||
Item {
|
||||
name: Some(self.name.clean()),
|
||||
attrs: inline::load_attrs(tcx, self.id),
|
||||
attrs: inline::load_attrs(cx.tcx(), self.id),
|
||||
source: Span::empty(),
|
||||
visibility: Some(ast::Public),
|
||||
def_id: self.id,
|
||||
inner: VariantItem(Variant { kind: kind }),
|
||||
stability: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1626,6 +1624,7 @@ impl Clean<Item> for doctree::Typedef {
|
|||
source: self.where.clean(),
|
||||
def_id: ast_util::local_def(self.id.clone()),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
inner: TypedefItem(Typedef {
|
||||
type_: self.ty.clean(),
|
||||
generics: self.gen.clean(),
|
||||
|
|
@ -1675,6 +1674,7 @@ impl Clean<Item> for doctree::Static {
|
|||
source: self.where.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
inner: StaticItem(Static {
|
||||
type_: self.type_.clean(),
|
||||
mutability: self.mutability.clean(),
|
||||
|
|
@ -1720,6 +1720,7 @@ impl Clean<Item> for doctree::Impl {
|
|||
source: self.where.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(),
|
||||
stability: self.stab.clean(),
|
||||
inner: ImplItem(Impl {
|
||||
generics: self.generics.clean(),
|
||||
trait_: self.trait_.clean(),
|
||||
|
|
@ -1754,6 +1755,7 @@ impl Clean<Vec<Item>> for ast::ViewItem {
|
|||
source: self.span.clean(),
|
||||
def_id: ast_util::local_def(0),
|
||||
visibility: self.vis.clean(),
|
||||
stability: None,
|
||||
inner: ViewItemItem(ViewItem { inner: node.clean() }),
|
||||
}
|
||||
};
|
||||
|
|
@ -1895,6 +1897,7 @@ impl Clean<Item> for ast::ForeignItem {
|
|||
source: self.span.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(),
|
||||
stability: None,
|
||||
inner: inner,
|
||||
}
|
||||
}
|
||||
|
|
@ -1977,7 +1980,7 @@ fn name_from_pat(p: &ast::Pat) -> String {
|
|||
/// Given a Type, resolve it using the def_map
|
||||
fn resolve_type(path: Path, tpbs: Option<Vec<TyParamBound>>,
|
||||
id: ast::NodeId) -> Type {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let cx = get_cx();
|
||||
let tycx = match cx.maybe_typed {
|
||||
core::Typed(ref tycx) => tycx,
|
||||
// If we're extracting tests, this return value doesn't matter.
|
||||
|
|
@ -2012,7 +2015,7 @@ fn resolve_type(path: Path, tpbs: Option<Vec<TyParamBound>>,
|
|||
def::DefTyParamBinder(i) => return TyParamBinder(i),
|
||||
_ => {}
|
||||
};
|
||||
let did = register_def(&**cx, def);
|
||||
let did = register_def(&*cx, def);
|
||||
ResolvedPath { path: path, typarams: tpbs, did: did }
|
||||
}
|
||||
|
||||
|
|
@ -2051,13 +2054,9 @@ fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource {
|
|||
}
|
||||
|
||||
fn resolve_def(id: ast::NodeId) -> Option<ast::DefId> {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => {
|
||||
tcx.def_map.borrow().find(&id).map(|&def| register_def(&**cx, def))
|
||||
}
|
||||
core::NotTyped(_) => None
|
||||
}
|
||||
get_cx().tcx_opt().and_then(|tcx| {
|
||||
tcx.def_map.borrow().find(&id).map(|&def| register_def(&*get_cx(), def))
|
||||
})
|
||||
}
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable)]
|
||||
|
|
@ -2072,6 +2071,7 @@ impl Clean<Item> for doctree::Macro {
|
|||
attrs: self.attrs.clean(),
|
||||
source: self.where.clean(),
|
||||
visibility: ast::Public.clean(),
|
||||
stability: self.stab.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
inner: MacroItem(Macro {
|
||||
source: self.where.to_src(),
|
||||
|
|
@ -2079,3 +2079,19 @@ impl Clean<Item> for doctree::Macro {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable)]
|
||||
pub struct Stability {
|
||||
pub level: attr::StabilityLevel,
|
||||
pub text: String
|
||||
}
|
||||
|
||||
impl Clean<Stability> for attr::Stability {
|
||||
fn clean(&self) -> Stability {
|
||||
Stability {
|
||||
level: self.level,
|
||||
text: self.text.as_ref().map_or("".to_string(),
|
||||
|interned| interned.get().to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use rustc;
|
||||
use rustc::{driver, middle};
|
||||
use rustc::middle::privacy;
|
||||
use rustc::middle::{privacy, ty};
|
||||
use rustc::lint;
|
||||
|
||||
use syntax::ast;
|
||||
|
|
@ -26,6 +26,7 @@ use visit_ast::RustdocVisitor;
|
|||
use clean;
|
||||
use clean::Clean;
|
||||
|
||||
/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
|
||||
pub enum MaybeTyped {
|
||||
Typed(middle::ty::ctxt),
|
||||
NotTyped(driver::session::Session)
|
||||
|
|
@ -52,6 +53,18 @@ impl DocContext {
|
|||
NotTyped(ref sess) => sess
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tcx_opt<'a>(&'a self) -> Option<&'a ty::ctxt> {
|
||||
match self.maybe_typed {
|
||||
Typed(ref tcx) => Some(tcx),
|
||||
NotTyped(_) => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tcx<'a>(&'a self) -> &'a ty::ctxt {
|
||||
let tcx_opt = self.tcx_opt();
|
||||
tcx_opt.expect("tcx not present")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CrateAnalysis {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
use syntax;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::ast::{Ident, NodeId};
|
||||
|
||||
use std::gc::Gc;
|
||||
|
|
@ -32,6 +33,7 @@ pub struct Module {
|
|||
pub statics: Vec<Static>,
|
||||
pub traits: Vec<Trait>,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub impls: Vec<Impl>,
|
||||
pub foreigns: Vec<ast::ForeignMod>,
|
||||
pub view_items: Vec<ast::ViewItem>,
|
||||
|
|
@ -45,6 +47,7 @@ impl Module {
|
|||
name : name,
|
||||
id: 0,
|
||||
vis: ast::Inherited,
|
||||
stab: None,
|
||||
where_outer: syntax::codemap::DUMMY_SP,
|
||||
where_inner: syntax::codemap::DUMMY_SP,
|
||||
attrs : Vec::new(),
|
||||
|
|
@ -83,6 +86,7 @@ pub enum TypeBound {
|
|||
|
||||
pub struct Struct {
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub id: NodeId,
|
||||
pub struct_type: StructType,
|
||||
pub name: Ident,
|
||||
|
|
@ -94,6 +98,7 @@ pub struct Struct {
|
|||
|
||||
pub struct Enum {
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub variants: Vec<Variant>,
|
||||
pub generics: ast::Generics,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
|
|
@ -108,6 +113,7 @@ pub struct Variant {
|
|||
pub kind: ast::VariantKind,
|
||||
pub id: ast::NodeId,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub where: Span,
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +123,7 @@ pub struct Function {
|
|||
pub id: NodeId,
|
||||
pub name: Ident,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub fn_style: ast::FnStyle,
|
||||
pub where: Span,
|
||||
pub generics: ast::Generics,
|
||||
|
|
@ -130,6 +137,7 @@ pub struct Typedef {
|
|||
pub attrs: Vec<ast::Attribute>,
|
||||
pub where: Span,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
}
|
||||
|
||||
pub struct Static {
|
||||
|
|
@ -139,6 +147,7 @@ pub struct Static {
|
|||
pub name: Ident,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub id: ast::NodeId,
|
||||
pub where: Span,
|
||||
}
|
||||
|
|
@ -152,6 +161,7 @@ pub struct Trait {
|
|||
pub id: ast::NodeId,
|
||||
pub where: Span,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
}
|
||||
|
||||
pub struct Impl {
|
||||
|
|
@ -162,6 +172,7 @@ pub struct Impl {
|
|||
pub attrs: Vec<ast::Attribute>,
|
||||
pub where: Span,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub id: ast::NodeId,
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +181,7 @@ pub struct Macro {
|
|||
pub id: ast::NodeId,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub where: Span,
|
||||
pub stab: Option<attr::Stability>,
|
||||
}
|
||||
|
||||
pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType {
|
||||
|
|
|
|||
70
src/librustdoc/externalfiles.rs
Normal file
70
src/librustdoc/externalfiles.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// 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.
|
||||
|
||||
use std::{io, str};
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct ExternalHtml{
|
||||
pub in_header: String,
|
||||
pub before_content: String,
|
||||
pub after_content: String
|
||||
}
|
||||
|
||||
impl ExternalHtml {
|
||||
pub fn load(in_header: &[String], before_content: &[String], after_content: &[String])
|
||||
-> Option<ExternalHtml> {
|
||||
match (load_external_files(in_header),
|
||||
load_external_files(before_content),
|
||||
load_external_files(after_content)) {
|
||||
(Some(ih), Some(bc), Some(ac)) => Some(ExternalHtml {
|
||||
in_header: ih,
|
||||
before_content: bc,
|
||||
after_content: ac
|
||||
}),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_string(input: &Path) -> io::IoResult<Option<String>> {
|
||||
let mut f = try!(io::File::open(input));
|
||||
let d = try!(f.read_to_end());
|
||||
Ok(str::from_utf8(d.as_slice()).map(|s| s.to_string()))
|
||||
}
|
||||
|
||||
macro_rules! load_or_return {
|
||||
($input: expr, $cant_read: expr, $not_utf8: expr) => {
|
||||
{
|
||||
let input = Path::new($input);
|
||||
match ::externalfiles::load_string(&input) {
|
||||
Err(e) => {
|
||||
let _ = writeln!(&mut io::stderr(),
|
||||
"error reading `{}`: {}", input.display(), e);
|
||||
return $cant_read;
|
||||
}
|
||||
Ok(None) => {
|
||||
let _ = writeln!(&mut io::stderr(),
|
||||
"error reading `{}`: not UTF-8", input.display());
|
||||
return $not_utf8;
|
||||
}
|
||||
Ok(Some(s)) => s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_external_files(names: &[String]) -> Option<String> {
|
||||
let mut out = String::new();
|
||||
for name in names.iter() {
|
||||
out.push_str(load_or_return!(name.as_slice(), None, None).as_slice());
|
||||
out.push_char('\n');
|
||||
}
|
||||
Some(out)
|
||||
}
|
||||
|
|
@ -104,7 +104,7 @@ mod imp {
|
|||
l_sysid: 0,
|
||||
};
|
||||
let ret = unsafe {
|
||||
libc::fcntl(fd, os::F_SETLKW, &flock as *os::flock)
|
||||
libc::fcntl(fd, os::F_SETLKW, &flock as *const os::flock)
|
||||
};
|
||||
if ret == -1 {
|
||||
unsafe { libc::close(fd); }
|
||||
|
|
@ -125,7 +125,7 @@ mod imp {
|
|||
l_sysid: 0,
|
||||
};
|
||||
unsafe {
|
||||
libc::fcntl(self.fd, os::F_SETLK, &flock as *os::flock);
|
||||
libc::fcntl(self.fd, os::F_SETLK, &flock as *const os::flock);
|
||||
libc::close(self.fd);
|
||||
}
|
||||
}
|
||||
|
|
@ -162,7 +162,8 @@ mod imp {
|
|||
|
||||
impl Lock {
|
||||
pub fn new(p: &Path) -> Lock {
|
||||
let p_16 = p.as_str().unwrap().to_utf16().append_one(0);
|
||||
let p_16: Vec<u16> = p.as_str().unwrap().utf16_units().collect();
|
||||
let p_16 = p_16.append_one(0);
|
||||
let handle = unsafe {
|
||||
libc::CreateFileW(p_16.as_ptr(),
|
||||
libc::FILE_GENERIC_READ |
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ pub trait DocFolder {
|
|||
|
||||
/// don't override!
|
||||
fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
|
||||
let Item { attrs, name, source, visibility, def_id, inner } = item;
|
||||
let Item { attrs, name, source, visibility, def_id, inner, stability } = item;
|
||||
let inner = inner;
|
||||
let inner = match inner {
|
||||
StructItem(mut i) => {
|
||||
|
|
@ -83,7 +83,7 @@ pub trait DocFolder {
|
|||
};
|
||||
|
||||
Some(Item { attrs: attrs, name: name, source: source, inner: inner,
|
||||
visibility: visibility, def_id: def_id })
|
||||
visibility: visibility, stability: stability, def_id: def_id })
|
||||
}
|
||||
|
||||
fn fold_mod(&mut self, m: Module) -> Module {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ pub struct FnStyleSpace(pub ast::FnStyle);
|
|||
pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
|
||||
/// Similar to VisSpace, but used for mutability
|
||||
pub struct MutableSpace(pub clean::Mutability);
|
||||
/// Wrapper struct for properly emitting the stability level.
|
||||
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>);
|
||||
|
||||
impl VisSpace {
|
||||
pub fn get(&self) -> Option<ast::Visibility> {
|
||||
|
|
@ -185,7 +189,7 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
|
|||
let mut generics = String::new();
|
||||
let last = path.segments.last().unwrap();
|
||||
if last.lifetimes.len() > 0 || last.types.len() > 0 {
|
||||
let mut counter = 0;
|
||||
let mut counter = 0u;
|
||||
generics.push_str("<");
|
||||
for lifetime in last.lifetimes.iter() {
|
||||
if counter > 0 { generics.push_str(", "); }
|
||||
|
|
@ -596,3 +600,34 @@ impl fmt::Show for MutableSpace {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Stability<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Stability(stab) = *self;
|
||||
match *stab {
|
||||
Some(ref stability) => {
|
||||
write!(f, "<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
|
||||
lvl = stability.level.to_str(),
|
||||
reason = stability.text)
|
||||
}
|
||||
None => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for ConciseStability<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let ConciseStability(stab) = *self;
|
||||
match *stab {
|
||||
Some(ref stability) => {
|
||||
write!(f, "<a class='stability {lvl}' title='{lvl}{colon}{reason}'></a>",
|
||||
lvl = stability.level.to_str(),
|
||||
colon = if stability.text.len() > 0 { ": " } else { "" },
|
||||
reason = stability.text)
|
||||
}
|
||||
None => {
|
||||
write!(f, "<a class='stability Unmarked' title='No stability level'></a>")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,13 @@
|
|||
use std::fmt;
|
||||
use std::io;
|
||||
|
||||
use externalfiles::ExternalHtml;
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct Layout {
|
||||
pub logo: String,
|
||||
pub favicon: String,
|
||||
pub external_html: ExternalHtml,
|
||||
pub krate: String,
|
||||
pub playground_url: String,
|
||||
}
|
||||
|
|
@ -44,6 +47,7 @@ r##"<!DOCTYPE html>
|
|||
<link rel="stylesheet" type="text/css" href="{root_path}main.css">
|
||||
|
||||
{favicon}
|
||||
{in_header}
|
||||
</head>
|
||||
<body>
|
||||
<!--[if lte IE 8]>
|
||||
|
|
@ -53,6 +57,8 @@ r##"<!DOCTYPE html>
|
|||
</div>
|
||||
<![endif]-->
|
||||
|
||||
{before_content}
|
||||
|
||||
<section class="sidebar">
|
||||
{logo}
|
||||
{sidebar}
|
||||
|
|
@ -105,6 +111,8 @@ r##"<!DOCTYPE html>
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{after_content}
|
||||
|
||||
<script>
|
||||
window.rootPath = "{root_path}";
|
||||
window.currentCrate = "{krate}";
|
||||
|
|
@ -133,6 +141,9 @@ r##"<!DOCTYPE html>
|
|||
} else {
|
||||
format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
|
||||
},
|
||||
in_header = layout.external_html.in_header,
|
||||
before_content = layout.external_html.before_content,
|
||||
after_content = layout.external_html.after_content,
|
||||
sidebar = *sidebar,
|
||||
krate = layout.krate,
|
||||
play_url = layout.playground_url,
|
||||
|
|
|
|||
|
|
@ -66,13 +66,13 @@ type hoedown_document = libc::c_void; // this is opaque to us
|
|||
|
||||
struct hoedown_renderer {
|
||||
opaque: *mut hoedown_html_renderer_state,
|
||||
blockcode: Option<extern "C" fn(*mut hoedown_buffer, *hoedown_buffer,
|
||||
*hoedown_buffer, *mut libc::c_void)>,
|
||||
blockquote: Option<extern "C" fn(*mut hoedown_buffer, *hoedown_buffer,
|
||||
blockcode: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*const hoedown_buffer, *mut libc::c_void)>,
|
||||
blockquote: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*mut libc::c_void)>,
|
||||
blockhtml: Option<extern "C" fn(*mut hoedown_buffer, *hoedown_buffer,
|
||||
blockhtml: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*mut libc::c_void)>,
|
||||
header: Option<extern "C" fn(*mut hoedown_buffer, *hoedown_buffer,
|
||||
header: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
libc::c_int, *mut libc::c_void)>,
|
||||
other: [libc::size_t, ..28],
|
||||
}
|
||||
|
|
@ -81,7 +81,8 @@ struct hoedown_html_renderer_state {
|
|||
opaque: *mut libc::c_void,
|
||||
toc_data: html_toc_data,
|
||||
flags: libc::c_uint,
|
||||
link_attributes: Option<extern "C" fn(*mut hoedown_buffer, *hoedown_buffer,
|
||||
link_attributes: Option<extern "C" fn(*mut hoedown_buffer,
|
||||
*const hoedown_buffer,
|
||||
*mut libc::c_void)>,
|
||||
}
|
||||
|
||||
|
|
@ -93,13 +94,13 @@ struct html_toc_data {
|
|||
}
|
||||
|
||||
struct MyOpaque {
|
||||
dfltblk: extern "C" fn(*mut hoedown_buffer, *hoedown_buffer,
|
||||
*hoedown_buffer, *mut libc::c_void),
|
||||
dfltblk: extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
|
||||
*const hoedown_buffer, *mut libc::c_void),
|
||||
toc_builder: Option<TocBuilder>,
|
||||
}
|
||||
|
||||
struct hoedown_buffer {
|
||||
data: *u8,
|
||||
data: *const u8,
|
||||
size: libc::size_t,
|
||||
asize: libc::size_t,
|
||||
unit: libc::size_t,
|
||||
|
|
@ -118,12 +119,12 @@ extern {
|
|||
max_nesting: libc::size_t) -> *mut hoedown_document;
|
||||
fn hoedown_document_render(doc: *mut hoedown_document,
|
||||
ob: *mut hoedown_buffer,
|
||||
document: *u8,
|
||||
document: *const u8,
|
||||
doc_size: libc::size_t);
|
||||
fn hoedown_document_free(md: *mut hoedown_document);
|
||||
|
||||
fn hoedown_buffer_new(unit: libc::size_t) -> *mut hoedown_buffer;
|
||||
fn hoedown_buffer_puts(b: *mut hoedown_buffer, c: *libc::c_char);
|
||||
fn hoedown_buffer_puts(b: *mut hoedown_buffer, c: *const libc::c_char);
|
||||
fn hoedown_buffer_free(b: *mut hoedown_buffer);
|
||||
|
||||
}
|
||||
|
|
@ -147,13 +148,13 @@ local_data_key!(test_idx: Cell<uint>)
|
|||
local_data_key!(pub playground_krate: Option<String>)
|
||||
|
||||
pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
|
||||
extern fn block(ob: *mut hoedown_buffer, text: *hoedown_buffer,
|
||||
lang: *hoedown_buffer, opaque: *mut libc::c_void) {
|
||||
extern fn block(ob: *mut hoedown_buffer, text: *const hoedown_buffer,
|
||||
lang: *const hoedown_buffer, opaque: *mut libc::c_void) {
|
||||
unsafe {
|
||||
if text.is_null() { return }
|
||||
|
||||
let opaque = opaque as *mut hoedown_html_renderer_state;
|
||||
let my_opaque: &MyOpaque = &*((*opaque).opaque as *MyOpaque);
|
||||
let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque);
|
||||
slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
|
||||
let origtext = str::from_utf8(text).unwrap();
|
||||
debug!("docblock: ==============\n{}\n=======", text);
|
||||
|
|
@ -205,15 +206,13 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
|
|||
s.push_str(highlight::highlight(text.as_slice(), None, id)
|
||||
.as_slice());
|
||||
let output = s.to_c_str();
|
||||
output.with_ref(|r| {
|
||||
hoedown_buffer_puts(ob, r)
|
||||
})
|
||||
hoedown_buffer_puts(ob, output.as_ptr());
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
extern fn header(ob: *mut hoedown_buffer, text: *hoedown_buffer,
|
||||
extern fn header(ob: *mut hoedown_buffer, text: *const hoedown_buffer,
|
||||
level: libc::c_int, opaque: *mut libc::c_void) {
|
||||
// hoedown does this, we may as well too
|
||||
"\n".with_c_str(|p| unsafe { hoedown_buffer_puts(ob, p) });
|
||||
|
|
@ -304,8 +303,10 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
|
|||
}
|
||||
|
||||
pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
|
||||
extern fn block(_ob: *mut hoedown_buffer, text: *hoedown_buffer,
|
||||
lang: *hoedown_buffer, opaque: *mut libc::c_void) {
|
||||
extern fn block(_ob: *mut hoedown_buffer,
|
||||
text: *const hoedown_buffer,
|
||||
lang: *const hoedown_buffer,
|
||||
opaque: *mut libc::c_void) {
|
||||
unsafe {
|
||||
if text.is_null() { return }
|
||||
let block_info = if lang.is_null() {
|
||||
|
|
@ -333,7 +334,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
|
|||
}
|
||||
}
|
||||
|
||||
extern fn header(_ob: *mut hoedown_buffer, text: *hoedown_buffer,
|
||||
extern fn header(_ob: *mut hoedown_buffer,
|
||||
text: *const hoedown_buffer,
|
||||
level: libc::c_int, opaque: *mut libc::c_void) {
|
||||
unsafe {
|
||||
let opaque = opaque as *mut hoedown_html_renderer_state;
|
||||
|
|
|
|||
|
|
@ -41,17 +41,18 @@ use std::str;
|
|||
use std::string::String;
|
||||
use std::sync::Arc;
|
||||
|
||||
use externalfiles::ExternalHtml;
|
||||
|
||||
use serialize::json::ToJson;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::attr;
|
||||
use syntax::parse::token::InternedString;
|
||||
use rustc::util::nodemap::NodeSet;
|
||||
|
||||
use clean;
|
||||
use doctree;
|
||||
use fold::DocFolder;
|
||||
use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace};
|
||||
use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace, Stability};
|
||||
use html::format::{ConciseStability};
|
||||
use html::highlight;
|
||||
use html::item_type::{ItemType, shortty};
|
||||
use html::item_type;
|
||||
|
|
@ -78,7 +79,7 @@ pub struct Context {
|
|||
/// This changes as the context descends into the module hierarchy.
|
||||
pub dst: Path,
|
||||
/// This describes the layout of each page, and is not modified after
|
||||
/// creation of the context (contains info like the favicon)
|
||||
/// creation of the context (contains info like the favicon and added html).
|
||||
pub layout: layout::Layout,
|
||||
/// This map is a list of what should be displayed on the sidebar of the
|
||||
/// current page. The key is the section header (traits, modules,
|
||||
|
|
@ -112,6 +113,15 @@ pub struct Implementor {
|
|||
generics: clean::Generics,
|
||||
trait_: clean::Type,
|
||||
for_: clean::Type,
|
||||
stability: Option<clean::Stability>,
|
||||
}
|
||||
|
||||
/// Metadata about implementations for a type.
|
||||
#[deriving(Clone)]
|
||||
pub struct Impl {
|
||||
impl_: clean::Impl,
|
||||
dox: Option<String>,
|
||||
stability: Option<clean::Stability>,
|
||||
}
|
||||
|
||||
/// This cache is used to store information about the `clean::Crate` being
|
||||
|
|
@ -135,7 +145,7 @@ pub struct Cache {
|
|||
///
|
||||
/// The values of the map are a list of implementations and documentation
|
||||
/// found on that implementation.
|
||||
pub impls: HashMap<ast::DefId, Vec<(clean::Impl, Option<String>)>>,
|
||||
pub impls: HashMap<ast::DefId, Vec<Impl>>,
|
||||
|
||||
/// Maintains a mapping of local crate node ids to the fully qualified name
|
||||
/// and "short type description" of that node. This is used when generating
|
||||
|
|
@ -220,7 +230,7 @@ local_data_key!(pub cache_key: Arc<Cache>)
|
|||
local_data_key!(pub current_location_key: Vec<String> )
|
||||
|
||||
/// Generates the documentation for `crate` into the directory `dst`
|
||||
pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
|
||||
pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) -> io::IoResult<()> {
|
||||
let mut cx = Context {
|
||||
dst: dst,
|
||||
current: Vec::new(),
|
||||
|
|
@ -229,12 +239,14 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
|
|||
layout: layout::Layout {
|
||||
logo: "".to_string(),
|
||||
favicon: "".to_string(),
|
||||
external_html: external_html.clone(),
|
||||
krate: krate.name.clone(),
|
||||
playground_url: "".to_string(),
|
||||
},
|
||||
include_sources: true,
|
||||
render_redirect_pages: false,
|
||||
};
|
||||
|
||||
try!(mkdir(&cx.dst));
|
||||
|
||||
// Crawl the crate attributes looking for attributes which control how we're
|
||||
|
|
@ -546,7 +558,8 @@ fn write_shared(cx: &Context,
|
|||
// going on). If they're in different crates then the crate defining
|
||||
// the trait will be interested in our implementation.
|
||||
if imp.def_id.krate == did.krate { continue }
|
||||
try!(write!(&mut f, r#""impl{} {} for {}","#,
|
||||
try!(write!(&mut f, r#""{}impl{} {} for {}","#,
|
||||
ConciseStability(&imp.stability),
|
||||
imp.generics, imp.trait_, imp.for_));
|
||||
}
|
||||
try!(writeln!(&mut f, r"];"));
|
||||
|
|
@ -778,6 +791,7 @@ impl DocFolder for Cache {
|
|||
generics: i.generics.clone(),
|
||||
trait_: i.trait_.get_ref().clone(),
|
||||
for_: i.for_.clone(),
|
||||
stability: item.stability.clone(),
|
||||
});
|
||||
}
|
||||
Some(..) | None => {}
|
||||
|
|
@ -963,7 +977,11 @@ impl DocFolder for Cache {
|
|||
let v = self.impls.find_or_insert_with(did, |_| {
|
||||
Vec::new()
|
||||
});
|
||||
v.push((i, dox));
|
||||
v.push(Impl {
|
||||
impl_: i,
|
||||
dox: dox,
|
||||
stability: item.stability.clone(),
|
||||
});
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
|
@ -1244,19 +1262,8 @@ impl<'a> fmt::Show for Item<'a> {
|
|||
try!(write!(fmt, "<a class='{}' href=''>{}</a>",
|
||||
shortty(self.item), self.item.name.get_ref().as_slice()));
|
||||
|
||||
// Write stability attributes
|
||||
match attr::find_stability_generic(self.item.attrs.iter()) {
|
||||
Some((ref stability, _)) => {
|
||||
try!(write!(fmt,
|
||||
"<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
|
||||
lvl = stability.level.to_str(),
|
||||
reason = match stability.text {
|
||||
Some(ref s) => (*s).clone(),
|
||||
None => InternedString::new(""),
|
||||
}));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
// Write stability level
|
||||
try!(write!(fmt, "{}", Stability(&self.item.stability)));
|
||||
|
||||
// Write `src` tag
|
||||
//
|
||||
|
|
@ -1450,10 +1457,11 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
|
||||
try!(write!(w, "
|
||||
<tr>
|
||||
<td><code>{}static {}{}: {}</code>{}</td>
|
||||
<td>{}<code>{}static {}{}: {}</code>{}</td>
|
||||
<td class='docblock'>{} </td>
|
||||
</tr>
|
||||
",
|
||||
ConciseStability(&myitem.stability),
|
||||
VisSpace(myitem.visibility),
|
||||
MutableSpace(s.mutability),
|
||||
*myitem.name.get_ref(),
|
||||
|
|
@ -1488,7 +1496,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
if myitem.name.is_none() { continue }
|
||||
try!(write!(w, "
|
||||
<tr>
|
||||
<td><a class='{class}' href='{href}'
|
||||
<td>{stab}<a class='{class}' href='{href}'
|
||||
title='{title}'>{}</a></td>
|
||||
<td class='docblock short'>{}</td>
|
||||
</tr>
|
||||
|
|
@ -1497,7 +1505,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
Markdown(shorter(myitem.doc_value())),
|
||||
class = shortty(myitem),
|
||||
href = item_path(myitem),
|
||||
title = full_path(cx, myitem)));
|
||||
title = full_path(cx, myitem),
|
||||
stab = ConciseStability(&myitem.stability)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1561,9 +1570,10 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
|||
try!(document(w, it));
|
||||
|
||||
fn meth(w: &mut fmt::Formatter, m: &clean::TraitMethod) -> fmt::Result {
|
||||
try!(write!(w, "<h3 id='{}.{}' class='method'><code>",
|
||||
shortty(m.item()),
|
||||
*m.item().name.get_ref()));
|
||||
try!(write!(w, "<h3 id='{}.{}' class='method'>{}<code>",
|
||||
shortty(m.item()),
|
||||
*m.item().name.get_ref(),
|
||||
ConciseStability(&m.item().stability)));
|
||||
try!(render_method(w, m.item()));
|
||||
try!(write!(w, "</code></h3>"));
|
||||
try!(document(w, m.item()));
|
||||
|
|
@ -1600,7 +1610,8 @@ 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_));
|
||||
}
|
||||
}
|
||||
|
|
@ -1673,7 +1684,8 @@ fn item_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
|||
try!(write!(w, "<h2 class='fields'>Fields</h2>\n<table>"));
|
||||
for field in fields {
|
||||
try!(write!(w, "<tr><td id='structfield.{name}'>\
|
||||
<code>{name}</code></td><td>",
|
||||
{stab}<code>{name}</code></td><td>",
|
||||
stab = ConciseStability(&field.stability),
|
||||
name = field.name.get_ref().as_slice()));
|
||||
try!(document(w, field));
|
||||
try!(write!(w, "</td></tr>"));
|
||||
|
|
@ -1739,7 +1751,8 @@ fn item_enum(w: &mut fmt::Formatter, it: &clean::Item,
|
|||
if e.variants.len() > 0 {
|
||||
try!(write!(w, "<h2 class='variants'>Variants</h2>\n<table>"));
|
||||
for variant in e.variants.iter() {
|
||||
try!(write!(w, "<tr><td id='variant.{name}'><code>{name}</code></td><td>",
|
||||
try!(write!(w, "<tr><td id='variant.{name}'>{stab}<code>{name}</code></td><td>",
|
||||
stab = ConciseStability(&variant.stability),
|
||||
name = variant.name.get_ref().as_slice()));
|
||||
try!(document(w, variant));
|
||||
match variant.inner {
|
||||
|
|
@ -1849,39 +1862,25 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
|||
fn render_methods(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result {
|
||||
match cache_key.get().unwrap().impls.find(&it.def_id) {
|
||||
Some(v) => {
|
||||
let mut non_trait = v.iter().filter(|p| {
|
||||
p.ref0().trait_.is_none()
|
||||
});
|
||||
let non_trait = non_trait.collect::<Vec<&(clean::Impl, Option<String>)>>();
|
||||
let mut traits = v.iter().filter(|p| {
|
||||
p.ref0().trait_.is_some()
|
||||
});
|
||||
let traits = traits.collect::<Vec<&(clean::Impl, Option<String>)>>();
|
||||
|
||||
let (non_trait, traits) = v.partitioned(|i| i.impl_.trait_.is_none());
|
||||
if non_trait.len() > 0 {
|
||||
try!(write!(w, "<h2 id='methods'>Methods</h2>"));
|
||||
for &(ref i, ref dox) in non_trait.move_iter() {
|
||||
try!(render_impl(w, i, dox));
|
||||
for i in non_trait.iter() {
|
||||
try!(render_impl(w, i));
|
||||
}
|
||||
}
|
||||
if traits.len() > 0 {
|
||||
try!(write!(w, "<h2 id='implementations'>Trait \
|
||||
Implementations</h2>"));
|
||||
let mut any_derived = false;
|
||||
for & &(ref i, ref dox) in traits.iter() {
|
||||
if !i.derived {
|
||||
try!(render_impl(w, i, dox));
|
||||
} else {
|
||||
any_derived = true;
|
||||
}
|
||||
let (derived, manual) = traits.partition(|i| i.impl_.derived);
|
||||
for i in manual.iter() {
|
||||
try!(render_impl(w, i));
|
||||
}
|
||||
if any_derived {
|
||||
if derived.len() > 0 {
|
||||
try!(write!(w, "<h3 id='derived_implementations'>Derived Implementations \
|
||||
</h3>"));
|
||||
for &(ref i, ref dox) in traits.move_iter() {
|
||||
if i.derived {
|
||||
try!(render_impl(w, i, dox));
|
||||
}
|
||||
for i in derived.iter() {
|
||||
try!(render_impl(w, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1891,15 +1890,16 @@ fn render_methods(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn render_impl(w: &mut fmt::Formatter, i: &clean::Impl,
|
||||
dox: &Option<String>) -> fmt::Result {
|
||||
try!(write!(w, "<h3 class='impl'><code>impl{} ", i.generics));
|
||||
match i.trait_ {
|
||||
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_.trait_ {
|
||||
Some(ref ty) => try!(write!(w, "{} for ", *ty)),
|
||||
None => {}
|
||||
}
|
||||
try!(write!(w, "{}</code></h3>", i.for_));
|
||||
match *dox {
|
||||
try!(write!(w, "{}</code></h3>", i.impl_.for_));
|
||||
match i.dox {
|
||||
Some(ref dox) => {
|
||||
try!(write!(w, "<div class='docblock'>{}</div>",
|
||||
Markdown(dox.as_slice())));
|
||||
|
|
@ -1909,8 +1909,9 @@ fn render_impl(w: &mut fmt::Formatter, i: &clean::Impl,
|
|||
|
||||
fn docmeth(w: &mut fmt::Formatter, item: &clean::Item,
|
||||
dox: bool) -> fmt::Result {
|
||||
try!(write!(w, "<h4 id='method.{}' class='method'><code>",
|
||||
*item.name.get_ref()));
|
||||
try!(write!(w, "<h4 id='method.{}' class='method'>{}<code>",
|
||||
*item.name.get_ref(),
|
||||
ConciseStability(&item.stability)));
|
||||
try!(render_method(w, item));
|
||||
try!(write!(w, "</code></h4>\n"));
|
||||
match item.doc_value() {
|
||||
|
|
@ -1922,8 +1923,8 @@ fn render_impl(w: &mut fmt::Formatter, i: &clean::Impl,
|
|||
}
|
||||
}
|
||||
|
||||
try!(write!(w, "<div class='methods'>"));
|
||||
for meth in i.methods.iter() {
|
||||
try!(write!(w, "<div class='impl-methods'>"));
|
||||
for meth in i.impl_.methods.iter() {
|
||||
try!(docmeth(w, meth, true));
|
||||
}
|
||||
|
||||
|
|
@ -1944,11 +1945,11 @@ fn render_impl(w: &mut fmt::Formatter, i: &clean::Impl,
|
|||
|
||||
// If we've implemented a trait, then also emit documentation for all
|
||||
// default methods which weren't overridden in the implementation block.
|
||||
match i.trait_ {
|
||||
match i.impl_.trait_ {
|
||||
Some(clean::ResolvedPath { did, .. }) => {
|
||||
try!({
|
||||
match cache_key.get().unwrap().traits.find(&did) {
|
||||
Some(t) => try!(render_default_methods(w, t, i)),
|
||||
Some(t) => try!(render_default_methods(w, t, &i.impl_)),
|
||||
None => {}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -258,8 +258,9 @@ nav.sub {
|
|||
.content .multi-column li { width: 100%; display: inline-block; }
|
||||
|
||||
.content .method { font-size: 1em; }
|
||||
.content .methods { margin-left: 20px; }
|
||||
.content .methods .docblock { margin-left: 20px; }
|
||||
.content .methods .docblock { margin-left: 40px; }
|
||||
|
||||
.content .impl-methods .docblock { margin-left: 40px; }
|
||||
|
||||
nav {
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
|
|
@ -372,20 +373,29 @@ p a:hover { text-decoration: underline; }
|
|||
}
|
||||
|
||||
.stability {
|
||||
border-left: 6px solid #000;
|
||||
border-left: 6px solid;
|
||||
padding: 3px 6px;
|
||||
border-radius: 3px;
|
||||
font-weight: 400;
|
||||
padding: 4px 10px;
|
||||
text-transform: lowercase;
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.stability.Deprecated { border-color: #D60027; color: #880017; }
|
||||
.stability.Experimental { border-color: #EC5315; color: #a53c0e; }
|
||||
.stability.Unstable { border-color: #FFD700; color: #b39800; }
|
||||
.stability.Stable { border-color: #AEC516; color: #7c8b10; }
|
||||
h1 .stability {
|
||||
text-transform: lowercase;
|
||||
font-weight: 400;
|
||||
margin-left: 14px;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
|
||||
.impl-methods .stability {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.stability.Deprecated { border-color: #A071A8; color: #82478C; }
|
||||
.stability.Experimental { border-color: #D46D6A; color: #AA3C39; }
|
||||
.stability.Unstable { border-color: #D4B16A; color: #AA8439; }
|
||||
.stability.Stable { border-color: #54A759; color: #2D8632; }
|
||||
.stability.Frozen { border-color: #009431; color: #007726; }
|
||||
.stability.Locked { border-color: #0084B6; color: #00668c; }
|
||||
.stability.Unmarked { border-color: #FFFFFF; }
|
||||
|
||||
:target { background: #FDFFD3; }
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ use std::io::{File, MemWriter};
|
|||
use std::str;
|
||||
use std::gc::Gc;
|
||||
use serialize::{json, Decodable, Encodable};
|
||||
use externalfiles::ExternalHtml;
|
||||
|
||||
// reexported from `clean` so it can be easily updated with the mod itself
|
||||
pub use clean::SCHEMA_VERSION;
|
||||
|
|
@ -39,6 +40,8 @@ pub use clean::SCHEMA_VERSION;
|
|||
pub mod clean;
|
||||
pub mod core;
|
||||
pub mod doctree;
|
||||
#[macro_escape]
|
||||
pub mod externalfiles;
|
||||
pub mod fold;
|
||||
pub mod html {
|
||||
pub mod highlight;
|
||||
|
|
@ -113,16 +116,17 @@ pub fn opts() -> Vec<getopts::OptGroup> {
|
|||
"ARGS"),
|
||||
optmulti("", "markdown-css", "CSS files to include via <link> in a rendered Markdown file",
|
||||
"FILES"),
|
||||
optmulti("", "markdown-in-header",
|
||||
"files to include inline in the <head> section of a rendered Markdown file",
|
||||
optmulti("", "html-in-header",
|
||||
"files to include inline in the <head> section of a rendered Markdown file \
|
||||
or generated documentation",
|
||||
"FILES"),
|
||||
optmulti("", "markdown-before-content",
|
||||
optmulti("", "html-before-content",
|
||||
"files to include inline between <body> and the content of a rendered \
|
||||
Markdown file",
|
||||
Markdown file or generated documentation",
|
||||
"FILES"),
|
||||
optmulti("", "markdown-after-content",
|
||||
optmulti("", "html-after-content",
|
||||
"files to include inline between the content and </body> of a rendered \
|
||||
Markdown file",
|
||||
Markdown file or generated documentation",
|
||||
"FILES"),
|
||||
optopt("", "markdown-playground-url",
|
||||
"URL to send code snippets to", "URL")
|
||||
|
|
@ -179,6 +183,14 @@ pub fn main_args(args: &[String]) -> int {
|
|||
let output = matches.opt_str("o").map(|s| Path::new(s));
|
||||
let cfgs = matches.opt_strs("cfg");
|
||||
|
||||
let external_html = match ExternalHtml::load(
|
||||
matches.opt_strs("html-in-header").as_slice(),
|
||||
matches.opt_strs("html-before-content").as_slice(),
|
||||
matches.opt_strs("html-after-content").as_slice()) {
|
||||
Some(eh) => eh,
|
||||
None => return 3
|
||||
};
|
||||
|
||||
match (should_test, markdown_input) {
|
||||
(true, true) => {
|
||||
return markdown::test(input, libs, test_args)
|
||||
|
|
@ -187,7 +199,7 @@ pub fn main_args(args: &[String]) -> int {
|
|||
return test::run(input, cfgs, libs, test_args)
|
||||
}
|
||||
(false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
|
||||
&matches),
|
||||
&matches, &external_html),
|
||||
(false, false) => {}
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +227,7 @@ pub fn main_args(args: &[String]) -> int {
|
|||
let started = time::precise_time_ns();
|
||||
match matches.opt_str("w").as_ref().map(|s| s.as_slice()) {
|
||||
Some("html") | None => {
|
||||
match html::render::run(krate, output.unwrap_or(Path::new("doc"))) {
|
||||
match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc"))) {
|
||||
Ok(()) => {}
|
||||
Err(e) => fail!("failed to generate documentation: {}", e),
|
||||
}
|
||||
|
|
@ -396,18 +408,17 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
|
|||
// "crate": { parsed crate ... },
|
||||
// "plugins": { output of plugins ... }
|
||||
// }
|
||||
let mut json = box std::collections::TreeMap::new();
|
||||
json.insert("schema".to_string(),
|
||||
json::String(SCHEMA_VERSION.to_string()));
|
||||
let plugins_json = box res.move_iter()
|
||||
.filter_map(|opt| {
|
||||
match opt {
|
||||
None => None,
|
||||
Some((string, json)) => {
|
||||
Some((string.to_string(), json))
|
||||
}
|
||||
let mut json = std::collections::TreeMap::new();
|
||||
json.insert("schema".to_string(), json::String(SCHEMA_VERSION.to_string()));
|
||||
let plugins_json = res.move_iter()
|
||||
.filter_map(|opt| {
|
||||
match opt {
|
||||
None => None,
|
||||
Some((string, json)) => {
|
||||
Some((string.to_string(), json))
|
||||
}
|
||||
}).collect();
|
||||
}
|
||||
}).collect();
|
||||
|
||||
// FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
|
||||
// straight to the Rust JSON representation.
|
||||
|
|
@ -417,7 +428,7 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
|
|||
let mut encoder = json::Encoder::new(&mut w as &mut io::Writer);
|
||||
krate.encode(&mut encoder).unwrap();
|
||||
}
|
||||
str::from_utf8(w.unwrap().as_slice()).unwrap().to_string()
|
||||
str::from_utf8_owned(w.unwrap()).unwrap()
|
||||
};
|
||||
let crate_json = match json::from_str(crate_json_str.as_slice()) {
|
||||
Ok(j) => j,
|
||||
|
|
@ -428,6 +439,5 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
|
|||
json.insert("plugins".to_string(), json::Object(plugins_json));
|
||||
|
||||
let mut file = try!(File::create(&dst));
|
||||
try!(json::Object(json).to_writer(&mut file));
|
||||
Ok(())
|
||||
json::Object(json).to_writer(&mut file)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,43 +9,19 @@
|
|||
// except according to those terms.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::{str, io};
|
||||
use std::io;
|
||||
use std::string::String;
|
||||
|
||||
use getopts;
|
||||
use testing;
|
||||
|
||||
use externalfiles::ExternalHtml;
|
||||
|
||||
use html::escape::Escape;
|
||||
use html::markdown;
|
||||
use html::markdown::{MarkdownWithToc, find_testable_code, reset_headers};
|
||||
use test::Collector;
|
||||
|
||||
fn load_string(input: &Path) -> io::IoResult<Option<String>> {
|
||||
let mut f = try!(io::File::open(input));
|
||||
let d = try!(f.read_to_end());
|
||||
Ok(str::from_utf8(d.as_slice()).map(|s| s.to_string()))
|
||||
}
|
||||
macro_rules! load_or_return {
|
||||
($input: expr, $cant_read: expr, $not_utf8: expr) => {
|
||||
{
|
||||
let input = Path::new($input);
|
||||
match load_string(&input) {
|
||||
Err(e) => {
|
||||
let _ = writeln!(&mut io::stderr(),
|
||||
"error reading `{}`: {}", input.display(), e);
|
||||
return $cant_read;
|
||||
}
|
||||
Ok(None) => {
|
||||
let _ = writeln!(&mut io::stderr(),
|
||||
"error reading `{}`: not UTF-8", input.display());
|
||||
return $not_utf8;
|
||||
}
|
||||
Ok(Some(s)) => s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Separate any lines at the start of the file that begin with `%`.
|
||||
fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
|
||||
let mut metadata = Vec::new();
|
||||
|
|
@ -62,18 +38,10 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
|
|||
(metadata, "")
|
||||
}
|
||||
|
||||
fn load_external_files(names: &[String]) -> Option<String> {
|
||||
let mut out = String::new();
|
||||
for name in names.iter() {
|
||||
out.push_str(load_or_return!(name.as_slice(), None, None).as_slice());
|
||||
out.push_char('\n');
|
||||
}
|
||||
Some(out)
|
||||
}
|
||||
|
||||
/// Render `input` (e.g. "foo.md") into an HTML file in `output`
|
||||
/// (e.g. output = "bar" => "bar/foo.html").
|
||||
pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int {
|
||||
pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
|
||||
external_html: &ExternalHtml) -> int {
|
||||
let input_p = Path::new(input);
|
||||
output.push(input_p.filestem().unwrap());
|
||||
output.set_extension("html");
|
||||
|
|
@ -91,17 +59,6 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
|
|||
}
|
||||
let playground = playground.unwrap_or("".to_string());
|
||||
|
||||
let (in_header, before_content, after_content) =
|
||||
match (load_external_files(matches.opt_strs("markdown-in-header")
|
||||
.as_slice()),
|
||||
load_external_files(matches.opt_strs("markdown-before-content")
|
||||
.as_slice()),
|
||||
load_external_files(matches.opt_strs("markdown-after-content")
|
||||
.as_slice())) {
|
||||
(Some(a), Some(b), Some(c)) => (a,b,c),
|
||||
_ => return 3
|
||||
};
|
||||
|
||||
let mut out = match io::File::create(&output) {
|
||||
Err(e) => {
|
||||
let _ = writeln!(&mut io::stderr(),
|
||||
|
|
@ -153,10 +110,10 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
|
|||
</html>"#,
|
||||
title = Escape(title),
|
||||
css = css,
|
||||
in_header = in_header,
|
||||
before_content = before_content,
|
||||
in_header = external_html.in_header,
|
||||
before_content = external_html.before_content,
|
||||
text = MarkdownWithToc(text),
|
||||
after_content = after_content,
|
||||
after_content = external_html.after_content,
|
||||
playground = playground,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl PluginManager {
|
|||
let lib = lib_result.unwrap();
|
||||
unsafe {
|
||||
let plugin = lib.symbol("rustdoc_plugin_entrypoint").unwrap();
|
||||
self.callbacks.push(mem::transmute::<*u8,PluginCallback>(plugin));
|
||||
self.callbacks.push(mem::transmute::<*mut u8,PluginCallback>(plugin));
|
||||
}
|
||||
self.dylibs.push(lib);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,7 +140,14 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
|
|||
let old = io::stdio::set_stderr(box w1);
|
||||
spawn(proc() {
|
||||
let mut p = io::ChanReader::new(rx);
|
||||
let mut err = old.unwrap_or(box io::stderr() as Box<Writer + Send>);
|
||||
let mut err = match old {
|
||||
Some(old) => {
|
||||
// Chop off the `Send` bound.
|
||||
let old: Box<Writer> = old;
|
||||
old
|
||||
}
|
||||
None => box io::stderr() as Box<Writer>,
|
||||
};
|
||||
io::util::copy(&mut p, &mut err).unwrap();
|
||||
});
|
||||
let emitter = diagnostic::EmitterWriter::new(box w2);
|
||||
|
|
|
|||
|
|
@ -15,9 +15,12 @@ use syntax::abi;
|
|||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::ast_map;
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
use rustc::middle::stability;
|
||||
|
||||
use std::gc::{Gc, GC};
|
||||
|
||||
use core;
|
||||
|
|
@ -41,6 +44,14 @@ impl<'a> RustdocVisitor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn stability(&self, id: ast::NodeId) -> Option<attr::Stability> {
|
||||
let tcx = match self.cx.maybe_typed {
|
||||
core::Typed(ref tcx) => tcx,
|
||||
core::NotTyped(_) => return None
|
||||
};
|
||||
stability::lookup(tcx, ast_util::local_def(id))
|
||||
}
|
||||
|
||||
pub fn visit(&mut self, krate: &ast::Crate) {
|
||||
self.attrs = krate.attrs.iter().map(|x| (*x).clone()).collect();
|
||||
|
||||
|
|
@ -65,6 +76,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
struct_type: struct_type,
|
||||
name: item.ident,
|
||||
vis: item.vis,
|
||||
stab: self.stability(item.id),
|
||||
attrs: item.attrs.iter().map(|x| *x).collect(),
|
||||
generics: generics.clone(),
|
||||
fields: sd.fields.iter().map(|x| (*x).clone()).collect(),
|
||||
|
|
@ -81,6 +93,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
name: x.node.name,
|
||||
attrs: x.node.attrs.iter().map(|x| *x).collect(),
|
||||
vis: x.node.vis,
|
||||
stab: self.stability(x.node.id),
|
||||
id: x.node.id,
|
||||
kind: x.node.kind.clone(),
|
||||
where: x.span,
|
||||
|
|
@ -90,6 +103,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
name: it.ident,
|
||||
variants: vars,
|
||||
vis: it.vis,
|
||||
stab: self.stability(it.id),
|
||||
generics: params.clone(),
|
||||
attrs: it.attrs.iter().map(|x| *x).collect(),
|
||||
id: it.id,
|
||||
|
|
@ -104,6 +118,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
Function {
|
||||
id: item.id,
|
||||
vis: item.vis,
|
||||
stab: self.stability(item.id),
|
||||
attrs: item.attrs.iter().map(|x| *x).collect(),
|
||||
decl: fd.clone(),
|
||||
name: item.ident,
|
||||
|
|
@ -125,6 +140,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
om.where_inner = m.inner;
|
||||
om.attrs = attrs;
|
||||
om.vis = vis;
|
||||
om.stab = self.stability(id);
|
||||
om.id = id;
|
||||
for i in m.items.iter() {
|
||||
self.visit_item(&**i, &mut om);
|
||||
|
|
@ -258,6 +274,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
attrs: item.attrs.iter().map(|x| *x).collect(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
stab: self.stability(item.id),
|
||||
};
|
||||
om.typedefs.push(t);
|
||||
},
|
||||
|
|
@ -271,6 +288,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
attrs: item.attrs.iter().map(|x| *x).collect(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
stab: self.stability(item.id),
|
||||
};
|
||||
om.statics.push(s);
|
||||
},
|
||||
|
|
@ -284,6 +302,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
attrs: item.attrs.iter().map(|x| *x).collect(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
stab: self.stability(item.id),
|
||||
};
|
||||
om.traits.push(t);
|
||||
},
|
||||
|
|
@ -297,6 +316,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
id: item.id,
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
stab: self.stability(item.id),
|
||||
};
|
||||
om.impls.push(i);
|
||||
},
|
||||
|
|
@ -309,6 +329,7 @@ impl<'a> RustdocVisitor<'a> {
|
|||
attrs: item.attrs.iter().map(|x| *x).collect(),
|
||||
name: item.ident,
|
||||
where: item.span,
|
||||
stab: self.stability(item.id),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue