Merge remote-tracking branch 'origin/master' into 0.11.0-release

Conflicts:
	src/libstd/lib.rs
This commit is contained in:
Alex Crichton 2014-07-02 11:08:21 -07:00
commit ff1dd44b40
715 changed files with 10358 additions and 8207 deletions

View file

@ -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,
})
}

View file

@ -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()),
}
}
}

View file

@ -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 {

View file

@ -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 {

View 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)
}

View file

@ -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 |

View file

@ -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 {

View file

@ -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("&lt;");
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>")
}
}
}
}

View file

@ -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,

View file

@ -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;

View file

@ -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'>{}&nbsp;</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(())

View file

@ -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; }

View file

@ -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)
}

View 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,
);

View file

@ -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);
}

View file

@ -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);

View file

@ -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),
})
}
}