rustdoc: incorporate stability index throughout

This commit hooks rustdoc into the stability index infrastructure in two
ways:

1. It looks up stability levels via the index, rather than by manual
attributes.

2. It adds stability level information throughout rustdoc output, rather
than just at the top header. In particular, a stability color (with
mouseover text) appears next to essentially every item that appears
in rustdoc's HTML output.

Along the way, the stability index code has been lightly refactored.
This commit is contained in:
Aaron Turon 2014-06-26 11:37:39 -07:00
parent 5cef1243a2
commit 256df5e3df
12 changed files with 284 additions and 174 deletions

View file

@ -30,7 +30,7 @@ use middle::def::*;
use middle::trans::adt; // for `adt::is_ffi_safe`
use middle::typeck::astconv::ast_ty_to_ty;
use middle::typeck::infer;
use middle::{typeck, ty, def, pat_util};
use middle::{typeck, ty, def, pat_util, stability};
use util::ppaux::{ty_to_str};
use util::nodemap::NodeSet;
use lint::{Context, LintPass, LintArray};
@ -1426,11 +1426,7 @@ impl LintPass for Stability {
Some(method) => {
match method.origin {
typeck::MethodStatic(def_id) => {
// If this implements a trait method, get def_id
// of the method inside trait definition.
// Otherwise, use the current def_id (which refers
// to the method inside impl).
ty::trait_method_of_method(cx.tcx, def_id).unwrap_or(def_id)
def_id
}
typeck::MethodParam(typeck::MethodParam {
trait_id: trait_id,
@ -1454,8 +1450,7 @@ impl LintPass for Stability {
// check anything for crate-local usage.
if ast_util::is_local(id) { return }
let stability = cx.tcx.stability.borrow_mut().lookup(&cx.tcx.sess.cstore, id);
let stability = stability::lookup(cx.tcx, id);
let (lint, label) = match stability {
// no stability attributes == Unstable
None => (UNSTABLE, "unmarked"),

View file

@ -24,6 +24,7 @@ use middle::ty::{node_id_to_type, lookup_item_type};
use middle::astencode;
use middle::ty;
use middle::typeck;
use middle::stability;
use middle;
use util::nodemap::{NodeMap, NodeSet};
@ -328,7 +329,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
encode_visibility(ebml_w, variant.node.vis);
encode_attributes(ebml_w, variant.node.attrs.as_slice());
let stab = ecx.tcx.stability.borrow().lookup_local(variant.node.id);
let stab = stability::lookup(ecx.tcx, ast_util::local_def(variant.node.id));
encode_stability(ebml_w, stab);
match variant.node.kind {
@ -592,7 +593,9 @@ fn encode_info_for_mod(ecx: &EncodeContext,
encode_path(ebml_w, path.clone());
encode_visibility(ebml_w, vis);
encode_stability(ebml_w, ecx.tcx.stability.borrow().lookup_local(id));
let stab = stability::lookup(ecx.tcx, ast_util::local_def(id));
encode_stability(ebml_w, stab);
// Encode the reexports of this module, if this module is public.
if vis == Public {
@ -722,7 +725,8 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
encode_symbol(ecx, ebml_w, ctor_id);
}
encode_stability(ebml_w, ecx.tcx.stability.borrow().lookup_local(ctor_id));
let stab = stability::lookup(ecx.tcx, ast_util::local_def(ctor_id));
encode_stability(ebml_w, stab);
// indicate that this is a tuple struct ctor, because downstream users will normally want
// the tuple struct definition, but without this there is no way for them to tell that
@ -768,7 +772,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
encode_method_ty_fields(ecx, ebml_w, m);
encode_parent_item(ebml_w, local_def(parent_id));
let stab = ecx.tcx.stability.borrow().lookup_local(m.def_id.node);
let stab = stability::lookup(ecx.tcx, m.def_id);
encode_stability(ebml_w, stab);
// The type for methods gets encoded twice, which is unfortunate.
@ -915,10 +919,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
}
debug!("encoding info for item at {}",
ecx.tcx.sess.codemap().span_to_str(item.span));
tcx.sess.codemap().span_to_str(item.span));
let def_id = local_def(item.id);
let stab = tcx.stability.borrow().lookup_local(item.id);
let stab = stability::lookup(tcx, ast_util::local_def(item.id));
match item.node {
ItemStatic(_, m, _) => {
@ -1206,7 +1210,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_method_ty_fields(ecx, ebml_w, &*method_ty);
encode_parent_item(ebml_w, def_id);
let stab = tcx.stability.borrow().lookup_local(method_def_id.node);
let stab = stability::lookup(tcx, method_def_id);
encode_stability(ebml_w, stab);
let elem = ast_map::PathName(method_ty.ident.name);

View file

@ -20,7 +20,8 @@ use syntax::ast::{Generics, StructDef, Ident};
use syntax::ast_util::is_local;
use syntax::attr::Stability;
use syntax::visit::{FnKind, FkMethod, Visitor};
use metadata::{cstore, csearch};
use middle::ty;
use metadata::csearch;
/// A stability index, giving the stability level for items and methods.
pub struct Index {
@ -105,21 +106,24 @@ impl Index {
attr::find_stability(krate.attrs.as_slice()));
annotator.index
}
}
/// Lookup the stability for a node, loading external crate
/// metadata as necessary.
pub fn lookup(&mut self, cstore: &cstore::CStore, id: DefId) -> Option<Stability> {
if is_local(id) {
self.lookup_local(id.node)
} else {
let stab = csearch::get_stability(cstore, id);
self.extern_cache.insert(id, stab.clone());
/// Lookup the stability for a node, loading external crate
/// metadata as necessary.
pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
// is this definition the implementation of a trait method?
match ty::trait_method_of_method(tcx, id) {
Some(trait_method_id) if trait_method_id != id => {
lookup(tcx, trait_method_id)
}
_ if is_local(id) => {
tcx.stability.borrow().local.find_copy(&id.node)
}
_ => {
let stab = csearch::get_stability(&tcx.sess.cstore, id);
let mut index = tcx.stability.borrow_mut();
(*index).extern_cache.insert(id, stab.clone());
stab
}
}
/// Lookup the stability for a local node without loading any external crates
pub fn lookup_local(&self, id: NodeId) -> Option<Stability> {
self.local.find_copy(&id)
}
}