Skip to content

rustdoc: add stability dashboard #15586

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 2 commits into from
Jul 11, 2014
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
4 changes: 4 additions & 0 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,10 @@ fn encode_info_for_struct(ecx: &EncodeContext,
encode_name(ebml_w, nm);
encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
encode_def_id(ebml_w, local_def(id));

let stab = stability::lookup(ecx.tcx, field.id);
encode_stability(ebml_w, stab);

ebml_w.end_tag();
}
index
Expand Down
12 changes: 9 additions & 3 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
use util::nodemap::{NodeMap, DefIdMap};
use syntax::codemap::Span;
use syntax::{attr, visit};
use syntax::ast;
use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
use syntax::ast::{Item, Required, Provided, TraitMethod, TypeMethod, Method};
use syntax::ast::{Generics, StructDef, Ident};
use syntax::ast::{Generics, StructDef, StructField, Ident};
use syntax::ast_util::is_local;
use syntax::attr::Stability;
use syntax::visit::{FnKind, FkMethod, Visitor};
Expand Down Expand Up @@ -91,6 +92,11 @@ impl Visitor<Option<Stability>> for Annotator {
s.ctor_id.map(|id| self.annotate(id, &[], parent.clone()));
visit::walk_struct_def(self, s, parent)
}

fn visit_struct_field(&mut self, s: &StructField, parent: Option<Stability>) {
let stab = self.annotate(s.node.id, s.node.attrs.as_slice(), parent);
visit::walk_struct_field(self, s, stab)
}
}

impl Index {
Expand All @@ -102,8 +108,8 @@ impl Index {
extern_cache: DefIdMap::new()
}
};
visit::walk_crate(&mut annotator, krate,
attr::find_stability(krate.attrs.as_slice()));
let stab = annotator.annotate(ast::CRATE_NODE_ID, krate.attrs.as_slice(), None);
visit::walk_crate(&mut annotator, krate, stab);
annotator.index
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1461,12 +1461,15 @@ 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
// uses this so we should be good for now.
// for the whole variant. Thus we read the
// stability from the whole variant as well.
// Struct variants are experimental and need
// more infrastructure work before we can get
// at the needed information here.
def_id: self.id,
stability: get_stability(self.id),
inner: StructFieldItem(
TypedStructField(ty.clean())
)
Expand All @@ -1482,7 +1485,7 @@ impl Clean<Item> for ty::VariantInfo {
visibility: Some(ast::Public),
def_id: self.id,
inner: VariantItem(Variant { kind: kind }),
stability: None,
stability: get_stability(self.id),
}
}
}
Expand Down Expand Up @@ -1890,7 +1893,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,
stability: get_stability(ast_util::local_def(self.id)),
inner: inner,
}
}
Expand Down
70 changes: 70 additions & 0 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use syntax::ast;
use syntax::ast_util;

use clean;
use stability_summary::ModuleSummary;
use html::item_type;
use html::item_type::ItemType;
use html::render;
Expand Down Expand Up @@ -631,3 +632,72 @@ impl<'a> fmt::Show for ConciseStability<'a> {
}
}
}

impl fmt::Show for ModuleSummary {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt_inner<'a>(f: &mut fmt::Formatter,
context: &mut Vec<&'a str>,
m: &'a ModuleSummary)
-> fmt::Result {
let cnt = m.counts;
let tot = cnt.total();
if tot == 0 { return Ok(()) }

context.push(m.name.as_slice());
let path = context.connect("::");

// the total width of each row's stability summary, in pixels
let width = 500;

try!(write!(f, "<tr>"));
try!(write!(f, "<td class='summary'>\
<a class='summary' href='{}'>{}</a></td>",
Vec::from_slice(context.slice_from(1))
.append_one("index.html").connect("/"),
path));
try!(write!(f, "<td>"));
try!(write!(f, "<span class='summary Stable' \
style='width: {}px; display: inline-block'>&nbsp</span>",
(width * cnt.stable)/tot));
try!(write!(f, "<span class='summary Unstable' \
style='width: {}px; display: inline-block'>&nbsp</span>",
(width * cnt.unstable)/tot));
try!(write!(f, "<span class='summary Experimental' \
style='width: {}px; display: inline-block'>&nbsp</span>",
(width * cnt.experimental)/tot));
try!(write!(f, "<span class='summary Deprecated' \
style='width: {}px; display: inline-block'>&nbsp</span>",
(width * cnt.deprecated)/tot));
try!(write!(f, "<span class='summary Unmarked' \
style='width: {}px; display: inline-block'>&nbsp</span>",
(width * cnt.unmarked)/tot));
try!(write!(f, "</td></tr>"));

for submodule in m.submodules.iter() {
try!(fmt_inner(f, context, submodule));
}
context.pop();
Ok(())
}

let mut context = Vec::new();

try!(write!(f,
r"<h1 class='fqn'>Stability dashboard: crate <a class='mod' href='index.html'>{}</a></h1>
This dashboard summarizes the stability levels for all of the public modules of
the crate, according to the total number of items at each level in the module and its children:
<blockquote>
<a class='stability Stable'></a> stable,<br/>
<a class='stability Unstable'></a> unstable,<br/>
<a class='stability Experimental'></a> experimental,<br/>
<a class='stability Deprecated'></a> deprecated,<br/>
<a class='stability Unmarked'></a> unmarked
</blockquote>
The counts do not include methods or trait
implementations that are visible only through a re-exported type.",
self.name));
try!(write!(f, "<table>"))
try!(fmt_inner(f, &mut context, self));
write!(f, "</table>")
}
}
56 changes: 51 additions & 5 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ use std::sync::Arc;

use externalfiles::ExternalHtml;

