Skip to content

Commit c4afcf4

Browse files
committed
auto merge of #12339 : alexcrichton/rust/rustdoc-fixes, r=sfackler
Commits have the details
2 parents 9f68f79 + 429ef87 commit c4afcf4

File tree

11 files changed

+314
-43
lines changed

11 files changed

+314
-43
lines changed

src/librustdoc/clean.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use rustc::metadata::csearch;
2525
use rustc::metadata::decoder;
2626

2727
use std;
28-
use std::hashmap::HashMap;
2928

3029
use doctree;
3130
use visit_ast;
@@ -68,17 +67,17 @@ impl<T: Clean<U>, U> Clean<~[U]> for syntax::opt_vec::OptVec<T> {
6867
pub struct Crate {
6968
name: ~str,
7069
module: Option<Item>,
71-
externs: HashMap<ast::CrateNum, ExternalCrate>,
70+
externs: ~[(ast::CrateNum, ExternalCrate)],
7271
}
7372

7473
impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
7574
fn clean(&self) -> Crate {
7675
use syntax::attr::find_crateid;
7776
let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
7877

79-
let mut externs = HashMap::new();
78+
let mut externs = ~[];
8079
cx.sess.cstore.iter_crate_data(|n, meta| {
81-
externs.insert(n, meta.clean());
80+
externs.push((n, meta.clean()));
8281
});
8382

8483
Crate {
@@ -181,6 +180,7 @@ pub enum ItemEnum {
181180
VariantItem(Variant),
182181
ForeignFunctionItem(Function),
183182
ForeignStaticItem(Static),
183+
MacroItem(Macro),
184184
}
185185

186186
#[deriving(Clone, Encodable, Decodable)]
@@ -206,7 +206,8 @@ impl Clean<Item> for doctree::Module {
206206
self.fns.clean(), self.foreigns.clean().concat_vec(),
207207
self.mods.clean(), self.typedefs.clean(),
208208
self.statics.clean(), self.traits.clean(),
209-
self.impls.clean(), self.view_items.clean()].concat_vec()
209+
self.impls.clean(), self.view_items.clean(),
210+
self.macros.clean()].concat_vec()
210211
})
211212
}
212213
}
@@ -1263,3 +1264,23 @@ fn resolve_def(id: ast::NodeId) -> Option<ast::DefId> {
12631264
None => None
12641265
}
12651266
}
1267+
1268+
#[deriving(Clone, Encodable, Decodable)]
1269+
pub struct Macro {
1270+
source: ~str,
1271+
}
1272+
1273+
impl Clean<Item> for doctree::Macro {
1274+
fn clean(&self) -> Item {
1275+
Item {
1276+
name: Some(self.name.clean()),
1277+
attrs: self.attrs.clean(),
1278+
source: self.where.clean(),
1279+
visibility: ast::Public.clean(),
1280+
id: self.id,
1281+
inner: MacroItem(Macro {
1282+
source: self.where.to_src(),
1283+
}),
1284+
}
1285+
}
1286+
}

src/librustdoc/doctree.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub struct Module {
3232
impls: ~[Impl],
3333
foreigns: ~[ast::ForeignMod],
3434
view_items: ~[ast::ViewItem],
35+
macros: ~[Macro],
3536
}
3637

3738
impl Module {
@@ -52,6 +53,7 @@ impl Module {
5253
impls : ~[],
5354
view_items : ~[],
5455
foreigns : ~[],
56+
macros : ~[],
5557
}
5658
}
5759
}
@@ -157,6 +159,13 @@ pub struct Impl {
157159
id: ast::NodeId,
158160
}
159161

162+
pub struct Macro {
163+
name: Ident,
164+
id: ast::NodeId,
165+
attrs: ~[ast::Attribute],
166+
where: Span,
167+
}
168+
160169
pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType {
161170
if sd.ctor_id.is_some() {
162171
// We are in a tuple-struct

src/librustdoc/html/render.rs

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ pub struct Cache {
157157
priv parent_stack: ~[ast::NodeId],
158158
priv search_index: ~[IndexItem],
159159
priv privmod: bool,
160+
priv public_items: HashSet<ast::NodeId>,
160161
}
161162

162163
/// Helper struct to render all source code to HTML pages
@@ -231,18 +232,23 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
231232
}
232233

233234
// Crawl the crate to build various caches used for the output
234-
let mut cache = Cache {
235-
impls: HashMap::new(),
236-
typarams: HashMap::new(),
237-
paths: HashMap::new(),
238-
traits: HashMap::new(),
239-
implementors: HashMap::new(),
240-
stack: ~[],
241-
parent_stack: ~[],
242-
search_index: ~[],
243-
extern_locations: HashMap::new(),
244-
privmod: false,
245-
};
235+
let mut cache = local_data::get(::analysiskey, |analysis| {
236+
let public_items = analysis.map(|a| a.public_items.clone());
237+
let public_items = public_items.unwrap_or(HashSet::new());
238+
Cache {
239+
impls: HashMap::new(),
240+
typarams: HashMap::new(),
241+
paths: HashMap::new(),
242+
traits: HashMap::new(),
243+
implementors: HashMap::new(),
244+
stack: ~[],
245+
parent_stack: ~[],
246+
search_index: ~[],
247+
extern_locations: HashMap::new(),
248+
privmod: false,
249+
public_items: public_items,
250+
}
251+
});
246252
cache.stack.push(krate.name.clone());
247253
krate = cache.fold_crate(krate);
248254

@@ -305,7 +311,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
305311
krate = folder.fold_crate(krate);
306312
}
307313

