From f1de04c7609ea31f76e445e3189dc6143f959f40 Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Wed, 9 Apr 2014 16:49:31 +0900 Subject: [PATCH] rustdoc: Represent item types as a small number in the search index. Has negligible improvements with gzip, but saves about 7% without it. This also has an effect of changing the tie-breaking order of item types. --- src/librustdoc/html/format.rs | 18 +++--- src/librustdoc/html/item_type.rs | 97 ++++++++++++++++++++++++++++++ src/librustdoc/html/render.rs | 55 ++++++----------- src/librustdoc/html/static/main.js | 36 +++++++++-- src/librustdoc/lib.rs | 1 + 5 files changed, 158 insertions(+), 49 deletions(-) create mode 100644 src/librustdoc/html/item_type.rs diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1457c454c5766..ca55d1f04ad2f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -24,6 +24,8 @@ use syntax::ast; use syntax::ast_util; use clean; +use html::item_type; +use html::item_type::ItemType; use html::render; use html::render::{cache_key, current_location_key}; @@ -172,17 +174,17 @@ fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool, }, |_cache| { Some((Vec::from_slice(fqn), match kind { - clean::TypeStruct => "struct", - clean::TypeEnum => "enum", - clean::TypeFunction => "fn", - clean::TypeTrait => "trait", + clean::TypeStruct => item_type::Struct, + clean::TypeEnum => item_type::Enum, + clean::TypeFunction => item_type::Function, + clean::TypeTrait => item_type::Trait, })) }) } fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool, root: |&render::Cache, &[~str]| -> Option<~str>, - info: |&render::Cache| -> Option<(Vec<~str> , &'static str)>) + info: |&render::Cache| -> Option<(Vec<~str> , ItemType)>) -> fmt::Result { // The generics will get written to both the title and link @@ -252,12 +254,12 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool, url.push_str("/"); } match shortty { - "mod" => { + item_type::Module => { url.push_str(*fqp.last().unwrap()); url.push_str("/index.html"); } _ => { - url.push_str(shortty); + url.push_str(shortty.to_static_str()); url.push_str("."); url.push_str(*fqp.last().unwrap()); url.push_str(".html"); diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs new file mode 100644 index 0000000000000..f59e8cb248738 --- /dev/null +++ b/src/librustdoc/html/item_type.rs @@ -0,0 +1,97 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Item types. + +use std::fmt; +use clean; + +/// Item type. Corresponds to `clean::ItemEnum` variants. +/// +/// The search index uses item types encoded as smaller numbers which equal to +/// discriminants. JavaScript then is used to decode them into the original value. +/// Consequently, every change to this type should be synchronized to +/// the `itemTypes` mapping table in `static/main.js`. +#[deriving(Eq, Clone)] +pub enum ItemType { + Module = 0, + Struct = 1, + Enum = 2, + Function = 3, + Typedef = 4, + Static = 5, + Trait = 6, + Impl = 7, + ViewItem = 8, + TyMethod = 9, + Method = 10, + StructField = 11, + Variant = 12, + ForeignFunction = 13, + ForeignStatic = 14, + Macro = 15, +} + +impl ItemType { + pub fn to_static_str(&self) -> &'static str { + match *self { + Module => "mod", + Struct => "struct", + Enum => "enum", + Function => "fn", + Typedef => "typedef", + Static => "static", + Trait => "trait", + Impl => "impl", + ViewItem => "viewitem", + TyMethod => "tymethod", + Method => "method", + StructField => "structfield", + Variant => "variant", + ForeignFunction => "ffi", + ForeignStatic => "ffs", + Macro => "macro", + } + } +} + +impl fmt::Show for ItemType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.to_static_str().fmt(f) + } +} + +impl fmt::Unsigned for ItemType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (*self as uint).fmt(f) + } +} + +pub fn shortty(item: &clean::Item) -> ItemType { + match item.inner { + clean::ModuleItem(..) => Module, + clean::StructItem(..) => Struct, + clean::EnumItem(..) => Enum, + clean::FunctionItem(..) => Function, + 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(..) => ForeignFunction, + clean::ForeignStaticItem(..) => ForeignStatic, + clean::MacroItem(..) => Macro, + } +} + diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 0b9a42d8e34b7..d2763f494ea4c 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 , &'static str)>, + pub paths: HashMap , 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, @@ -311,7 +313,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> { if i > 0 { try!(write!(&mut w, ",")); } - try!(write!(&mut w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}", + try!(write!(&mut w, "\\{ty:{:u},name:\"{}\",path:\"{}\",desc:{}", item.ty, item.name, item.path, item.desc.to_json().to_str())); match item.parent { @@ -330,7 +332,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> { if i > 0 { try!(write!(&mut w, ",")); } - try!(write!(&mut w, "\\{type:'{}',name:'{}'\\}", + try!(write!(&mut w, "\\{type:{:u},name:'{}'\\}", short, *fqp.last().unwrap())); } try!(write!(&mut w, "];")); @@ -622,12 +624,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 @@ -687,7 +690,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)); } _ => {} } @@ -845,7 +848,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(), }; @@ -899,27 +902,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 { @@ -1009,7 +991,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" } } @@ -1095,13 +1077,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, "")); } curty = myty; @@ -1704,8 +1686,9 @@ impl<'a> fmt::Show for Sidebar<'a> { }; try!(write!(w, "

{}

", 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, " fmt::Show for Sidebar<'a> { ty = short, tysel = short, class = class, - curty = shortty(cur), + curty = curty, name = item.as_slice())); } try!(write!(w, "
")); @@ -1735,7 +1718,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(), diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 1904ab27d17d9..43fb02f62be2e 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -135,7 +135,7 @@ function execQuery(query, max, searchWords) { var valLower = query.query.toLowerCase(), val = valLower, - typeFilter = query.type, + typeFilter = itemTypeFromName(query.type), results = [], split = valLower.split("::"); @@ -156,7 +156,7 @@ for (var i = 0; i < nSearchWords; i += 1) { if (searchWords[i] === val) { // filter type: ... queries - if (!typeFilter || typeFilter === searchIndex[i].ty) { + if (typeFilter < 0 || typeFilter === searchIndex[i].ty) { results.push({id: i, index: -1}); } } @@ -174,7 +174,7 @@ searchWords[j].replace(/_/g, "").indexOf(val) > -1) { // filter type: ... queries - if (!typeFilter || typeFilter === searchIndex[j].ty) { + if (typeFilter < 0 || typeFilter === searchIndex[j].ty) { results.push({id: j, index: searchWords[j].replace(/_/g, "").indexOf(val)}); } } @@ -405,7 +405,7 @@ shown.push(item); name = item.name; - type = item.ty; + type = itemTypes[item.ty]; output += ''; @@ -427,7 +427,7 @@ output += item.path + '::' + myparent.name + '::