From ab92ea526d455b402efbccc7160c8aec0237c88f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 28 Apr 2014 20:36:08 -0700 Subject: std: Modernize the local_data api This commit brings the local_data api up to modern rust standards with a few key improvements: * The `pop` and `set` methods have been combined into one method, `replace` * The `get_mut` method has been removed. All interior mutability should be done through `RefCell`. * All functionality is now exposed as a method on the keys themselves. Instead of importing std::local_data, you now use "key.replace()" and "key.get()". * All closures have been removed in favor of RAII functionality. This means that get() and get_mut() no long require closures, but rather return Option where the smart pointer takes care of relinquishing the borrow and also implements the necessary Deref traits * The modify() function was removed to cut the local_data interface down to its bare essentials (similarly to how RefCell removed set/get). [breaking-change] --- src/librustdoc/html/format.rs | 129 ++++++++++++++++----------------- src/librustdoc/html/markdown.rs | 23 +++--- src/librustdoc/html/render.rs | 154 +++++++++++++++++++--------------------- 3 files changed, 142 insertions(+), 164 deletions(-) (limited to 'src/librustdoc/html') diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1e2f89659cd..223f9341b73 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -17,7 +17,6 @@ use std::fmt; use std::io; -use std::local_data; use std::strbuf::StrBuf; use syntax::ast; @@ -206,78 +205,72 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool, generics.push_str(">"); } - // Did someone say rightward-drift? - local_data::get(current_location_key, |loc| { - let loc = loc.unwrap(); - - local_data::get(cache_key, |cache| { - let cache = cache.unwrap(); - let abs_root = root(&**cache, loc.as_slice()); - let rel_root = match path.segments.get(0).name.as_slice() { - "self" => Some("./".to_owned()), - _ => None, - }; - - if print_all { - let amt = path.segments.len() - 1; - match rel_root { - Some(root) => { - let mut root = StrBuf::from_str(root); - for seg in path.segments.slice_to(amt).iter() { - if "super" == seg.name || "self" == seg.name { - try!(write!(w, "{}::", seg.name)); - } else { - root.push_str(seg.name); - root.push_str("/"); - try!(write!(w, "{}::", - root.as_slice(), - seg.name)); - } - } - } - None => { - for seg in path.segments.slice_to(amt).iter() { - try!(write!(w, "{}::", seg.name)); - } + let loc = current_location_key.get().unwrap(); + let cache = cache_key.get().unwrap(); + let abs_root = root(&**cache, loc.as_slice()); + let rel_root = match path.segments.get(0).name.as_slice() { + "self" => Some("./".to_owned()), + _ => None, + }; + + if print_all { + let amt = path.segments.len() - 1; + match rel_root { + Some(root) => { + let mut root = StrBuf::from_str(root); + for seg in path.segments.slice_to(amt).iter() { + if "super" == seg.name || "self" == seg.name { + try!(write!(w, "{}::", seg.name)); + } else { + root.push_str(seg.name); + root.push_str("/"); + try!(write!(w, "{}::", + root.as_slice(), + seg.name)); } } } - - match info(&**cache) { - // This is a documented path, link to it! - Some((ref fqp, shortty)) if abs_root.is_some() => { - let mut url = StrBuf::from_str(abs_root.unwrap()); - let to_link = fqp.slice_to(fqp.len() - 1); - for component in to_link.iter() { - url.push_str(*component); - url.push_str("/"); - } - match shortty { - item_type::Module => { - url.push_str(*fqp.last().unwrap()); - url.push_str("/index.html"); - } - _ => { - url.push_str(shortty.to_static_str()); - url.push_str("."); - url.push_str(*fqp.last().unwrap()); - url.push_str(".html"); - } - } - - try!(write!(w, "{}", - shortty, url, fqp.connect("::"), last.name)); + None => { + for seg in path.segments.slice_to(amt).iter() { + try!(write!(w, "{}::", seg.name)); } + } + } + } + match info(&**cache) { + // This is a documented path, link to it! + Some((ref fqp, shortty)) if abs_root.is_some() => { + let mut url = StrBuf::from_str(abs_root.unwrap()); + let to_link = fqp.slice_to(fqp.len() - 1); + for component in to_link.iter() { + url.push_str(*component); + url.push_str("/"); + } + match shortty { + item_type::Module => { + url.push_str(*fqp.last().unwrap()); + url.push_str("/index.html"); + } _ => { - try!(write!(w, "{}", last.name)); + url.push_str(shortty.to_static_str()); + url.push_str("."); + url.push_str(*fqp.last().unwrap()); + url.push_str(".html"); } } - try!(write!(w, "{}", generics.as_slice())); - Ok(()) - }) - }) + + try!(write!(w, "{}", + shortty, url, fqp.connect("::"), last.name)); + } + + _ => { + try!(write!(w, "{}", last.name)); + } + } + try!(write!(w, "{}", generics.as_slice())); + Ok(()) } /// Helper to render type parameters @@ -302,10 +295,8 @@ impl fmt::Show for clean::Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::TyParamBinder(id) | clean::Generic(id) => { - local_data::get(cache_key, |cache| { - let m = cache.unwrap(); - f.buf.write(m.typarams.get(&id).as_bytes()) - }) + let m = cache_key.get().unwrap(); + f.buf.write(m.typarams.get(&id).as_bytes()) } clean::ResolvedPath{id, typarams: ref tp, path: ref path} => { try!(resolved_path(f.buf, id, path, false)); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 9d6b0ec5517..0141df34a6c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -27,11 +27,11 @@ #![allow(non_camel_case_types)] use libc; +use std::cell::RefCell; use std::fmt; use std::io; -use std::local_data; -use std::str; use std::slice; +use std::str; use collections::HashMap; use html::toc::TocBuilder; @@ -139,7 +139,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> { } } -local_data_key!(used_header_map: HashMap<~str, uint>) +local_data_key!(used_header_map: RefCell>) pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result { extern fn block(ob: *mut hoedown_buffer, text: *hoedown_buffer, @@ -216,15 +216,12 @@ pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result { let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) }; // Make sure our hyphenated ID is unique for this page - let id = local_data::get_mut(used_header_map, |map| { - let map = map.unwrap(); - match map.find_mut(&id) { - None => {} - Some(a) => { *a += 1; return format!("{}-{}", id, *a - 1) } - } - map.insert(id.clone(), 1); - id.clone() - }); + let map = used_header_map.get().unwrap(); + let id = match map.borrow_mut().find_mut(&id) { + None => id, + Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) } + }; + map.borrow_mut().insert(id.clone(), 1); let sec = match opaque.toc_builder { Some(ref mut builder) => { @@ -348,7 +345,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { /// used at the beginning of rendering an entire HTML page to reset from the /// previous state (if any). pub fn reset_headers() { - local_data::set(used_header_map, HashMap::new()) + used_header_map.replace(Some(RefCell::new(HashMap::new()))); } impl<'a> fmt::Show for Markdown<'a> { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a0d21bbf149..fe80d26d109 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -37,7 +37,6 @@ use collections::{HashMap, HashSet}; use std::fmt; use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader}; use std::io; -use std::local_data; use std::str; use std::strbuf::StrBuf; @@ -243,24 +242,22 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> { } // Crawl the crate to build various caches used for the output - let mut cache = local_data::get(::analysiskey, |analysis| { - let public_items = analysis.map(|a| a.public_items.clone()); - let public_items = public_items.unwrap_or(NodeSet::new()); - Cache { - impls: HashMap::new(), - typarams: HashMap::new(), - paths: HashMap::new(), - traits: HashMap::new(), - implementors: HashMap::new(), - stack: Vec::new(), - parent_stack: Vec::new(), - search_index: Vec::new(), - extern_locations: HashMap::new(), - privmod: false, - public_items: public_items, - orphan_methods: Vec::new(), - } - }); + let public_items = ::analysiskey.get().map(|a| a.public_items.clone()); + let public_items = public_items.unwrap_or(NodeSet::new()); + let mut cache = Cache { + impls: HashMap::new(), + typarams: HashMap::new(), + paths: HashMap::new(), + traits: HashMap::new(), + implementors: HashMap::new(), + stack: Vec::new(), + parent_stack: Vec::new(), + search_index: Vec::new(), + extern_locations: HashMap::new(), + privmod: false, + public_items: public_items, + orphan_methods: Vec::new(), + }; cache.stack.push(krate.name.clone()); krate = cache.fold_crate(krate); @@ -833,7 +830,7 @@ impl Context { item.name = Some(krate.name); // using a rwarc makes this parallelizable in the future - local_data::set(cache_key, Arc::new(cache)); + cache_key.replace(Some(Arc::new(cache))); let mut work = vec!((self, item)); loop { @@ -859,7 +856,7 @@ impl Context { info!("Rendering an item to {}", w.path().display()); // A little unfortunate that this is done like this, but it sure // does make formatting *a lot* nicer. - local_data::set(current_location_key, cx.current.clone()); + current_location_key.replace(Some(cx.current.clone())); let mut title = StrBuf::from_str(cx.current.connect("::")); if pushname { @@ -1299,31 +1296,28 @@ fn item_trait(w: &mut Writer, it: &clean::Item, try!(write!(w, "")); } - local_data::get(cache_key, |cache| { - let cache = cache.unwrap(); - match cache.implementors.find(&it.id) { - Some(implementors) => { - try!(write!(w, " -

