From 62267470f630c6bf8553feb65d5c130e6890ba70 Mon Sep 17 00:00:00 2001
From: mitaa
Date: Sat, 27 Feb 2016 07:35:05 +0100
Subject: [PATCH 1/6] Refactor src-link creation for local sources
Since we emit the sources beforhand we actually **know** whether we
can safely create src-links to these files and where they are stored.
---
src/librustdoc/html/render.rs | 73 +++++++++++++++--------------------
1 file changed, 32 insertions(+), 41 deletions(-)
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index af6dec8dc8688..c9c9f1968133e 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -104,6 +104,8 @@ pub struct Context {
/// the source files are present in the html rendering, then this will be
/// `true`.
pub include_sources: bool,
+ /// The local file sources we've emitted and their respective url-paths.
+ pub local_sources: HashMap,
/// A flag, which when turned off, will render pages which redirect to the
/// real location of an item. This is used to allow external links to
/// publicly reused items to redirect to the right location.
@@ -262,8 +264,6 @@ pub struct Cache {
struct SourceCollector<'a> {
cx: &'a mut Context,
- /// Processed source-file paths
- seen: HashSet,
/// Root destination to place all HTML output into
dst: PathBuf,
}
@@ -423,6 +423,7 @@ pub fn run(mut krate: clean::Crate,
playground_url: "".to_string(),
},
include_sources: true,
+ local_sources: HashMap::new(),
render_redirect_pages: false,
issue_tracker_base_url: None,
};
@@ -770,11 +771,8 @@ fn render_sources(cx: &mut Context,
try_err!(mkdir(&dst), &dst);
let mut folder = SourceCollector {
dst: dst,
- seen: HashSet::new(),
cx: cx,
};
- // skip all invalid spans
- folder.seen.insert("".to_string());
Ok(folder.fold_crate(krate))
}
@@ -866,7 +864,13 @@ impl<'a> DocFolder for SourceCollector<'a> {
fn fold_item(&mut self, item: clean::Item) -> Option {
// If we're including source files, and we haven't seen this file yet,
// then we need to render it out to the filesystem
- if self.cx.include_sources && !self.seen.contains(&item.source.filename) {
+ if self.cx.include_sources
+ // skip all invalid spans
+ && item.source.filename != ""
+ // macros from other libraries get special filenames which we can
+ // safely ignore
+ && !(item.source.filename.starts_with("<")
+ && item.source.filename.ends_with("macros>")) {
// If it turns out that we couldn't read this file, then we probably
// can't read any of the files (generating html output from json or
@@ -884,7 +888,6 @@ impl<'a> DocFolder for SourceCollector<'a> {
false
}
};
- self.seen.insert(item.source.filename.clone());
}
self.fold_item_recur(item)
@@ -895,19 +898,14 @@ impl<'a> SourceCollector<'a> {
/// Renders the given filename into its corresponding HTML source file.
fn emit_source(&mut self, filename: &str) -> io::Result<()> {
let p = PathBuf::from(filename);
+ if self.cx.local_sources.contains_key(&p) {
+ // We've already emitted this source
+ return Ok(());
+ }
- // If we couldn't open this file, then just returns because it
- // probably means that it's some standard library macro thing and we
- // can't have the source to it anyway.
let mut contents = Vec::new();
- match File::open(&p).and_then(|mut f| f.read_to_end(&mut contents)) {
- Ok(r) => r,
- // macros from other libraries get special filenames which we can
- // safely ignore
- Err(..) if filename.starts_with("<") &&
- filename.ends_with("macros>") => return Ok(()),
- Err(e) => return Err(e)
- };
+ try!(File::open(&p).and_then(|mut f| f.read_to_end(&mut contents)));
+
let contents = str::from_utf8(&contents).unwrap();
// Remove the utf-8 BOM if any
@@ -920,16 +918,20 @@ impl<'a> SourceCollector<'a> {
// Create the intermediate directories
let mut cur = self.dst.clone();
let mut root_path = String::from("../../");
+ let mut href = String::new();
clean_srcpath(&self.cx.src_root, &p, false, |component| {
cur.push(component);
mkdir(&cur).unwrap();
root_path.push_str("../");
+ href.push_str(component);
+ href.push('/');
});
-
let mut fname = p.file_name().expect("source has no filename")
.to_os_string();
fname.push(".html");
cur.push(&fname[..]);
+ href.push_str(&fname.to_string_lossy());
+
let mut w = BufWriter::new(try!(File::create(&cur)));
let title = format!("{} -- source", cur.file_name().unwrap()
.to_string_lossy());
@@ -944,7 +946,8 @@ impl<'a> SourceCollector<'a> {
try!(layout::render(&mut w, &self.cx.layout,
&page, &(""), &Source(contents)));
try!(w.flush());
- return Ok(());
+ self.cx.local_sources.insert(p, href);
+ Ok(())
}
}
@@ -1459,7 +1462,7 @@ impl<'a> Item<'a> {
/// If `None` is returned, then a source link couldn't be generated. This
/// may happen, for example, with externally inlined items where the source
/// of their crate documentation isn't known.
- fn href(&self, cx: &Context) -> Option {
+ fn href(&self) -> Option {
let href = if self.item.source.loline == self.item.source.hiline {
format!("{}", self.item.source.loline)
} else {
@@ -1492,25 +1495,13 @@ impl<'a> Item<'a> {
// know the span, so we plow forward and generate a proper url. The url
// has anchors for the line numbers that we're linking to.
} else if self.item.def_id.is_local() {
- let mut path = Vec::new();
- clean_srcpath(&cx.src_root, Path::new(&self.item.source.filename),
- true, |component| {
- path.push(component.to_string());
- });
-
- // If the span points into an external macro the
- // source-file will be bogus, i.e ``
- let filename = &self.item.source.filename;
- if !(filename.starts_with("<") && filename.ends_with("macros>")) {
- Some(format!("{root}src/{krate}/{path}.html#{href}",
- root = self.cx.root_path,
- krate = self.cx.layout.krate,
- path = path.join("/"),
- href = href))
- } else {
- None
- }
-
+ self.cx.local_sources.get(&PathBuf::from(&self.item.source.filename)).map(|path| {
+ format!("{root}src/{krate}/{path}.html#{href}",
+ root = self.cx.root_path,
+ krate = self.cx.layout.krate,
+ path = path,
+ href = href)
+ })
// If this item is not part of the local crate, then things get a little
// trickier. We don't actually know the span of the external item, but
// we know that the documentation on the other end knows the span!
@@ -1590,7 +1581,7 @@ impl<'a> fmt::Display for Item<'a> {
// this page, and this link will be auto-clicked. The `id` attribute is
// used to find the link to auto-click.
if self.cx.include_sources && !is_primitive {
- match self.href(self.cx) {
+ match self.href() {
Some(l) => {
try!(write!(fmt, "[src] ",
From 8f6e09a956d65dbd81bb5ea12791208aed322704 Mon Sep 17 00:00:00 2001
From: mitaa
Date: Sun, 28 Feb 2016 12:11:13 +0100
Subject: [PATCH 2/6] Simplify `if let`/`match` expressions
---
src/librustdoc/clean/inline.rs | 25 +--
src/librustdoc/clean/mod.rs | 83 ++++-----
src/librustdoc/fold.rs | 1 +
src/librustdoc/html/render.rs | 306 +++++++++++++++------------------
src/librustdoc/lib.rs | 55 ++----
src/librustdoc/passes.rs | 33 ++--
src/librustdoc/test.rs | 21 +--
src/librustdoc/visit_ast.rs | 6 +-
8 files changed, 211 insertions(+), 319 deletions(-)
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 02ea83615a372..6fd80feaac747 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -138,13 +138,10 @@ pub fn load_attrs(cx: &DocContext, tcx: &TyCtxt,
/// These names are used later on by HTML rendering to generate things like
/// source links back to the original item.
pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
- match cx.tcx_opt() {
- Some(tcx) => {
- let fqn = tcx.sess.cstore.extern_item_path(did);
- let fqn = fqn.into_iter().map(|i| i.to_string()).collect();
- cx.external_paths.borrow_mut().as_mut().unwrap().insert(did, (fqn, kind));
- }
- None => {}
+ if let Some(tcx) = cx.tcx_opt() {
+ let fqn = tcx.sess.cstore.extern_item_path(did);
+ let fqn = fqn.into_iter().map(|i| i.to_string()).collect();
+ cx.external_paths.borrow_mut().as_mut().unwrap().insert(did, (fqn, kind));
}
}
@@ -230,12 +227,9 @@ pub fn build_impls(cx: &DocContext, tcx: &TyCtxt,
tcx.populate_inherent_implementations_for_type_if_necessary(did);
let mut impls = Vec::new();
- match tcx.inherent_impls.borrow().get(&did) {
- None => {}
- Some(i) => {
- for &did in i.iter() {
- build_impl(cx, tcx, did, &mut impls);
- }
+ if let Some(i) = tcx.inherent_impls.borrow().get(&did) {
+ for &did in i.iter() {
+ build_impl(cx, tcx, did, &mut impls);
}
}
@@ -464,9 +458,8 @@ fn build_module(cx: &DocContext, tcx: &TyCtxt,
}
cstore::DlDef(def) if item.vis == hir::Public => {
if !visited.insert(def) { continue }
- match try_inline_def(cx, tcx, def) {
- Some(i) => items.extend(i),
- None => {}
+ if let Some(i) = try_inline_def(cx, tcx, def) {
+ items.extend(i)
}
}
cstore::DlDef(..) => {}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index b6da5b0ef20e8..96a56a7c113f3 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -100,10 +100,7 @@ impl, U> Clean for Rc {
impl, U> Clean> for Option {
fn clean(&self, cx: &DocContext) -> Option {
- match self {
- &None => None,
- &Some(ref v) => Some(v.clean(cx))
- }
+ self.as_ref().map(|v| v.clean(cx))
}
}
@@ -332,27 +329,20 @@ impl Item {
}
pub fn stability_class(&self) -> String {
- match self.stability {
- Some(ref s) => {
- let mut base = match s.level {
- stability::Unstable => "unstable".to_string(),
- stability::Stable => String::new(),
- };
- if !s.deprecated_since.is_empty() {
- base.push_str(" deprecated");
- }
- base
+ self.stability.as_ref().map(|ref s| {
+ let mut base = match s.level {
+ stability::Unstable => "unstable".to_string(),
+ stability::Stable => String::new(),
+ };
+ if !s.deprecated_since.is_empty() {
+ base.push_str(" deprecated");
}
- _ => String::new(),
- }
+ base
+ }).unwrap_or(String::new())
}
pub fn stable_since(&self) -> Option<&str> {
- if let Some(ref s) = self.stability {
- return Some(&s.since[..]);
- }
-
- None
+ self.stability.as_ref().map(|s| &s.since[..])
}
}
@@ -711,7 +701,7 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> {
if let &ty::Region::ReLateBound(_, _) = *reg {
debug!(" hit an ReLateBound {:?}", reg);
if let Some(lt) = reg.clean(cx) {
- late_bounds.push(lt)
+ late_bounds.push(lt);
}
}
}
@@ -780,8 +770,7 @@ impl Clean> for ty::Region {
fn clean(&self, cx: &DocContext) -> Option {
match *self {
ty::ReStatic => Some(Lifetime::statik()),
- ty::ReLateBound(_, ty::BrNamed(_, name)) =>
- Some(Lifetime(name.to_string())),
+ ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name.to_string())),
ty::ReEarlyBound(ref data) => Some(Lifetime(data.name.clean(cx))),
ty::ReLateBound(..) |
@@ -1151,12 +1140,12 @@ impl<'tcx> Clean for ty::FnOutput<'tcx> {
impl<'a, 'tcx> Clean for (DefId, &'a ty::PolyFnSig<'tcx>) {
fn clean(&self, cx: &DocContext) -> FnDecl {
let (did, sig) = *self;
- let mut names = if let Some(_) = cx.map.as_local_node_id(did) {
+ let mut names = if cx.map.as_local_node_id(did).is_some() {
vec![].into_iter()
} else {
cx.tcx().sess.cstore.method_arg_names(did).into_iter()
}.peekable();
- if names.peek().map(|s| &**s) == Some("self") {
+ if let Some("self") = names.peek().map(|s| &s[..]) {
let _ = names.next();
}
FnDecl {
@@ -1627,15 +1616,9 @@ impl Clean for hir::Ty {
}
}
TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
- TyPolyTraitRef(ref bounds) => {
- PolyTraitRef(bounds.clean(cx))
- },
- TyInfer => {
- Infer
- },
- TyTypeof(..) => {
- panic!("Unimplemented type {:?}", self.node)
- },
+ TyPolyTraitRef(ref bounds) => PolyTraitRef(bounds.clean(cx)),
+ TyInfer => Infer,
+ TyTypeof(..) => panic!("Unimplemented type {:?}", self.node),
}
}
}
@@ -2253,7 +2236,7 @@ impl Clean> for doctree::Impl {
polarity: Some(self.polarity.clean(cx)),
}),
});
- return ret;
+ ret
}
}
@@ -2393,9 +2376,8 @@ impl Clean> for doctree::Import {
}
hir::ViewPathSimple(name, ref p) => {
if !denied {
- match inline::try_inline(cx, self.id, Some(name)) {
- Some(items) => return items,
- None => {}
+ if let Some(items) = inline::try_inline(cx, self.id, Some(name)) {
+ return items;
}
}
(vec![], SimpleImport(name.clean(cx),
@@ -2460,9 +2442,8 @@ impl Clean> for hir::ForeignMod {
fn clean(&self, cx: &DocContext) -> Vec- {
let mut items = self.items.clean(cx);
for item in &mut items {
- match item.inner {
- ForeignFunctionItem(ref mut f) => f.abi = self.abi,
- _ => {}
+ if let ForeignFunctionItem(ref mut f) = item.inner {
+ f.abi = self.abi;
}
}
items
@@ -2598,11 +2579,7 @@ fn resolve_type(cx: &DocContext,
};
}
};
- let def = match tcx.def_map.borrow().get(&id) {
- Some(k) => k.full_def(),
- None => panic!("unresolved id not in defmap")
- };
-
+ let def = tcx.def_map.borrow().get(&id).expect("unresolved id not in defmap").full_def();
debug!("resolve_type: def={:?}", def);
let is_generic = match def {
@@ -2659,7 +2636,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId {
let t = inline::build_external_trait(cx, tcx, did);
cx.external_traits.borrow_mut().as_mut().unwrap().insert(did, t);
}
- return did;
+ did
}
fn resolve_use_source(cx: &DocContext, path: Path, id: ast::NodeId) -> ImportSource {
@@ -2732,12 +2709,10 @@ impl Clean
for attr::Stability {
_=> "".to_string(),
},
reason: {
- if let Some(ref depr) = self.rustc_depr {
- depr.reason.to_string()
- } else if let attr::Unstable {reason: Some(ref reason), ..} = self.level {
- reason.to_string()
- } else {
- "".to_string()
+ match (&self.rustc_depr, &self.level) {
+ (&Some(ref depr), _) => depr.reason.to_string(),
+ (&None, &attr::Unstable {reason: Some(ref reason), ..}) => reason.to_string(),
+ _ => "".to_string(),
}
},
issue: match self.level {
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 5a4f95d1a1a5a..afe1387ad9fe6 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -81,6 +81,7 @@ pub trait DocFolder : Sized {
c.module = match replace(&mut c.module, None) {
Some(module) => self.fold_item(module), None => None
};
+
let external_traits = replace(&mut c.external_traits, HashMap::new());
c.external_traits = external_traits.into_iter().map(|(k, mut v)| {
let items = replace(&mut v.items, Vec::new());
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c9c9f1968133e..319c9d7d18560 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -433,41 +433,38 @@ pub fn run(mut krate: clean::Crate,
// Crawl the crate attributes looking for attributes which control how we're
// going to emit HTML
let default: &[_] = &[];
- match krate.module.as_ref().map(|m| m.doc_list().unwrap_or(default)) {
- Some(attrs) => {
- for attr in attrs {
- match *attr {
- clean::NameValue(ref x, ref s)
- if "html_favicon_url" == *x => {
- cx.layout.favicon = s.to_string();
- }
- clean::NameValue(ref x, ref s)
- if "html_logo_url" == *x => {
- cx.layout.logo = s.to_string();
- }
- clean::NameValue(ref x, ref s)
- if "html_playground_url" == *x => {
- cx.layout.playground_url = s.to_string();
- markdown::PLAYGROUND_KRATE.with(|slot| {
- if slot.borrow().is_none() {
- let name = krate.name.clone();
- *slot.borrow_mut() = Some(Some(name));
- }
- });
- }
- clean::NameValue(ref x, ref s)
- if "issue_tracker_base_url" == *x => {
- cx.issue_tracker_base_url = Some(s.to_string());
- }
- clean::Word(ref x)
- if "html_no_source" == *x => {
- cx.include_sources = false;
- }
- _ => {}
+ if let Some(attrs) = krate.module.as_ref().map(|m| m.doc_list().unwrap_or(default)) {
+ for attr in attrs {
+ match *attr {
+ clean::NameValue(ref x, ref s)
+ if "html_favicon_url" == *x => {
+ cx.layout.favicon = s.to_string();
+ }
+ clean::NameValue(ref x, ref s)
+ if "html_logo_url" == *x => {
+ cx.layout.logo = s.to_string();
+ }
+ clean::NameValue(ref x, ref s)
+ if "html_playground_url" == *x => {
+ cx.layout.playground_url = s.to_string();
+ markdown::PLAYGROUND_KRATE.with(|slot| {
+ if slot.borrow().is_none() {
+ let name = krate.name.clone();
+ *slot.borrow_mut() = Some(Some(name));
+ }
+ });
+ }
+ clean::NameValue(ref x, ref s)
+ if "issue_tracker_base_url" == *x => {
+ cx.issue_tracker_base_url = Some(s.to_string());
+ }
+ clean::Word(ref x)
+ if "html_no_source" == *x => {
+ cx.include_sources = false;
}
+ _ => {}
}
}
- None => {}
}
// Crawl the crate to build various caches used for the output
@@ -986,15 +983,12 @@ impl DocFolder for Cache {
// Collect all the implementors of traits.
if let clean::ImplItem(ref i) = item.inner {
- match i.trait_ {
- Some(clean::ResolvedPath{ did, .. }) => {
- self.implementors.entry(did).or_insert(vec![]).push(Implementor {
- def_id: item.def_id,
- stability: item.stability.clone(),
- impl_: i.clone(),
- });
- }
- Some(..) | None => {}
+ if let Some(clean::ResolvedPath{ did, .. }) = i.trait_ {
+ self.implementors.entry(did).or_insert(vec![]).push(Implementor {
+ def_id: item.def_id,
+ stability: item.stability.clone(),
+ impl_: i.clone(),
+ });
}
}
@@ -1054,6 +1048,9 @@ impl DocFolder for Cache {
}
});
+ // A crate has a module at its root, containing all items,
+ // which should not be indexed. The crate-item itself is
+ // inserted later on when serializing the search-index.
if item.def_id.index != CRATE_DEF_INDEX {
self.search_index.push(IndexItem {
ty: shortty(&item),
@@ -1078,13 +1075,14 @@ impl DocFolder for Cache {
}
// Keep track of the fully qualified path for this item.
- let pushed = if item.name.is_some() {
- let n = item.name.as_ref().unwrap();
- if !n.is_empty() {
+ let pushed = match item.name {
+ Some(ref n) if !n.is_empty() => {
self.stack.push(n.to_string());
true
- } else { false }
- } else { false };
+ }
+ _ => false,
+ };
+
match item.inner {
clean::StructItem(..) | clean::EnumItem(..) |
clean::TypedefItem(..) | clean::TraitItem(..) |
@@ -1153,60 +1151,53 @@ impl DocFolder for Cache {
// Once we've recursively found all the generics, then hoard off all the
// implementations elsewhere
- let ret = match self.fold_item_recur(item) {
- Some(item) => {
- match item {
- clean::Item{ attrs, inner: clean::ImplItem(i), .. } => {
- // extract relevant documentation for this impl
- let dox = match attrs.into_iter().find(|a| {
- match *a {
- clean::NameValue(ref x, _)
- if "doc" == *x => {
- true
- }
- _ => false
- }
- }) {
- Some(clean::NameValue(_, dox)) => Some(dox),
- Some(..) | None => None,
- };
-
- // Figure out the id of this impl. This may map to a
- // primitive rather than always to a struct/enum.
- let did = match i.for_ {
- clean::ResolvedPath { did, .. } |
- clean::BorrowedRef {
- type_: box clean::ResolvedPath { did, .. }, ..
- } => {
- Some(did)
- }
-
- ref t => {
- t.primitive_type().and_then(|t| {
- self.primitive_locations.get(&t).map(|n| {
- let id = t.to_def_index();
- DefId { krate: *n, index: id }
- })
- })
- }
- };
-
- if let Some(did) = did {
- self.impls.entry(did).or_insert(vec![]).push(Impl {
- impl_: i,
- dox: dox,
- stability: item.stability.clone(),
- });
+ let ret = self.fold_item_recur(item).and_then(|item| {
+ if let clean::Item { attrs, inner: clean::ImplItem(i), .. } = item {
+ // extract relevant documentation for this impl
+ let dox = match attrs.into_iter().find(|a| {
+ match *a {
+ clean::NameValue(ref x, _)
+ if "doc" == *x => {
+ true
}
+ _ => false
+ }
+ }) {
+ Some(clean::NameValue(_, dox)) => Some(dox),
+ Some(..) | None => None,
+ };
+ // Figure out the id of this impl. This may map to a
+ // primitive rather than always to a struct/enum.
+ let did = match i.for_ {
+ clean::ResolvedPath { did, .. } |
+ clean::BorrowedRef {
+ type_: box clean::ResolvedPath { did, .. }, ..
+ } => {
+ Some(did)
+ }
- None
+ ref t => {
+ t.primitive_type().and_then(|t| {
+ self.primitive_locations.get(&t).map(|n| {
+ let id = t.to_def_index();
+ DefId { krate: *n, index: id }
+ })
+ })
}
+ };
- i => Some(i),
+ if let Some(did) = did {
+ self.impls.entry(did).or_insert(vec![]).push(Impl {
+ impl_: i,
+ dox: dox,
+ stability: item.stability.clone(),
+ });
}
+ None
+ } else {
+ Some(item)
}
- i => i,
- };
+ });
if pushed { self.stack.pop().unwrap(); }
if parent_pushed { self.parent_stack.pop().unwrap(); }
@@ -1581,13 +1572,10 @@ impl<'a> fmt::Display for Item<'a> {
// this page, and this link will be auto-clicked. The `id` attribute is
// used to find the link to auto-click.
if self.cx.include_sources && !is_primitive {
- match self.href() {
- Some(l) => {
- try!(write!(fmt, "[src] ",
- self.item.def_id.index.as_usize(), l, "goto source code"));
- }
- None => {}
+ if let Some(l) = self.href() {
+ try!(write!(fmt, "[src] ",
+ self.item.def_id.index.as_usize(), l, "goto source code"));
}
}
@@ -1801,7 +1789,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
}
fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Option {
- let mut result = item.stability.as_ref().and_then(|stab| {
+ item.stability.as_ref().and_then(|stab| {
let reason = if show_reason && !stab.reason.is_empty() {
format!(": {}", stab.reason)
} else {
@@ -1836,10 +1824,8 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Optio
};
Some(format!("{} ",
item.stability_class(), text))
- });
-
- if result.is_none() {
- result = item.deprecation.as_ref().and_then(|depr| {
+ }).or_else(|| {
+ item.deprecation.as_ref().and_then(|depr| {
let note = if show_reason && !depr.note.is_empty() {
format!(": {}", depr.note)
} else {
@@ -1853,10 +1839,8 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Optio
let text = format!("Deprecated{}{}", since, Markdown(¬e));
Some(format!("{} ", text))
- });
- }
-
- result
+ })
+ })
}
struct Initializer<'a>(&'a str);
@@ -2108,17 +2092,12 @@ fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
fn render_stability_since_raw<'a>(w: &mut fmt::Formatter,
ver: Option<&'a str>,
containing_ver: Option<&'a str>) -> fmt::Result {
- if containing_ver != ver {
- match ver {
- Some(v) =>
- if v.len() > 0 {
- try!(write!(w, "{} ",
- v))
- },
- None => {}
+ if let Some(v) = ver {
+ if containing_ver != ver && v.len() > 0 {
+ try!(write!(w, "{} ",
+ v))
}
}
-
Ok(())
}
@@ -2289,43 +2268,33 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
try!(write!(w, "{name}
",
name = variant.name.as_ref().unwrap()));
try!(document(w, cx, variant));
- match variant.inner {
- clean::VariantItem(ref var) => {
- match var.kind {
- clean::StructVariant(ref s) => {
- let fields = s.fields.iter().filter(|f| {
- match f.inner {
- clean::StructFieldItem(ref t) => match *t {
- clean::HiddenStructField => false,
- clean::TypedStructField(..) => true,
- },
- _ => false,
- }
- });
- try!(write!(w, "Fields \n
- "));
- for field in fields {
- try!(write!(w, "\
- {f}
",
- v = variant.name.as_ref().unwrap(),
- f = field.name.as_ref().unwrap()));
- try!(document(w, cx, field));
- try!(write!(w, " "));
- }
- try!(write!(w, "
"));
- }
- _ => ()
+
+ use clean::{Variant, StructVariant};
+ if let clean::VariantItem( Variant { kind: StructVariant(ref s) } ) = variant.inner {
+ let fields = s.fields.iter().filter(|f| {
+ match f.inner {
+ clean::StructFieldItem(clean::TypedStructField(..)) => true,
+ _ => false,
}
+ });
+ try!(write!(w, "Fields \n
+ "));
+ for field in fields {
+ try!(write!(w, "\
+ {f}
",
+ v = variant.name.as_ref().unwrap(),
+ f = field.name.as_ref().unwrap()));
+ try!(document(w, cx, field));
+ try!(write!(w, " "));
}
- _ => ()
+ try!(write!(w, "
"));
}
try!(write!(w, " "));
try!(render_stability_since(w, variant, it));
try!(write!(w, " "));
}
try!(write!(w, ""));
-
}
try!(render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All));
Ok(())
@@ -2356,9 +2325,8 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
VisSpace(it.visibility),
if structhead {"struct "} else {""},
it.name.as_ref().unwrap()));
- match g {
- Some(g) => try!(write!(w, "{}{}", *g, WhereClause(g))),
- None => {}
+ if let Some(g) = g {
+ try!(write!(w, "{}{}", *g, WhereClause(g)))
}
match ty {
doctree::Plain => {
@@ -2452,7 +2420,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
}
}
if let AssocItemRender::DerefFor { .. } = what {
- return Ok(())
+ return Ok(());
}
if !traits.is_empty() {
let deref_impl = traits.iter().find(|t| {
@@ -2533,10 +2501,17 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
link: AssocItemLink, render_static: bool,
outer_version: Option<&str>) -> fmt::Result {
let name = item.name.as_ref().unwrap();
+
+ let is_static = match item.inner {
+ clean::MethodItem(ref method) => method.self_ == SelfTy::SelfStatic,
+ clean::TyMethodItem(ref method) => method.self_ == SelfTy::SelfStatic,
+ _ => false
+ };
+
match item.inner {
clean::MethodItem(..) | clean::TyMethodItem(..) => {
// Only render when the method is not static or we allow static methods
- if !is_static_method(item) || render_static {
+ if !is_static || render_static {
let id = derive_id(format!("method.{}", name));
try!(write!(w, "", id, shortty(item)));
try!(render_stability_since_raw(w, item.stable_since(), outer_version));
@@ -2572,22 +2547,11 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
_ => panic!("can't make docs for trait item with name {:?}", item.name)
}
- return if let AssocItemLink::Anchor = link {
- if is_static_method(item) && !render_static {
- Ok(())
- } else {
+ match link {
+ AssocItemLink::Anchor if !is_static || render_static => {
document(w, cx, item)
- }
- } else {
- Ok(())
- };
-
- fn is_static_method(item: &clean::Item) -> bool {
- match item.inner {
- clean::MethodItem(ref method) => method.self_ == SelfTy::SelfStatic,
- clean::TyMethodItem(ref method) => method.self_ == SelfTy::SelfStatic,
- _ => false
- }
+ },
+ _ => Ok(()),
}
}
@@ -2605,9 +2569,8 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
outer_version: Option<&str>) -> fmt::Result {
for trait_item in &t.items {
let n = trait_item.name.clone();
- match i.items.iter().find(|m| { m.name == n }) {
- Some(..) => continue,
- None => {}
+ if i.items.iter().find(|m| { m.name == n }).is_some() {
+ continue;
}
try!(doctraititem(w, cx, trait_item, AssocItemLink::GotoSource(did), render_static,
@@ -2623,7 +2586,6 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
if let Some(clean::ResolvedPath { did, .. }) = i.impl_.trait_ {
if let Some(t) = cache().traits.get(&did) {
try!(render_default_items(w, cx, did, t, &i.impl_, render_header, outer_version));
-
}
}
try!(write!(w, ""));
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index ffb15d157b066..53003c5ee52ad 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -283,19 +283,15 @@ pub fn main_args(args: &[String]) -> isize {
info!("going to format");
match matches.opt_str("w").as_ref().map(|s| &**s) {
Some("html") | None => {
- match html::render::run(krate, &external_html,
- output.unwrap_or(PathBuf::from("doc")),
- passes.into_iter().collect()) {
- Ok(()) => {}
- Err(e) => panic!("failed to generate documentation: {}", e),
- }
+ html::render::run(krate, &external_html,
+ output.unwrap_or(PathBuf::from("doc")),
+ passes.into_iter().collect())
+ .expect("failed to generate documentation")
}
Some("json") => {
- match json_output(krate, json_plugins,
- output.unwrap_or(PathBuf::from("doc.json"))) {
- Ok(()) => {}
- Err(e) => panic!("failed to write json: {}", e),
- }
+ json_output(krate, json_plugins,
+ output.unwrap_or(PathBuf::from("doc.json")))
+ .expect("failed to write json")
}
Some(s) => {
println!("unknown output format: {}", s);
@@ -332,18 +328,10 @@ fn parse_externs(matches: &getopts::Matches) -> Result {
let mut externs = HashMap::new();
for arg in &matches.opt_strs("extern") {
let mut parts = arg.splitn(2, '=');
- let name = match parts.next() {
- Some(s) => s,
- None => {
- return Err("--extern value must not be empty".to_string());
- }
- };
- let location = match parts.next() {
- Some(s) => s,
- None => {
- return Err("--extern value must be of the format `foo=bar`".to_string());
- }
- };
+ let name = try!(parts.next().ok_or("--extern value must not be empty".to_string()));
+ let location = try!(parts.next()
+ .ok_or("--extern value must be of the format `foo=bar`"
+ .to_string()));
let name = name.to_string();
externs.entry(name).or_insert(vec![]).push(location.to_string());
}
@@ -448,17 +436,16 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
// Run everything!
info!("Executing passes/plugins");
let (krate, json) = pm.run_plugins(krate);
- return Output { krate: krate, json_plugins: json, passes: passes, };
+ Output { krate: krate, json_plugins: json, passes: passes }
}
/// This input format purely deserializes the json output file. No passes are
/// run over the deserialized output.
fn json_input(input: &str) -> Result {
let mut bytes = Vec::new();
- match File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) {
- Ok(_) => {}
- Err(e) => return Err(format!("couldn't open {}: {}", input, e)),
- };
+ if let Err(e) = File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) {
+ return Err(format!("couldn't open {}: {}", input, e))
+ }
match json::from_reader(&mut &bytes[..]) {
Err(s) => Err(format!("{:?}", s)),
Ok(Json::Object(obj)) => {
@@ -507,21 +494,13 @@ fn json_output(krate: clean::Crate, res: Vec ,
json.insert("schema".to_string(), Json::String(SCHEMA_VERSION.to_string()));
let plugins_json = res.into_iter()
.filter_map(|opt| {
- match opt {
- None => None,
- Some((string, json)) => {
- Some((string.to_string(), json))
- }
- }
+ opt.map(|(string, json)| (string.to_string(), json))
}).collect();
// FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
// straight to the Rust JSON representation.
let crate_json_str = format!("{}", json::as_json(&krate));
- let crate_json = match json::from_str(&crate_json_str) {
- Ok(j) => j,
- Err(e) => panic!("Rust generated JSON is invalid: {:?}", e)
- };
+ let crate_json = json::from_str(&crate_json_str).expect("Rust generated JSON is invalid");
json.insert("crate".to_string(), crate_json);
json.insert("plugins".to_string(), Json::Object(plugins_json));
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index 957957eaec6e5..46e801631bf5b 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -205,22 +205,19 @@ impl<'a> fold::DocFolder for Stripper<'a> {
self.fold_item_recur(i)
};
- match i {
- Some(i) => {
- match i.inner {
- // emptied modules/impls have no need to exist
- clean::ModuleItem(ref m)
- if m.items.is_empty() &&
- i.doc_value().is_none() => None,
- clean::ImplItem(ref i) if i.items.is_empty() => None,
- _ => {
- self.retained.insert(i.def_id);
- Some(i)
- }
+ i.and_then(|i| {
+ match i.inner {
+ // emptied modules/impls have no need to exist
+ clean::ModuleItem(ref m)
+ if m.items.is_empty() &&
+ i.doc_value().is_none() => None,
+ clean::ImplItem(ref i) if i.items.is_empty() => None,
+ _ => {
+ self.retained.insert(i.def_id);
+ Some(i)
}
}
- None => None,
- }
+ })
}
}
@@ -275,13 +272,11 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
let mut docstr = String::new();
let mut i = i;
for attr in &i.attrs {
- match *attr {
- clean::NameValue(ref x, ref s)
- if "doc" == *x => {
+ if let clean::NameValue(ref x, ref s) = *attr {
+ if "doc" == *x {
docstr.push_str(s);
docstr.push('\n');
- },
- _ => ()
+ }
}
}
let mut a: Vec = i.attrs.iter().filter(|&a| match a {
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 39550488a9e87..e97357f98898b 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -121,9 +121,8 @@ pub fn run(input: &str,
let mut v = RustdocVisitor::new(&ctx, None);
v.visit(ctx.map.krate());
let mut krate = v.clean(&ctx);
- match crate_name {
- Some(name) => krate.name = name,
- None => {}
+ if let Some(name) = crate_name {
+ krate.name = name;
}
let (krate, _) = passes::collapse_docs(krate);
let (krate, _) = passes::unindent_comments(krate);
@@ -334,13 +333,10 @@ pub fn maketest(s: &str, cratename: Option<&str>, dont_insert_main: bool,
// Don't inject `extern crate std` because it's already injected by the
// compiler.
if !s.contains("extern crate") && !opts.no_crate_inject && cratename != Some("std") {
- match cratename {
- Some(cratename) => {
- if s.contains(cratename) {
- prog.push_str(&format!("extern crate {};\n", cratename));
- }
+ if let Some(cratename) = cratename {
+ if s.contains(cratename) {
+ prog.push_str(&format!("extern crate {};\n", cratename));
}
- None => {}
}
}
if dont_insert_main || s.contains("fn main") {
@@ -476,12 +472,7 @@ impl DocFolder for Collector {
_ => typename_if_impl(&item)
};
- let pushed = if let Some(name) = current_name {
- self.names.push(name);
- true
- } else {
- false
- };
+ let pushed = current_name.map(|name| self.names.push(name)).is_some();
if let Some(doc) = item.doc_value() {
self.cnt = 0;
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ba389bc42b78c..bc6b4f83984b0 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -263,13 +263,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let name = renamed.unwrap_or(item.name);
match item.node {
hir::ItemExternCrate(ref p) => {
- let path = match *p {
- None => None,
- Some(x) => Some(x.to_string()),
- };
om.extern_crates.push(ExternCrate {
name: name,
- path: path,
+ path: p.map(|x|x.to_string()),
vis: item.vis,
attrs: item.attrs.clone(),
whence: item.span,
From 2a28b69948e13ec09a8a7701fa4d9001e880ad5f Mon Sep 17 00:00:00 2001
From: mitaa
Date: Sun, 28 Feb 2016 10:12:41 +0100
Subject: [PATCH 3/6] Refactor rustdocs attribute handling
---
src/librustdoc/clean/inline.rs | 20 +-----
src/librustdoc/clean/mod.rs | 111 ++++++++++++++++-----------------
src/librustdoc/html/render.rs | 47 +++-----------
src/librustdoc/lib.rs | 39 +++++-------
src/librustdoc/passes.rs | 4 +-
5 files changed, 85 insertions(+), 136 deletions(-)
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 6fd80feaac747..32f3706675ad2 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -26,7 +26,7 @@ use rustc::middle::const_eval;
use core::DocContext;
use doctree;
-use clean;
+use clean::{self, Attributes};
use super::{Clean, ToSource};
@@ -253,7 +253,7 @@ pub fn build_impls(cx: &DocContext, tcx: &TyCtxt,
cstore::DlImpl(did) => build_impl(cx, tcx, did, impls),
cstore::DlDef(Def::Mod(did)) => {
// Don't recurse if this is a #[doc(hidden)] module
- if load_attrs(cx, tcx, did).iter().any(|a| is_doc_hidden(a)) {
+ if load_attrs(cx, tcx, did).list_def("doc").has_word("hidden") {
return;
}
@@ -282,7 +282,7 @@ pub fn build_impl(cx: &DocContext,
if let Some(ref t) = associated_trait {
// 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)) {
+ if trait_attrs.list_def("doc").has_word("hidden") {
return
}
}
@@ -422,20 +422,6 @@ pub fn build_impl(cx: &DocContext,
});
}
-fn is_doc_hidden(a: &clean::Attribute) -> bool {
- match *a {
- clean::List(ref name, ref inner) if *name == "doc" => {
- inner.iter().any(|a| {
- match *a {
- clean::Word(ref s) => *s == "hidden",
- _ => false,
- }
- })
- }
- _ => false
- }
-}
-
fn build_module(cx: &DocContext, tcx: &TyCtxt,
did: DefId) -> clean::Module {
let mut items = Vec::new();
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 96a56a7c113f3..20bcf759cf7c4 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -258,7 +258,7 @@ pub struct Item {
pub source: Span,
/// Not everything has a name. E.g., impls
pub name: Option,
- pub attrs: Vec ,
+ pub attrs: Vec,
pub inner: ItemEnum,
pub visibility: Option,
pub def_id: DefId,
@@ -267,49 +267,10 @@ pub struct Item {
}
impl Item {
- /// Finds the `doc` attribute as a List and returns the list of attributes
- /// nested inside.
- pub fn doc_list<'a>(&'a self) -> Option<&'a [Attribute]> {
- for attr in &self.attrs {
- match *attr {
- List(ref x, ref list) if "doc" == *x => {
- return Some(list);
- }
- _ => {}
- }
- }
- return None;
- }
-
/// Finds the `doc` attribute as a NameValue and returns the corresponding
/// value found.
pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
- for attr in &self.attrs {
- match *attr {
- NameValue(ref x, ref v) if "doc" == *x => {
- return Some(v);
- }
- _ => {}
- }
- }
- return None;
- }
-
- pub fn is_hidden_from_doc(&self) -> bool {
- match self.doc_list() {
- Some(l) => {
- for innerattr in l {
- match *innerattr {
- Word(ref s) if "hidden" == *s => {
- return true
- }
- _ => (),
- }
- }
- },
- None => ()
- }
- return false;
+ self.attrs.value("doc")
}
pub fn is_mod(&self) -> bool {
@@ -438,10 +399,54 @@ impl Clean- for doctree::Module {
}
}
+pub trait Attributes {
+ fn has_word(&self, &str) -> bool;
+ fn value<'a>(&'a self, &str) -> Option<&'a str>;
+ fn list_def<'a>(&'a self, &str) -> &'a [Attribute];
+}
+
+impl Attributes for [Attribute] {
+ /// Returns whether the attribute list contains a specific `Word`
+ fn has_word(&self, word: &str) -> bool {
+ for attr in self {
+ if let Word(ref w) = *attr {
+ if word == *w {
+ return true;
+ }
+ }
+ }
+ false
+ }
+
+ /// Finds an attribute as NameValue and returns the corresponding value found.
+ fn value<'a>(&'a self, name: &str) -> Option<&'a str> {
+ for attr in self {
+ if let NameValue(ref x, ref v) = *attr {
+ if name == *x {
+ return Some(v);
+ }
+ }
+ }
+ None
+ }
+
+ /// Finds an attribute as List and returns the list of attributes nested inside.
+ fn list_def<'a>(&'a self, name: &str) -> &'a [Attribute] {
+ for attr in self {
+ if let List(ref x, ref list) = *attr {
+ if name == *x {
+ return &list[..];
+ }
+ }
+ }
+ &[]
+ }
+}
+
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
pub enum Attribute {
Word(String),
- List(String, Vec
),
+ List(String, Vec),
NameValue(String, String)
}
@@ -1513,24 +1518,16 @@ impl PrimitiveType {
}
fn find(attrs: &[Attribute]) -> Option {
- for attr in attrs {
- let list = match *attr {
- List(ref k, ref l) if *k == "doc" => l,
- _ => continue,
- };
- for sub_attr in list {
- let value = match *sub_attr {
- NameValue(ref k, ref v)
- if *k == "primitive" => v,
- _ => continue,
- };
- match PrimitiveType::from_str(value) {
- Some(p) => return Some(p),
- None => {}
+ for attr in attrs.list_def("doc") {
+ if let NameValue(ref k, ref v) = *attr {
+ if "primitive" == *k {
+ if let ret@Some(..) = PrimitiveType::from_str(v) {
+ return ret;
+ }
}
}
}
- return None
+ None
}
pub fn to_string(&self) -> &'static str {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 319c9d7d18560..f1d8369007983 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -62,7 +62,7 @@ use rustc::middle::stability;
use rustc::session::config::get_unstable_features_setting;
use rustc_front::hir;
-use clean::{self, SelfTy};
+use clean::{self, SelfTy, Attributes};
use doctree;
use fold::DocFolder;
use html::escape::Escape;
@@ -432,8 +432,7 @@ pub fn run(mut krate: clean::Crate,
// Crawl the crate attributes looking for attributes which control how we're
// going to emit HTML
- let default: &[_] = &[];
- if let Some(attrs) = krate.module.as_ref().map(|m| m.doc_list().unwrap_or(default)) {
+ if let Some(attrs) = krate.module.as_ref().map(|m| m.attrs.list_def("doc")) {
for attr in attrs {
match *attr {
clean::NameValue(ref x, ref s)
@@ -833,28 +832,13 @@ fn extern_location(e: &clean::ExternalCrate, dst: &Path) -> ExternalLocation {
// Failing that, see if there's an attribute specifying where to find this
// external crate
- for attr in &e.attrs {
- match *attr {
- clean::List(ref x, ref list) if "doc" == *x => {
- for attr in list {
- match *attr {
- clean::NameValue(ref x, ref s)
- if "html_root_url" == *x => {
- if s.ends_with("/") {
- return Remote(s.to_string());
- }
- return Remote(format!("{}/", s));
- }
- _ => {}
- }
- }
- }
- _ => {}
+ e.attrs.list_def("doc").value("html_root_url").map(|url| {
+ let mut url = url.to_owned();
+ if !url.ends_with("/") {
+ url.push('/')
}
- }
-
- // Well, at least we tried.
- return Unknown;
+ Remote(url)
+ }).unwrap_or(Unknown) // Well, at least we tried.
}
impl<'a> DocFolder for SourceCollector<'a> {
@@ -1153,19 +1137,6 @@ impl DocFolder for Cache {
// implementations elsewhere
let ret = self.fold_item_recur(item).and_then(|item| {
if let clean::Item { attrs, inner: clean::ImplItem(i), .. } = item {
- // extract relevant documentation for this impl
- let dox = match attrs.into_iter().find(|a| {
- match *a {
- clean::NameValue(ref x, _)
- if "doc" == *x => {
- true
- }
- _ => false
- }
- }) {
- Some(clean::NameValue(_, dox)) => Some(dox),
- Some(..) | None => None,
- };
// Figure out the id of this impl. This may map to a
// primitive rather than always to a struct/enum.
let did = match i.for_ {
@@ -1189,7 +1160,7 @@ impl DocFolder for Cache {
if let Some(did) = did {
self.impls.entry(did).or_insert(vec![]).push(Impl {
impl_: i,
- dox: dox,
+ dox: attrs.value("doc").map(|s|s.to_owned()),
stability: item.stability.clone(),
});
}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 53003c5ee52ad..3c7aadb3533c4 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -94,6 +94,8 @@ pub mod visit_ast;
pub mod test;
mod flock;
+use clean::Attributes;
+
type Pass = (&'static str, // name
fn(clean::Crate) -> plugins::PluginResult, // fn
&'static str); // description
@@ -379,32 +381,25 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
// Process all of the crate attributes, extracting plugin metadata along
// with the passes which we are supposed to run.
- match krate.module.as_ref().unwrap().doc_list() {
- Some(nested) => {
- for inner in nested {
- match *inner {
- clean::Word(ref x)
- if "no_default_passes" == *x => {
- default_passes = false;
- }
- clean::NameValue(ref x, ref value)
- if "passes" == *x => {
- for pass in value.split_whitespace() {
- passes.push(pass.to_string());
- }
- }
- clean::NameValue(ref x, ref value)
- if "plugins" == *x => {
- for p in value.split_whitespace() {
- plugins.push(p.to_string());
- }
- }
- _ => {}
+ for attr in krate.module.as_ref().unwrap().attrs.list_def("doc") {
+ match *attr {
+ clean::Word(ref w) if "no_default_passes" == *w => {
+ default_passes = false;
+ },
+ clean::NameValue(ref name, ref value) => {
+ let sink = match &name[..] {
+ "passes" => &mut passes,
+ "plugins" => &mut plugins,
+ _ => continue,
+ };
+ for p in value.split_whitespace() {
+ sink.push(p.to_string());
}
}
+ _ => (),
}
- None => {}
}
+
if default_passes {
for name in DEFAULT_PASSES.iter().rev() {
passes.insert(0, name.to_string());
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index 46e801631bf5b..6293aa3c2725c 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -16,7 +16,7 @@ use std::string::String;
use std::usize;
use rustc_front::hir;
-use clean;
+use clean::{self, Attributes};
use clean::Item;
use plugins;
use fold;
@@ -33,7 +33,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
}
impl<'a> fold::DocFolder for Stripper<'a> {
fn fold_item(&mut self, i: Item) -> Option- {
- if i.is_hidden_from_doc() {
+ if i.attrs.list_def("doc").has_word("hidden") {
debug!("found one in strip_hidden; removing");
self.stripped.insert(i.def_id);
From 032156210deaf71fddc4f8577fa2b541606ed547 Mon Sep 17 00:00:00 2001
From: mitaa
Date: Sun, 28 Feb 2016 12:23:07 +0100
Subject: [PATCH 4/6] Use `Item::is_*` methods consistently
---
src/librustdoc/clean/mod.rs | 24 ++++++++++++++++++++----
src/librustdoc/html/render.rs | 24 ++++++------------------
2 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 20bcf759cf7c4..c2a37a555d693 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -175,9 +175,8 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> {
};
let mut tmp = Vec::new();
for child in &mut m.items {
- match child.inner {
- ModuleItem(..) => {}
- _ => continue,
+ if !child.is_mod() {
+ continue;
}
let prim = match PrimitiveType::find(&child.attrs) {
Some(prim) => prim,
@@ -272,7 +271,12 @@ impl Item {
pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
self.attrs.value("doc")
}
-
+ pub fn is_crate(&self) -> bool {
+ match self.inner {
+ ModuleItem(Module { items: _, is_crate: true }) => true,
+ _ => false
+ }
+ }
pub fn is_mod(&self) -> bool {
match self.inner { ModuleItem(..) => true, _ => false }
}
@@ -288,6 +292,18 @@ impl Item {
pub fn is_fn(&self) -> bool {
match self.inner { FunctionItem(..) => true, _ => false }
}
+ pub fn is_associated_type(&self) -> bool {
+ match self.inner { AssociatedTypeItem(..) => true, _ => false }
+ }
+ pub fn is_associated_const(&self) -> bool {
+ match self.inner { AssociatedConstItem(..) => true, _ => false }
+ }
+ pub fn is_method(&self) -> bool {
+ match self.inner { MethodItem(..) => true, _ => false }
+ }
+ pub fn is_ty_method(&self) -> bool {
+ match self.inner { TyMethodItem(..) => true, _ => false }
+ }
pub fn stability_class(&self) -> String {
self.stability.as_ref().map(|ref s| {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index f1d8369007983..88f21b67a5ac6 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1266,11 +1266,7 @@ impl Context {
}
title.push_str(" - Rust");
let tyname = shortty(it).to_static_str();
- let is_crate = match it.inner {
- clean::ModuleItem(clean::Module { items: _, is_crate: true }) => true,
- _ => false
- };
- let desc = if is_crate {
+ let desc = if it.is_crate() {
format!("API documentation for the Rust `{}` crate.",
cx.layout.krate)
} else {
@@ -1891,18 +1887,10 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
bounds,
WhereClause(&t.generics)));
- let types = t.items.iter().filter(|m| {
- match m.inner { clean::AssociatedTypeItem(..) => true, _ => false }
- }).collect::>();
- let consts = t.items.iter().filter(|m| {
- match m.inner { clean::AssociatedConstItem(..) => true, _ => false }
- }).collect::>();
- let required = t.items.iter().filter(|m| {
- match m.inner { clean::TyMethodItem(_) => true, _ => false }
- }).collect::>();
- let provided = t.items.iter().filter(|m| {
- match m.inner { clean::MethodItem(_) => true, _ => false }
- }).collect::>();
+ let types = t.items.iter().filter(|m| m.is_associated_type()).collect::>();
+ let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>();
+ let required = t.items.iter().filter(|m| m.is_ty_method()).collect::>();
+ let provided = t.items.iter().filter(|m| m.is_method()).collect::>();
if t.items.is_empty() {
try!(write!(w, "{{ }}"));
@@ -2600,7 +2588,7 @@ impl<'a> fmt::Display for Sidebar<'a> {
try!(write!(fmt, "
"));
// sidebar refers to the enclosing module, not this module
- let relpath = if shortty(it) == ItemType::Module { "../" } else { "" };
+ let relpath = if it.is_mod() { "../" } else { "" };
try!(write!(fmt,
"