use rustc::middle::subst;
use rustc::middle::subst::VecPerParamSpace;
use rustc::middle::ty;
+use rustc::middle::stability;
use std::rc::Rc;
use std::u32;
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;
}
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| {
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),
};
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(),
pub inner: ItemEnum,
pub visibility: Option<Visibility>,
pub def_id: ast::DefId,
+ pub stability: Option<Stability>,
}
impl Item {
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,
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,
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,
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,
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(),
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,
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(),
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();
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(),
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 => {
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,
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();
};
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,
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())),
}
} 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())),
}
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(),
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(),
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(),
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([]) => {
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
};
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,
}
}
}
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(),
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(),
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(),
source: self.span.clean(),
def_id: ast_util::local_def(0),
visibility: self.vis.clean(),
+ stability: None,
inner: ViewItemItem(ViewItem { inner: node.clean() }),
}
};
source: self.span.clean(),
def_id: ast_util::local_def(self.id),
visibility: self.vis.clean(),
+ stability: None,
inner: inner,
}
}
/// 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.
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 }
}
}
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)]
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(),
}
}
}
+
+#[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()),
+ }
+ }
+}