308-
for (&n, e) in krate.externs.iter() {
314+
for &(n, ref e) in krate.externs.iter() {
309315
cache.extern_locations.insert(n, extern_location(e, &cx.dst));
310316
}
311317

@@ -565,8 +571,24 @@ impl DocFolder for Cache {
565571
clean::StructItem(..) | clean::EnumItem(..) |
566572
clean::TypedefItem(..) | clean::TraitItem(..) |
567573
clean::FunctionItem(..) | clean::ModuleItem(..) |
568-
clean::ForeignFunctionItem(..) | clean::VariantItem(..) => {
569-
self.paths.insert(item.id, (self.stack.clone(), shortty(&item)));
574+
clean::ForeignFunctionItem(..) => {
575+
// Reexported items mean that the same id can show up twice in
576+
// the rustdoc ast that we're looking at. We know, however, that
577+
// a reexported item doesn't show up in the `public_items` map,
578+
// so we can skip inserting into the paths map if there was
579+
// already an entry present and we're not a public item.
580+
if !self.paths.contains_key(&item.id) ||
581+
self.public_items.contains(&item.id) {
582+
self.paths.insert(item.id,
583+
(self.stack.clone(), shortty(&item)));
584+
}
585+
}
586+
// link variants to their parent enum because pages aren't emitted
587+
// for each variant
588+
clean::VariantItem(..) => {
589+
let mut stack = self.stack.clone();
590+
stack.pop();
591+
self.paths.insert(item.id, (stack, "enum"));
570592
}
571593
_ => {}
572594
}
@@ -791,6 +813,7 @@ fn shortty(item: &clean::Item) -> &'static str {
791813
clean::VariantItem(..) => "variant",
792814
clean::ForeignFunctionItem(..) => "ffi",
793815
clean::ForeignStaticItem(..) => "ffs",
816+
clean::MacroItem(..) => "macro",
794817
}
795818
}
796819

@@ -869,6 +892,7 @@ impl<'a> fmt::Show for Item<'a> {
869892
clean::StructItem(ref s) => item_struct(fmt.buf, self.item, s),
870893
clean::EnumItem(ref e) => item_enum(fmt.buf, self.item, e),
871894
clean::TypedefItem(ref t) => item_typedef(fmt.buf, self.item, t),
895+
clean::MacroItem(ref m) => item_macro(fmt.buf, self.item, m),
872896
_ => Ok(())
873897
}
874898
}
@@ -937,6 +961,8 @@ fn item_module(w: &mut Writer, cx: &Context,
937961
(_, &clean::ViewItemItem(..)) => Greater,
938962
(&clean::ModuleItem(..), _) => Less,
939963
(_, &clean::ModuleItem(..)) => Greater,
964+
(&clean::MacroItem(..), _) => Less,
965+
(_, &clean::MacroItem(..)) => Greater,
940966
(&clean::StructItem(..), _) => Less,
941967
(_, &clean::StructItem(..)) => Greater,
942968
(&clean::EnumItem(..), _) => Less,
@@ -987,6 +1013,7 @@ fn item_module(w: &mut Writer, cx: &Context,
9871013
clean::VariantItem(..) => "Variants",
9881014
clean::ForeignFunctionItem(..) => "Foreign Functions",
9891015
clean::ForeignStaticItem(..) => "Foreign Statics",
1016+
clean::MacroItem(..) => "Macros",
9901017
}));
9911018
}
9921019

@@ -1099,15 +1126,15 @@ fn item_trait(w: &mut Writer, it: &clean::Item,
10991126
if_ok!(write!(w, "\\{\n"));
11001127
for m in required.iter() {
11011128
if_ok!(write!(w, " "));
1102-
if_ok!(render_method(w, m.item(), true));
1129+
if_ok!(render_method(w, m.item()));
11031130
if_ok!(write!(w, ";\n"));
11041131
}
11051132
if required.len() > 0 && provided.len() > 0 {
11061133
if_ok!(w.write("\n".as_bytes()));
11071134
}
11081135
for m in provided.iter() {
11091136
if_ok!(write!(w, " "));
1110-
if_ok!(render_method(w, m.item(), true));
1137+
if_ok!(render_method(w, m.item()));
11111138
if_ok!(write!(w, " \\{ ... \\}\n"));
11121139
}
11131140
if_ok!(write!(w, "\\}"));
@@ -1121,7 +1148,7 @@ fn item_trait(w: &mut Writer, it: &clean::Item,
11211148
if_ok!(write!(w, "<h3 id='{}.{}' class='method'><code>",
11221149
shortty(m.item()),
11231150
*m.item().name.get_ref()));
1124-
if_ok!(render_method(w, m.item(), false));
1151+
if_ok!(render_method(w, m.item()));
11251152
if_ok!(write!(w, "</code></h3>"));
11261153
if_ok!(document(w, m.item()));
11271154
Ok(())
@@ -1176,32 +1203,27 @@ fn item_trait(w: &mut Writer, it: &clean::Item,
11761203
})
11771204
}
11781205

