diff options
Diffstat (limited to 'src/librustdoc/html/format.rs')
| -rw-r--r-- | src/librustdoc/html/format.rs | 156 |
1 files changed, 123 insertions, 33 deletions
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 4d0f6928d50..7010e7fa4ea 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -13,11 +13,13 @@ use std::local_data; use std::rt::io; use syntax::ast; +use syntax::ast_util; use clean; use html::render::{cache_key, current_location_key}; pub struct VisSpace(Option<ast::visibility>); +pub struct PuritySpace(ast::purity); pub struct Method<'self>(&'self clean::SelfTy, &'self clean::FnDecl); impl fmt::Default for clean::Generics { @@ -95,7 +97,8 @@ impl fmt::Default for clean::Path { } } -fn resolved_path(w: &mut io::Writer, id: ast::NodeId, path: &clean::Path) { +fn resolved_path(w: &mut io::Writer, id: ast::NodeId, + path: &clean::Path, print_all: bool) { // The generics will get written to both the title and link let mut generics = ~""; let last = path.segments.last(); @@ -117,47 +120,73 @@ fn resolved_path(w: &mut io::Writer, id: ast::NodeId, path: &clean::Path) { // Did someone say rightward-drift? do local_data::get(current_location_key) |loc| { let loc = loc.unwrap(); + + if print_all { + let mut root = match path.segments[0].name.as_slice() { + "super" => ~"../", + "self" => ~"", + _ => "../".repeat(loc.len() - 1), + }; + let amt = path.segments.len() - 1; + for seg in path.segments.slice_to(amt).iter() { + if "super" == seg.name || "self" == seg.name { + write!(w, "{}::", seg.name); + } else { + root.push_str(seg.name); + root.push_str("/"); + write!(w, "<a class='mod' + href='{}index.html'>{}</a>::", + root, + seg.name); + } + } + } + do local_data::get(cache_key) |cache| { do cache.unwrap().read |cache| { match cache.paths.find(&id) { // This is a documented path, link to it! Some(&(ref fqp, shortty)) => { let fqn = fqp.connect("::"); - let mut same = 0; - for (a, b) in loc.iter().zip(fqp.iter()) { - if *a == *b { - same += 1; - } else { - break; - } - } + let same = loc.iter().zip(fqp.iter()) + .take_while(|&(a, b)| *a == *b).len(); let mut url = ~""; - for _ in range(same, loc.len()) { + if "super" == path.segments[0].name { url.push_str("../"); + } else if "self" != path.segments[0].name { + url.push_str("../".repeat(loc.len() - same)); } - if same == fqp.len() { - url.push_str(shortty); - url.push_str("."); - url.push_str(*fqp.last()); - url.push_str(".html"); - } else { + if same < fqp.len() { let remaining = fqp.slice_from(same); let to_link = remaining.slice_to(remaining.len() - 1); for component in to_link.iter() { url.push_str(*component); url.push_str("/"); } - url.push_str(shortty); - url.push_str("."); - url.push_str(*remaining.last()); - url.push_str(".html"); } - + match shortty { + "mod" => { + url.push_str(*fqp.last()); + url.push_str("/index.html"); + } + _ => { + url.push_str(shortty); + url.push_str("."); + url.push_str(*fqp.last()); + url.push_str(".html"); + } + } write!(w, "<a class='{}' href='{}' title='{}'>{}</a>{}", shortty, url, fqn, last.name, generics); } None => { + if print_all { + let amt = path.segments.len() - 1; + for seg in path.segments.iter().take(amt) { + write!(w, "{}::", seg.name); + } + } write!(w, "{}{}", last.name, generics); } }; @@ -176,9 +205,8 @@ impl fmt::Default for clean::Type { } } } - clean::Unresolved(*) => unreachable!(), clean::ResolvedPath{id, typarams: ref typarams, path: ref path} => { - resolved_path(f.buf, id, path); + resolved_path(f.buf, id, path, false); match *typarams { Some(ref params) => { f.buf.write("<".as_bytes()); @@ -228,11 +256,7 @@ impl fmt::Default for clean::Type { None => {} } write!(f.buf, "{}{}fn{}", - match decl.purity { - ast::unsafe_fn => "unsafe ", - ast::extern_fn => "extern ", - ast::impure_fn => "" - }, + PuritySpace(decl.purity), match decl.onceness { ast::Once => "once ", ast::Many => "", @@ -242,11 +266,7 @@ impl fmt::Default for clean::Type { } clean::BareFunction(ref decl) => { write!(f.buf, "{}{}fn{}{}", - match decl.purity { - ast::unsafe_fn => "unsafe ", - ast::extern_fn => "extern ", - ast::impure_fn => "" - }, + PuritySpace(decl.purity), match decl.abi { ~"" | ~"\"Rust\"" => ~"", ref s => " " + *s + " ", @@ -362,3 +382,73 @@ impl fmt::Default for VisSpace { } } } + +impl fmt::Default for PuritySpace { + fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) { + match **p { + ast::unsafe_fn => write!(f.buf, "unsafe "), + ast::extern_fn => write!(f.buf, "extern "), + ast::impure_fn => {} + } + } +} + +impl fmt::Default for clean::ViewPath { + fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) { + match *v { + clean::SimpleImport(ref name, ref src) => { + if *name == src.path.segments.last().name { + write!(f.buf, "use {};", *src); + } else { + write!(f.buf, "use {} = {};", *name, *src); + } + } + clean::GlobImport(ref src) => { + write!(f.buf, "use {}::*;", *src); + } + clean::ImportList(ref src, ref names) => { + write!(f.buf, "use {}::\\{", *src); + for (i, n) in names.iter().enumerate() { + if i > 0 { write!(f.buf, ", "); } + write!(f.buf, "{}", *n); + } + write!(f.buf, "\\};"); + } + } + } +} + +impl fmt::Default for clean::ImportSource { + fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) { + match v.did { + Some(did) if ast_util::is_local(did) => { + resolved_path(f.buf, did.node, &v.path, true); + } + _ => { + for (i, seg) in v.path.segments.iter().enumerate() { + if i > 0 { write!(f.buf, "::") } + write!(f.buf, "{}", seg.name); + } + } + } + } +} + +impl fmt::Default for clean::ViewListIdent { + fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) { + match v.source { + Some(did) if ast_util::is_local(did) => { + let path = clean::Path { + global: false, + segments: ~[clean::PathSegment { + name: v.name.clone(), + lifetime: None, + types: ~[], + }] + }; + resolved_path(f.buf, did.node, &path, false); + } + _ => write!(f.buf, "{}", v.name), + } + } +} |