Implementors

-
    - ")); - for i in implementors.iter() { - match *i { - PathType(ref ty) => { - try!(write!(w, "
  • {}
  • ", *ty)); - } - OtherType(ref generics, ref trait_, ref for_) => { - try!(write!(w, "
  • impl{} {} for {}
  • ", - *generics, *trait_, *for_)); - } + match cache_key.get().unwrap().implementors.find(&it.id) { + Some(implementors) => { + try!(write!(w, " +

    Implementors

    +
      + ")); + for i in implementors.iter() { + match *i { + PathType(ref ty) => { + try!(write!(w, "
    • {}
    • ", *ty)); + } + OtherType(ref generics, ref trait_, ref for_) => { + try!(write!(w, "
    • impl{} {} for {}
    • ", + *generics, *trait_, *for_)); } } - try!(write!(w, "
    ")); } - None => {} + try!(write!(w, "
")); } - Ok(()) - }) + None => {} + } + Ok(()) } fn render_method(w: &mut Writer, meth: &clean::Item) -> fmt::Result { @@ -1550,51 +1544,48 @@ fn render_struct(w: &mut Writer, it: &clean::Item, } fn render_methods(w: &mut Writer, it: &clean::Item) -> fmt::Result { - local_data::get(cache_key, |cache| { - let c = cache.unwrap(); - match c.impls.find(&it.id) { - Some(v) => { - let mut non_trait = v.iter().filter(|p| { - p.ref0().trait_.is_none() - }); - let non_trait = non_trait.collect::)>>(); - let mut traits = v.iter().filter(|p| { - p.ref0().trait_.is_some() - }); - let traits = traits.collect::)>>(); - - if non_trait.len() > 0 { - try!(write!(w, "

