about summary refs log tree commit diff
path: root/src/librustdoc/html/render.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/html/render.rs')
-rw-r--r--src/librustdoc/html/render.rs111
1 files changed, 58 insertions, 53 deletions
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index ccee4f0ffc9..669a489a4fb 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -52,6 +52,8 @@ use rustc::util::nodemap::NodeSet;
 use clean;
 use doctree;
 use fold::DocFolder;
+use html::item_type;
+use html::item_type::{ItemType, shortty};
 use html::format::{VisSpace, Method, FnStyleSpace};
 use html::layout;
 use html::markdown;
@@ -138,7 +140,7 @@ pub struct Cache {
     /// URLs when a type is being linked to. External paths are not located in
     /// this map because the `External` type itself has all the information
     /// necessary.
-    pub paths: HashMap<ast::NodeId, (Vec<~str> , &'static str)>,
+    pub paths: HashMap<ast::NodeId, (Vec<~str> , ItemType)>,
 
     /// This map contains information about all known traits of this crate.
     /// Implementations of a crate should inherit the documentation of the
@@ -193,7 +195,7 @@ struct Sidebar<'a> { cx: &'a Context, item: &'a clean::Item, }
 /// Struct representing one entry in the JS search index. These are all emitted
 /// by hand to a large JS file at the end of cache-creation.
 struct IndexItem {
-    ty: &'static str,
+    ty: ItemType,
     name: ~str,
     path: ~str,
     desc: ~str,
@@ -262,6 +264,9 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
     });
     cache.stack.push(krate.name.clone());
     krate = cache.fold_crate(krate);
+
+    let mut nodeid_to_pathid = HashMap::new();
+    let mut pathid_to_nodeid = Vec::new();
     {
         let Cache { search_index: ref mut index,
                     orphan_methods: ref meths, paths: ref mut paths, ..} = cache;
@@ -283,48 +288,67 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
             }
         };
 
-        // Prune the paths that do not appear in the index.
-        let mut unseen: HashSet<ast::NodeId> = paths.keys().map(|&id| id).collect();
+        // Reduce `NodeId` in paths into smaller sequential numbers,
+        // and prune the paths that do not appear in the index.
         for item in index.iter() {
             match item.parent {
-                Some(ref pid) => { unseen.remove(pid); }
+                Some(nodeid) => {
+                    if !nodeid_to_pathid.contains_key(&nodeid) {
+                        let pathid = pathid_to_nodeid.len();
+                        nodeid_to_pathid.insert(nodeid, pathid);
+                        pathid_to_nodeid.push(nodeid);
+                    }
+                }
                 None => {}
             }
         }