1179-
fn render_method(w: &mut Writer, meth: &clean::Item,
1180-
withlink: bool) -> fmt::Result {
1206+
fn render_method(w: &mut Writer, meth: &clean::Item) -> fmt::Result {
11811207
fn fun(w: &mut Writer, it: &clean::Item, purity: ast::Purity,
1182-
g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl,
1183-
withlink: bool) -> fmt::Result {
1184-
write!(w, "{}fn {withlink, select,
1185-
true{<a href='\\#{ty}.{name}'
1186-
class='fnname'>{name}</a>}
1187-
other{<span class='fnname'>{name}</span>}
1188-
}{generics}{decl}",
1208+
g: &clean::Generics, selfty: &clean::SelfTy,
1209+
d: &clean::FnDecl) -> fmt::Result {
1210+
write!(w, "{}fn <a href='\\#{ty}.{name}' class='fnname'>{name}</a>\
1211+
{generics}{decl}",
11891212
match purity {
11901213
ast::UnsafeFn => "unsafe ",
11911214
_ => "",
11921215
},
11931216
ty = shortty(it),
11941217
name = it.name.get_ref().as_slice(),
11951218
generics = *g,
1196-
decl = Method(selfty, d),
1197-
withlink = if withlink {"true"} else {"false"})
1219+
decl = Method(selfty, d))
11981220
}
11991221
match meth.inner {
12001222
clean::TyMethodItem(ref m) => {
1201-
fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink)
1223+
fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl)
12021224
}
12031225
clean::MethodItem(ref m) => {
1204-
fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink)
1226+
fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl)
12051227
}
12061228
_ => unreachable!()
12071229
}
@@ -1432,7 +1454,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl,
14321454
fn docmeth(w: &mut Writer, item: &clean::Item) -> io::IoResult<bool> {
14331455
if_ok!(write!(w, "<h4 id='method.{}' class='method'><code>",
14341456
*item.name.get_ref()));
1435-
if_ok!(render_method(w, item, false));
1457+
if_ok!(render_method(w, item));
14361458
if_ok!(write!(w, "</code></h4>\n"));
14371459
match item.doc_value() {
14381460
Some(s) => {
@@ -1609,3 +1631,9 @@ impl<'a> fmt::Show for Source<'a> {
16091631
Ok(())
16101632
}
16111633
}
1634+
1635+
fn item_macro(w: &mut Writer, it: &clean::Item,
1636+
t: &clean::Macro) -> fmt::Result {
1637+
if_ok!(write!(w, "<pre class='macro'>{}</pre>", t.source));
1638+
document(w, it)
1639+
}

src/librustdoc/html/static/main.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,5 @@ a {
301301
.stability.Stable { border-color: #AEC516; color: #7c8b10; }
302302
.stability.Frozen { border-color: #009431; color: #007726; }
303303
.stability.Locked { border-color: #0084B6; color: #00668c; }
304+
305+
:target { background: #FDFFD3; }

src/librustdoc/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ fn json_output(krate: clean::Crate, res: ~[plugins::PluginJson],
344344
};
345345
let crate_json = match json::from_str(crate_json_str) {
346346
Ok(j) => j,
347-
Err(_) => fail!("Rust generated JSON is invalid??")
347+
Err(e) => fail!("Rust generated JSON is invalid: {:?}", e)
348348
};
349349

350350
json.insert(~"crate", crate_json);

src/librustdoc/passes.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ impl<'a> fold::DocFolder for Stripper<'a> {
150150
}
151151
clean::ImplItem(..) => {}
152152

153-
// tymethods have no control over privacy
154-
clean::TyMethodItem(..) => {}
153+
// tymethods/macros have no control over privacy
154+
clean::MacroItem(..) | clean::TyMethodItem(..) => {}
155155
}
156156

157157
let fastreturn = match i.inner {

src/librustdoc/visit_ast.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,14 @@ impl<'a> RustdocVisitor<'a> {
280280
ast::ItemForeignMod(ref fm) => {
281281
om.foreigns.push(fm.clone());
282282
}
283-
_ => (),
283+
ast::ItemMac(ref _m) => {
284+
om.macros.push(Macro {
285+
id: item.id,
286+
attrs: item.attrs.clone(),
287+
name: item.ident,
288+
where: item.span,
289+
})
290+
}
284291
}
285292
}
286293
}

src/libstd/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
#[cfg(test)] pub use ops = realstd::ops;
7878
#[cfg(test)] pub use cmp = realstd::cmp;
7979

80-
mod macros;
80+
pub mod macros;
8181

8282
mod rtdeps;
8383

0 commit comments

Comments
 (0)