Skip to content

rustdoc: Another round of improvements #24396

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 16, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,17 @@ fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEn
})
}

fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
did: ast::DefId) -> Vec<clean::Item> {
pub fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
did: ast::DefId) -> Vec<clean::Item> {
ty::populate_implementations_for_type_if_necessary(tcx, did);
let mut impls = Vec::new();

match tcx.inherent_impls.borrow().get(&did) {
None => {}
Some(i) => {
impls.extend(i.iter().map(|&did| { build_impl(cx, tcx, did) }));
for &did in i.iter() {
build_impl(cx, tcx, did, &mut impls);
}
}
}

Expand All @@ -247,9 +249,9 @@ fn build_impls(cx: &DocContext, tcx: &ty::ctxt,

fn populate_impls(cx: &DocContext, tcx: &ty::ctxt,
def: decoder::DefLike,
impls: &mut Vec<Option<clean::Item>>) {
impls: &mut Vec<clean::Item>) {
match def {
decoder::DlImpl(did) => impls.push(build_impl(cx, tcx, did)),
decoder::DlImpl(did) => build_impl(cx, tcx, did, impls),
decoder::DlDef(def::DefMod(did)) => {
csearch::each_child_of_item(&tcx.sess.cstore,
did,
Expand All @@ -262,14 +264,15 @@ fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
}
}

impls.into_iter().filter_map(|a| a).collect()
return impls;
}

fn build_impl(cx: &DocContext,
tcx: &ty::ctxt,
did: ast::DefId) -> Option<clean::Item> {
pub fn build_impl(cx: &DocContext,
tcx: &ty::ctxt,
did: ast::DefId,
ret: &mut Vec<clean::Item>) {
if !cx.inlined.borrow_mut().as_mut().unwrap().insert(did) {
return None
return
}

let attrs = load_attrs(cx, tcx, did);
Expand All @@ -278,13 +281,13 @@ fn build_impl(cx: &DocContext,
// If this is an impl for a #[doc(hidden)] trait, be sure to not inline
let trait_attrs = load_attrs(cx, tcx, t.def_id);
if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
return None
return
}
}

// If this is a defaulted impl, then bail out early here
if csearch::is_default_impl(&tcx.sess.cstore, did) {
return Some(clean::Item {
return ret.push(clean::Item {
inner: clean::DefaultImplItem(clean::DefaultImpl {
// FIXME: this should be decoded
unsafety: ast::Unsafety::Normal,
Expand Down Expand Up @@ -352,19 +355,25 @@ fn build_impl(cx: &DocContext,
})
}
}
}).collect();
}).collect::<Vec<_>>();
let polarity = csearch::get_impl_polarity(tcx, did);
let ty = ty::lookup_item_type(tcx, did);
return Some(clean::Item {
let trait_ = associated_trait.clean(cx).map(|bound| {
match bound {
clean::TraitBound(polyt, _) => polyt.trait_,
clean::RegionBound(..) => unreachable!(),
}
});
if let Some(clean::ResolvedPath { did, .. }) = trait_ {
if Some(did) == cx.deref_trait_did.get() {
super::build_deref_target_impls(cx, &trait_items, ret);
}
}
ret.push(clean::Item {
inner: clean::ImplItem(clean::Impl {
unsafety: ast::Unsafety::Normal, // FIXME: this should be decoded
derived: clean::detect_derived(&attrs),
trait_: associated_trait.clean(cx).map(|bound| {
match bound {
clean::TraitBound(polyt, _) => polyt.trait_,
clean::RegionBound(..) => unreachable!(),
}
}),
trait_: trait_,
for_: ty.ty.clean(cx),
generics: (&ty.generics, &predicates, subst::TypeSpace).clean(cx),
items: trait_items,
Expand Down
101 changes: 95 additions & 6 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
fn clean(&self, cx: &DocContext) -> Crate {
use rustc::session::config::Input;

if let Some(t) = cx.tcx_opt() {
cx.deref_trait_did.set(t.lang_items.deref_trait());
}

let mut externs = Vec::new();
cx.sess().cstore.iter_crate_data(|n, meta| {
externs.push((n, meta.clean(cx)));
Expand Down Expand Up @@ -313,6 +317,22 @@ impl Item {
pub fn is_fn(&self) -> bool {
match self.inner { FunctionItem(..) => true, _ => false }
}

pub fn stability_class(&self) -> String {
match self.stability {
Some(ref s) => {
let mut base = match s.level {
attr::Unstable => "unstable".to_string(),
attr::Stable => String::new(),
};
if !s.deprecated_since.is_empty() {
base.push_str(" deprecated");
}
base
}
_ => String::new(),
}
}
}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
Expand Down Expand Up @@ -371,7 +391,7 @@ impl Clean<Item> for doctree::Module {
items.extend(self.statics.iter().map(|x| x.clean(cx)));
items.extend(self.constants.iter().map(|x| x.clean(cx)));
items.extend(self.traits.iter().map(|x| x.clean(cx)));
items.extend(self.impls.iter().map(|x| x.clean(cx)));
items.extend(self.impls.iter().flat_map(|x| x.clean(cx).into_iter()));
items.extend(self.macros.iter().map(|x| x.clean(cx)));
items.extend(self.def_traits.iter().map(|x| x.clean(cx)));

Expand Down Expand Up @@ -1254,6 +1274,7 @@ impl Clean<Item> for ast::ImplItem {
ast::MacImplItem(_) => {
MacroItem(Macro {
source: self.span.to_src(cx),
imported_from: None,
})
}
};
Expand Down Expand Up @@ -2169,9 +2190,21 @@ fn detect_derived<M: AttrMetaMethods>(attrs: &[M]) -> bool {
attr::contains_name(attrs, "automatically_derived")
}

impl Clean<Item> for doctree::Impl {
fn clean(&self, cx: &DocContext) -> Item {
Item {
impl Clean<Vec<Item>> for doctree::Impl {
fn clean(&self, cx: &DocContext) -> Vec<Item> {
let mut ret = Vec::new();
let trait_ = self.trait_.clean(cx);
let items = self.items.clean(cx);

// If this impl block is an implementation of the Deref trait, then we
// need to try inlining the target's inherent impl blocks as well.
if let Some(ResolvedPath { did, .. }) = trait_ {
if Some(did) == cx.deref_trait_did.get() {
build_deref_target_impls(cx, &items, &mut ret);
}
}

ret.push(Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
Expand All @@ -2181,12 +2214,66 @@ impl Clean<Item> for doctree::Impl {
inner: ImplItem(Impl {
unsafety: self.unsafety,
generics: self.generics.clean(cx),
trait_: self.trait_.clean(cx),
trait_: trait_,
for_: self.for_.clean(cx),
items: self.items.clean(cx),
items: items,
derived: detect_derived(&self.attrs),
polarity: Some(self.polarity.clean(cx)),
}),
});
return ret;
}
}

fn build_deref_target_impls(cx: &DocContext,
items: &[Item],
ret: &mut Vec<Item>) {
let tcx = match cx.tcx_opt() {
Some(t) => t,
None => return,
};

for item in items {
let target = match item.inner {
TypedefItem(ref t) => &t.type_,
_ => continue,
};
let primitive = match *target {
ResolvedPath { did, .. } if ast_util::is_local(did) => continue,
ResolvedPath { did, .. } => {
ret.extend(inline::build_impls(cx, tcx, did));
continue
}
_ => match target.primitive_type() {
Some(prim) => prim,
None => continue,
}
};
let did = match primitive {
Isize => tcx.lang_items.isize_impl(),
I8 => tcx.lang_items.i8_impl(),
I16 => tcx.lang_items.i16_impl(),
I32 => tcx.lang_items.i32_impl(),
I64 => tcx.lang_items.i64_impl(),
Usize => tcx.lang_items.usize_impl(),
U8 => tcx.lang_items.u8_impl(),
U16 => tcx.lang_items.u16_impl(),
U32 => tcx.lang_items.u32_impl(),
U64 => tcx.lang_items.u64_impl(),
F32 => tcx.lang_items.f32_impl(),
F64 => tcx.lang_items.f64_impl(),
Char => tcx.lang_items.char_impl(),
Bool => None,
Str => tcx.lang_items.str_impl(),
Slice => tcx.lang_items.slice_impl(),
Array => tcx.lang_items.slice_impl(),
PrimitiveTuple => None,
PrimitiveRawPointer => tcx.lang_items.const_ptr_impl(),
};
if let Some(did) = did {
if !ast_util::is_local(did) {
inline::build_impl(cx, tcx, did, ret);
}
}
}
}
Expand Down Expand Up @@ -2541,6 +2628,7 @@ fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<ast::DefId> {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Macro {
pub source: String,
pub imported_from: Option<String>,
}

impl Clean<Item> for doctree::Macro {
Expand All @@ -2554,6 +2642,7 @@ impl Clean<Item> for doctree::Macro {
def_id: ast_util::local_def(self.id),
inner: MacroItem(Macro {
source: self.whence.to_src(cx),
imported_from: self.imported_from.clean(cx),
}),
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use rustc_resolve as resolve;

use syntax::{ast, ast_map, codemap, diagnostic};

use std::cell::RefCell;
use std::cell::{RefCell, Cell};
use std::collections::{HashMap, HashSet};

use visit_ast::RustdocVisitor;
Expand Down Expand Up @@ -48,6 +48,7 @@ pub struct DocContext<'tcx> {
pub external_typarams: RefCell<Option<HashMap<ast::DefId, String>>>,
pub inlined: RefCell<Option<HashSet<ast::DefId>>>,
pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
pub deref_trait_did: Cell<Option<ast::DefId>>,
}

impl<'tcx> DocContext<'tcx> {
Expand Down Expand Up @@ -77,6 +78,7 @@ pub struct CrateAnalysis {
pub external_paths: ExternalPaths,
pub external_typarams: RefCell<Option<HashMap<ast::DefId, String>>>,
pub inlined: RefCell<Option<HashSet<ast::DefId>>>,
pub deref_trait_did: Option<ast::DefId>,
}

pub type Externs = HashMap<String, Vec<String>>;
Expand Down Expand Up @@ -147,15 +149,17 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
external_paths: RefCell::new(Some(HashMap::new())),
inlined: RefCell::new(Some(HashSet::new())),
populated_crate_impls: RefCell::new(HashSet::new()),
deref_trait_did: Cell::new(None),
};
debug!("crate: {:?}", ctxt.krate);

let analysis = CrateAnalysis {
let mut analysis = CrateAnalysis {
exported_items: exported_items,
public_items: public_items,
external_paths: RefCell::new(None),
external_typarams: RefCell::new(None),
inlined: RefCell::new(None),
deref_trait_did: None,
};

let krate = {
Expand All @@ -170,5 +174,6 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
*analysis.external_typarams.borrow_mut() = map;
let map = ctxt.inlined.borrow_mut().take();
*analysis.inlined.borrow_mut() = map;
analysis.deref_trait_did = ctxt.deref_trait_did.get();
(krate, analysis)
}
1 change: 1 addition & 0 deletions src/librustdoc/doctree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ pub struct Macro {
pub attrs: Vec<ast::Attribute>,
pub whence: Span,
pub stab: Option<attr::Stability>,
pub imported_from: Option<Ident>,
}

pub struct ExternCrate {
Expand Down
Loading