Methods

")); - for &(ref i, ref dox) in non_trait.move_iter() { + match cache_key.get().unwrap().impls.find(&it.id) { + Some(v) => { + let mut non_trait = v.iter().filter(|p| { + p.ref0().trait_.is_none() + }); + let non_trait = non_trait.collect::)>>(); + let mut traits = v.iter().filter(|p| { + p.ref0().trait_.is_some() + }); + let traits = traits.collect::)>>(); + + if non_trait.len() > 0 { + try!(write!(w, "

Methods

")); + for &(ref i, ref dox) in non_trait.move_iter() { + try!(render_impl(w, i, dox)); + } + } + if traits.len() > 0 { + try!(write!(w, "

Trait \ + Implementations

")); + let mut any_derived = false; + for & &(ref i, ref dox) in traits.iter() { + if !i.derived { try!(render_impl(w, i, dox)); + } else { + any_derived = true; } } - if traits.len() > 0 { - try!(write!(w, "

Trait \ - Implementations

")); - let mut any_derived = false; - for & &(ref i, ref dox) in traits.iter() { - if !i.derived { + if any_derived { + try!(write!(w, "

Derived Implementations \ +

")); + for &(ref i, ref dox) in traits.move_iter() { + if i.derived { try!(render_impl(w, i, dox)); - } else { - any_derived = true; - } - } - if any_derived { - try!(write!(w, "

Derived Implementations \ -

")); - for &(ref i, ref dox) in traits.move_iter() { - if i.derived { - try!(render_impl(w, i, dox)); - } } } } } - None => {} } - Ok(()) - }) + None => {} + } + Ok(()) } fn render_impl(w: &mut Writer, i: &clean::Impl, @@ -1644,9 +1635,8 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, match trait_id { None => {} Some(id) => { - try!(local_data::get(cache_key, |cache| { - let cache = cache.unwrap(); - match cache.traits.find(&id) { + try!({ + match cache_key.get().unwrap().traits.find(&id) { Some(t) => { for method in t.methods.iter() { let n = method.item().name.clone(); @@ -1661,7 +1651,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, None => {} } Ok(()) - })) + }) } } try!(write!(w, "")); -- cgit 1.4.1-3-g733a5