use serialize::json;
use serialize::Encodable;
use serialize::json::ToJson;
use syntax::ast;
use syntax::ast_util;
Expand All @@ -59,6 +61,7 @@ use html::item_type;
use html::layout;
use html::markdown::Markdown;
use html::markdown;
use stability_summary;

/// Major driving force in all rustdoc rendering. This contains information
/// about where in the tree-like hierarchy rendering is occurring and controls
Expand Down Expand Up @@ -249,6 +252,11 @@ pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) ->

try!(mkdir(&cx.dst));

// Crawl the crate, building a summary of the stability levels. NOTE: this
// summary *must* be computed with the original `krate`; the folding below
// removes the impls from their modules.
let summary = stability_summary::build(&krate);

// Crawl the crate attributes looking for attributes which control how we're
// going to emit HTML
match krate.module.as_ref().map(|m| m.doc_list().unwrap_or(&[])) {
Expand Down Expand Up @@ -361,7 +369,7 @@ pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) ->
let krate = try!(render_sources(&mut cx, krate));

// And finally render the whole crate's documentation
cx.krate(krate)
cx.krate(krate, summary)
}

fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult<String> {
Expand Down Expand Up @@ -1045,13 +1053,34 @@ impl Context {
///
/// This currently isn't parallelized, but it'd be pretty easy to add
/// parallelization to this function.
fn krate(self, mut krate: clean::Crate) -> io::IoResult<()> {
fn krate(mut self, mut krate: clean::Crate,
stability: stability_summary::ModuleSummary) -> io::IoResult<()> {
let mut item = match krate.module.take() {
Some(i) => i,
None => return Ok(())
};
item.name = Some(krate.name);

// render stability dashboard
try!(self.recurse(stability.name.clone(), |this| {
let json_dst = &this.dst.join("stability.json");
let mut json_out = BufferedWriter::new(try!(File::create(json_dst)));
try!(stability.encode(&mut json::Encoder::new(&mut json_out)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this json file loaded anywhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The information is also written as a json file, intended for consumption by pages like http://huonw.github.io/isrustfastyet/

Ah.


let title = stability.name.clone().append(" - Stability dashboard");
let page = layout::Page {
ty: "mod",
root_path: this.root_path.as_slice(),
title: title.as_slice(),
};
let html_dst = &this.dst.join("stability.html");
let mut html_out = BufferedWriter::new(try!(File::create(html_dst)));
layout::render(&mut html_out, &this.layout, &page,
&Sidebar{ cx: this, item: &item },
&stability)
}));

// render the crate documentation
let mut work = vec!((self, item));
loop {
match work.pop() {
Expand All @@ -1061,6 +1090,7 @@ impl Context {
None => break,
}
}

Ok(())
}

Expand Down Expand Up @@ -1233,6 +1263,8 @@ impl<'a> Item<'a> {
}
}



impl<'a> fmt::Show for Item<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
// Write the breadcrumb trail header for the top
Expand Down Expand Up @@ -1269,6 +1301,17 @@ impl<'a> fmt::Show for Item<'a> {
// Write stability level
try!(write!(fmt, "{}", Stability(&self.item.stability)));

// Links to out-of-band information, i.e. src and stability dashboard
try!(write!(fmt, "<span class='out-of-band'>"));

// Write stability dashboard link
match self.item.inner {
clean::ModuleItem(ref m) if m.is_crate => {
try!(write!(fmt, "<a href='stability.html'>[stability dashboard]</a> "));
}
_ => {}
};

// Write `src` tag
//
// When this item is part of a `pub use` in a downstream crate, the
Expand All @@ -1278,14 +1321,15 @@ impl<'a> fmt::Show for Item<'a> {
if self.cx.include_sources && !is_primitive {
match self.href() {
Some(l) => {
try!(write!(fmt,
"<a class='source' id='src-{}' \
href='{}'>[src]</a>",
try!(write!(fmt, "<a id='src-{}' href='{}'>[src]</a>",
self.item.def_id.node, l));
}
None => {}
}
}

try!(write!(fmt, "</span>"));

try!(write!(fmt, "</h1>\n"));

match self.item.inner {
Expand Down Expand Up @@ -1355,6 +1399,7 @@ fn document(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
fn item_module(w: &mut fmt::Formatter, cx: &Context,
item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
try!(document(w, item));

let mut indices = range(0, items.len()).filter(|i| {
!ignore_private_item(&items[*i])
}).collect::<Vec<uint>>();
Expand Down Expand Up @@ -1514,6 +1559,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
}
}
}

write!(w, "</table>")
}

Expand Down
11 changes: 10 additions & 1 deletion src/librustdoc/html/static/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ nav.sub {
.docblock h2 { font-size: 1.15em; }
.docblock h3, .docblock h4, .docblock h5 { font-size: 1em; }

.content .source {
.content .out-of-band {
float: right;
font-size: 23px;
}
Expand Down Expand Up @@ -409,6 +409,15 @@ h1 .stability {
.stability.Locked { border-color: #0084B6; color: #00668c; }
.stability.Unmarked { border-color: #FFFFFF; }

.summary {
padding-right: 0px;
}
.summary.Deprecated { background-color: #A071A8; }
.summary.Experimental { background-color: #D46D6A; }
.summary.Unstable { background-color: #D4B16A; }
.summary.Stable { background-color: #54A759; }
.summary.Unmarked { background-color: #FFFFFF; }

:target { background: #FDFFD3; }

/* Code highlighting */
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub mod html {
pub mod markdown;
pub mod passes;
pub mod plugins;
pub mod stability_summary;
pub mod visit_ast;
pub mod test;
mod flock;
Expand Down
Loading