-        for pid in unseen.iter() {
-            paths.remove(pid);
-        }
+        assert_eq!(nodeid_to_pathid.len(), pathid_to_nodeid.len());
     }
 
     // Publish the search index
     let index = {
         let mut w = MemWriter::new();
-        try!(write!(&mut w, "searchIndex['{}'] = [", krate.name));
+        try!(write!(&mut w, r#"searchIndex['{}'] = \{"items":["#, krate.name));
+
+        let mut lastpath = ~"";
         for (i, item) in cache.search_index.iter().enumerate() {
+            // Omit the path if it is same to that of the prior item.
+            let path;
+            if lastpath == item.path {
+                path = "";
+            } else {
+                lastpath = item.path.clone();
+                path = item.path.as_slice();
+            };
+
             if i > 0 {
                 try!(write!(&mut w, ","));
             }
-            try!(write!(&mut w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}",
-                        item.ty, item.name, item.path,
+            try!(write!(&mut w, r#"[{:u},"{}","{}",{}"#,
+                        item.ty, item.name, path,
                         item.desc.to_json().to_str()));
             match item.parent {
-                Some(id) => {
-                    try!(write!(&mut w, ",parent:'{}'", id));
+                Some(nodeid) => {
+                    let pathid = *nodeid_to_pathid.find(&nodeid).unwrap();
+                    try!(write!(&mut w, ",{}", pathid));
                 }
                 None => {}
             }
-            try!(write!(&mut w, "\\}"));
+            try!(write!(&mut w, "]"));
         }
-        try!(write!(&mut w, "];"));
-        try!(write!(&mut w, "allPaths['{}'] = \\{", krate.name));
-        for (i, (&id, &(ref fqp, short))) in cache.paths.iter().enumerate() {
+
+        try!(write!(&mut w, r#"],"paths":["#));
+
+        for (i, &nodeid) in pathid_to_nodeid.iter().enumerate() {
+            let &(ref fqp, short) = cache.paths.find(&nodeid).unwrap();
             if i > 0 {
                 try!(write!(&mut w, ","));
             }
-            try!(write!(&mut w, "'{}':\\{type:'{}',name:'{}'\\}",
-                        id, short, *fqp.last().unwrap()));
+            try!(write!(&mut w, r#"[{:u},"{}"]"#,
+                        short, *fqp.last().unwrap()));
         }
-        try!(write!(&mut w, "\\};"));
+
+        try!(write!(&mut w, r"]\};"));
 
         str::from_utf8(w.unwrap().as_slice()).unwrap().to_owned()
     };
@@ -360,7 +384,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
             }
         }
         let mut w = try!(File::create(&dst));
-        try!(writeln!(&mut w, r"var searchIndex = \{\}; var allPaths = \{\};"));
+        try!(writeln!(&mut w, r"var searchIndex = \{\};"));
         for index in all_indexes.iter() {
             try!(writeln!(&mut w, "{}", *index));
         }
@@ -613,12 +637,13 @@ impl DocFolder for Cache {
                         } else {
                             let last = self.parent_stack.last().unwrap();
                             let path = match self.paths.find(last) {
-                                Some(&(_, "trait")) =>
+                                Some(&(_, item_type::Trait)) =>
                                     Some(self.stack.slice_to(self.stack.len() - 1)),
                                 // The current stack not necessarily has correlation for
                                 // where the type was defined. On the other hand,
                                 // `paths` always has the right information if present.
-                                Some(&(ref fqp, "struct")) | Some(&(ref fqp, "enum")) =>
+                                Some(&(ref fqp, item_type::Struct)) |
+                                Some(&(ref fqp, item_type::Enum)) =>
                                     Some(fqp.slice_to(fqp.len() - 1)),
                                 Some(..) => Some(self.stack.as_slice()),
                                 None => None
@@ -678,7 +703,7 @@ impl DocFolder for Cache {
             clean::VariantItem(..) => {
                 let mut stack = self.stack.clone();
                 stack.pop();
-                self.paths.insert(item.id, (stack, "enum"));
+                self.paths.insert(item.id, (stack, item_type::Enum));
             }
             _ => {}
         }
@@ -836,7 +861,7 @@ impl Context {
             }
             title.push_str(" - Rust");
             let page = layout::Page {
-                ty: shortty(it),
+                ty: shortty(it).to_static_str(),
                 root_path: cx.root_path.as_slice(),
                 title: title.as_slice(),
             };
@@ -890,27 +915,6 @@ impl Context {
     }
 }
 
-fn shortty(item: &clean::Item) -> &'static str {
-    match item.inner {
-        clean::ModuleItem(..)          => "mod",
-        clean::StructItem(..)          => "struct",
-        clean::EnumItem(..)            => "enum",
-        clean::FunctionItem(..)        => "fn",
-        clean::TypedefItem(..)         => "typedef",
-        clean::StaticItem(..)          => "static",
-        clean::TraitItem(..)           => "trait",
-        clean::ImplItem(..)            => "impl",
-        clean::ViewItemItem(..)        => "viewitem",
-        clean::TyMethodItem(..)        => "tymethod",
-        clean::MethodItem(..)          => "method",
-        clean::StructFieldItem(..)     => "structfield",
-        clean::VariantItem(..)         => "variant",
-        clean::ForeignFunctionItem(..) => "ffi",
-        clean::ForeignStaticItem(..)   => "ffs",
-        clean::MacroItem(..)           => "macro",
-    }
-}
-
 impl<'a> Item<'a> {
     fn ismodule(&self) -> bool {
         match self.item.inner {
@@ -1000,7 +1004,7 @@ impl<'a> fmt::Show for Item<'a> {
 fn item_path(item: &clean::Item) -> ~str {
     match item.inner {
         clean::ModuleItem(..) => *item.name.get_ref() + "/index.html",
-        _ => shortty(item) + "." + *item.name.get_ref() + ".html"
+        _ => shortty(item).to_static_str() + "." + *item.name.get_ref() + ".html"
     }
 }
 
@@ -1086,13 +1090,13 @@ fn item_module(w: &mut Writer, cx: &Context,
     indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
 
     debug!("{:?}", indices);
-    let mut curty = "";
+    let mut curty = None;
     for &idx in indices.iter() {
         let myitem = &items[idx];
 
-        let myty = shortty(myitem);
+        let myty = Some(shortty(myitem));
         if myty != curty {
-            if curty != "" {
+            if curty.is_some() {
                 try!(write!(w, "</table>"));
             }
             curty = myty;
@@ -1695,8 +1699,9 @@ impl<'a> fmt::Show for Sidebar<'a> {
             };
             try!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty));
             for item in items.iter() {
+                let curty = shortty(cur).to_static_str();
                 let class = if cur.name.get_ref() == item &&
-                               short == shortty(cur) { "current" } else { "" };
+                               short == curty { "current" } else { "" };
                 try!(write!(w, "<a class='{ty} {class}' href='{curty, select,
                                 mod{../}
                                 other{}
@@ -1707,7 +1712,7 @@ impl<'a> fmt::Show for Sidebar<'a> {
                        ty = short,
                        tysel = short,
                        class = class,
-                       curty = shortty(cur),
+                       curty = curty,
                        name = item.as_slice()));
             }
             try!(write!(w, "</div>"));
@@ -1726,7 +1731,7 @@ impl<'a> fmt::Show for Sidebar<'a> {
 fn build_sidebar(m: &clean::Module) -> HashMap<~str, Vec<~str> > {
     let mut map = HashMap::new();
     for item in m.items.iter() {
-        let short = shortty(item);
+        let short = shortty(item).to_static_str();
         let myname = match item.name {
             None => continue,
             Some(ref s) => s.to_owned(),