about summary refs log tree commit diff
path: root/src/librustdoc/html/format.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/html/format.rs')
-rw-r--r--src/librustdoc/html/format.rs156
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("&lt;".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),
+        }
+    }
+}