Skip to content

Commit f1de04c

Browse files
committed
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.
1 parent ab6915d commit f1de04c

File tree

5 files changed

+158
-49
lines changed

5 files changed

+158
-49
lines changed

src/librustdoc/html/format.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -24,6 +24,8 @@ use syntax::ast;
2424
use syntax::ast_util;
2525

2626
use clean;
27+
use html::item_type;
28+
use html::item_type::ItemType;
2729
use html::render;
2830
use html::render::{cache_key, current_location_key};
2931

@@ -172,17 +174,17 @@ fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
172174
},
173175
|_cache| {
174176
Some((Vec::from_slice(fqn), match kind {
175-
clean::TypeStruct => "struct",
176-
clean::TypeEnum => "enum",
177-
clean::TypeFunction => "fn",
178-
clean::TypeTrait => "trait",
177+
clean::TypeStruct => item_type::Struct,
178+
clean::TypeEnum => item_type::Enum,
179+
clean::TypeFunction => item_type::Function,
180+
clean::TypeTrait => item_type::Trait,
179181
}))
180182
})
181183
}
182184

183185
fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
184186
root: |&render::Cache, &[~str]| -> Option<~str>,
185-
info: |&render::Cache| -> Option<(Vec<~str> , &'static str)>)
187+
info: |&render::Cache| -> Option<(Vec<~str> , ItemType)>)
186188
-> fmt::Result
187189
{
188190
// 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,
252254
url.push_str("/");
253255
}
254256
match shortty {
255-
"mod" => {
257+
item_type::Module => {
256258
url.push_str(*fqp.last().unwrap());
257259
url.push_str("/index.html");
258260
}
259261
_ => {
260-
url.push_str(shortty);
262+
url.push_str(shortty.to_static_str());
261263
url.push_str(".");
262264
url.push_str(*fqp.last().unwrap());
263265
url.push_str(".html");

src/librustdoc/html/item_type.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Item types.
12+
13+
use std::fmt;
14+
use clean;
15+
16+
/// Item type. Corresponds to `clean::ItemEnum` variants.
17+
///
18+
/// The search index uses item types encoded as smaller numbers which equal to
19+
/// discriminants. JavaScript then is used to decode them into the original value.
20+
/// Consequently, every change to this type should be synchronized to
21+
/// the `itemTypes` mapping table in `static/main.js`.
22+
#[deriving(Eq, Clone)]
23+
pub enum ItemType {
24+
Module = 0,
25+
Struct = 1,
26+
Enum = 2,
27+
Function = 3,
28+
Typedef = 4,
29+
Static = 5,
30+
Trait = 6,
31+
Impl = 7,
32+
ViewItem = 8,
33+
TyMethod = 9,
34+
Method = 10,
35+
StructField = 11,
36+
Variant = 12,
37+
ForeignFunction = 13,
38+
ForeignStatic = 14,
39+
Macro = 15,
40+
}
41+
42+
impl ItemType {
43+
pub fn to_static_str(&self) -> &'static str {
44+
match *self {
45+
Module => "mod",
46+
Struct => "struct",
47+
Enum => "enum",
48+
Function => "fn",
49+
Typedef => "typedef",
50+
Static => "static",
51+
Trait => "trait",
52+
Impl => "impl",
53+
ViewItem => "viewitem",
54+
TyMethod => "tymethod",
55+
Method => "method",
56+
StructField => "structfield",
57+
Variant => "variant",
58+
ForeignFunction => "ffi",
59+
ForeignStatic => "ffs",
60+
Macro => "macro",
61+
}
62+
}
63+
}
64+
65+
impl fmt::Show for ItemType {
66+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67+
self.to_static_str().fmt(f)
68+
}
69+
}
70+
71+
impl fmt::Unsigned for ItemType {
72+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73+
(*self as uint).fmt(f)
74+
}
75+
}
76+
77+
pub fn shortty(item: &clean::Item) -> ItemType {
78+
match item.inner {
79+
clean::ModuleItem(..) => Module,
80+
clean::StructItem(..) => Struct,
81+
clean::EnumItem(..) => Enum,
82+
clean::FunctionItem(..) => Function,
83+
clean::TypedefItem(..) => Typedef,
84+
clean::StaticItem(..) => Static,
85+
clean::TraitItem(..) => Trait,
86+
clean::ImplItem(..) => Impl,
87+
clean::ViewItemItem(..) => ViewItem,
88+
clean::TyMethodItem(..) => TyMethod,
89+
clean::MethodItem(..) => Method,
90+
clean::StructFieldItem(..) => StructField,
91+
clean::VariantItem(..) => Variant,
92+
clean::ForeignFunctionItem(..) => ForeignFunction,
93+
clean::ForeignStaticItem(..) => ForeignStatic,
94+
clean::MacroItem(..) => Macro,
95+
}
96+
}
97+

src/librustdoc/html/render.rs

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ use rustc::util::nodemap::NodeSet;
5252
use clean;
5353
use doctree;
5454
use fold::DocFolder;
55+
use html::item_type;
56+
use html::item_type::{ItemType, shortty};
5557
use html::format::{VisSpace, Method, FnStyleSpace};
5658
use html::layout;
5759
use html::markdown;
@@ -138,7 +140,7 @@ pub struct Cache {
138140
/// URLs when a type is being linked to. External paths are not located in
139141
/// this map because the `External` type itself has all the information
140142
/// necessary.
141-
pub paths: HashMap<ast::NodeId, (Vec<~str> , &'static str)>,
143+
pub paths: HashMap<ast::NodeId, (Vec<~str> , ItemType)>,
142144

143145
/// This map contains information about all known traits of this crate.
144146
/// Implementations of a crate should inherit the documentation of the
@@ -193,7 +195,7 @@ struct Sidebar<'a> { cx: &'a Context, item: &'a clean::Item, }
193195
/// Struct representing one entry in the JS search index. These are all emitted
194196
/// by hand to a large JS file at the end of cache-creation.
195197
struct IndexItem {
196-
ty: &'static str,
198+
ty: ItemType,
197199
name: ~str,
198200
path: ~str,
199201
desc: ~str,
@@ -311,7 +313,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
311313
if i > 0 {
312314
try!(write!(&mut w, ","));
313315
}
314-
try!(write!(&mut w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}",
316+
try!(write!(&mut w, "\\{ty:{:u},name:\"{}\",path:\"{}\",desc:{}",
315317
item.ty, item.name, item.path,
316318
item.desc.to_json().to_str()));
317319
match item.parent {
@@ -330,7 +332,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
330332
if i > 0 {
331333
try!(write!(&mut w, ","));
332334
}
333-
try!(write!(&mut w, "\\{type:'{}',name:'{}'\\}",
335+
try!(write!(&mut w, "\\{type:{:u},name:'{}'\\}",
334336
short, *fqp.last().unwrap()));
335337
}
336338
try!(write!(&mut w, "];"));
@@ -622,12 +624,13 @@ impl DocFolder for Cache {
622624
} else {
623625
let last = self.parent_stack.last().unwrap();
624626
let path = match self.paths.find(last) {
625-
Some(&(_, "trait")) =>
627+
Some(&(_, item_type::Trait)) =>
626628
Some(self.stack.slice_to(self.stack.len() - 1)),
627629
// The current stack not necessarily has correlation for
628630
// where the type was defined. On the other hand,
629631
// `paths` always has the right information if present.
630-
Some(&(ref fqp, "struct")) | Some(&(ref fqp, "enum")) =>
632+
Some(&(ref fqp, item_type::Struct)) |
633+
Some(&(ref fqp, item_type::Enum)) =>
631634
Some(fqp.slice_to(fqp.len() - 1)),
632635
Some(..) => Some(self.stack.as_slice()),
633636
None => None
@@ -687,7 +690,7 @@ impl DocFolder for Cache {
687690
clean::VariantItem(..) => {
688691
let mut stack = self.stack.clone();
689692
stack.pop();
690-
self.paths.insert(item.id, (stack, "enum"));
693+
self.paths.insert(item.id, (stack, item_type::Enum));
691694
}
692695
_ => {}
693696
}
@@ -845,7 +848,7 @@ impl Context {
845848
}
846849
title.push_str(" - Rust");
847850
let page = layout::Page {
848-
ty: shortty(it),
851+
ty: shortty(it).to_static_str(),
849852
root_path: cx.root_path.as_slice(),
850853
title: title.as_slice(),
851854
};
@@ -899,27 +902,6 @@ impl Context {
899902
}
900903
}
901904

902-
fn shortty(item: &clean::Item) -> &'static str {
903-
match item.inner {
904-
clean::ModuleItem(..) => "mod",
905-
clean::StructItem(..) => "struct",
906-
clean::EnumItem(..) => "enum",
907-
clean::FunctionItem(..) => "fn",
908-
clean::TypedefItem(..) => "typedef",
909-
clean::StaticItem(..) => "static",
910-
clean::TraitItem(..) => "trait",
911-
clean::ImplItem(..) => "impl",
912-
clean::ViewItemItem(..) => "viewitem",
913-
clean::TyMethodItem(..) => "tymethod",
914-
clean::MethodItem(..) => "method",
915-
clean::StructFieldItem(..) => "structfield",
916-
clean::VariantItem(..) => "variant",
917-
clean::ForeignFunctionItem(..) => "ffi",
918-
clean::ForeignStaticItem(..) => "ffs",
919-
clean::MacroItem(..) => "macro",
920-
}
921-
}
922-
923905
impl<'a> Item<'a> {
924906
fn ismodule(&self) -> bool {
925907
match self.item.inner {
@@ -1009,7 +991,7 @@ impl<'a> fmt::Show for Item<'a> {
1009991
fn item_path(item: &clean::Item) -> ~str {
1010992
match item.inner {
1011993
clean::ModuleItem(..) => *item.name.get_ref() + "/index.html",
1012-
_ => shortty(item) + "." + *item.name.get_ref() + ".html"
994+
_ => shortty(item).to_static_str() + "." + *item.name.get_ref() + ".html"
1013995
}
1014996
}
1015997

@@ -1095,13 +1077,13 @@ fn item_module(w: &mut Writer, cx: &Context,
10951077
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
10961078

10971079
debug!("{:?}", indices);
1098-
let mut curty = "";
1080+
let mut curty = None;
10991081
for &idx in indices.iter() {
11001082
let myitem = &items[idx];
11011083

1102-
let myty = shortty(myitem);
1084+
let myty = Some(shortty(myitem));
11031085
if myty != curty {
1104-
if curty != "" {
1086+
if curty.is_some() {
11051087
try!(write!(w, "</table>"));
11061088
}
11071089
curty = myty;
@@ -1704,8 +1686,9 @@ impl<'a> fmt::Show for Sidebar<'a> {
17041686
};
17051687
try!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty));
17061688
for item in items.iter() {
1689+
let curty = shortty(cur).to_static_str();
17071690
let class = if cur.name.get_ref() == item &&
1708-
short == shortty(cur) { "current" } else { "" };
1691+
short == curty { "current" } else { "" };
17091692
try!(write!(w, "<a class='{ty} {class}' href='{curty, select,
17101693
mod{../}
17111694
other{}
@@ -1716,7 +1699,7 @@ impl<'a> fmt::Show for Sidebar<'a> {
17161699
ty = short,
17171700
tysel = short,
17181701
class = class,
1719-
curty = shortty(cur),
1702+
curty = curty,
17201703
name = item.as_slice()));
17211704
}
17221705
try!(write!(w, "</div>"));
@@ -1735,7 +1718,7 @@ impl<'a> fmt::Show for Sidebar<'a> {
17351718
fn build_sidebar(m: &clean::Module) -> HashMap<~str, Vec<~str> > {
17361719
let mut map = HashMap::new();
17371720
for item in m.items.iter() {
1738-
let short = shortty(item);
1721+
let short = shortty(item).to_static_str();
17391722
let myname = match item.name {
17401723
None => continue,
17411724
Some(ref s) => s.to_owned(),

src/librustdoc/html/static/main.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
function execQuery(query, max, searchWords) {
136136
var valLower = query.query.toLowerCase(),
137137
val = valLower,
138-
typeFilter = query.type,
138+
typeFilter = itemTypeFromName(query.type),
139139
results = [],
140140
split = valLower.split("::");
141141

@@ -156,7 +156,7 @@
156156
for (var i = 0; i < nSearchWords; i += 1) {
157157
if (searchWords[i] === val) {
158158
// filter type: ... queries
159-
if (!typeFilter || typeFilter === searchIndex[i].ty) {
159+
if (typeFilter < 0 || typeFilter === searchIndex[i].ty) {
160160
results.push({id: i, index: -1});
161161
}
162162
}
@@ -174,7 +174,7 @@
174174
searchWords[j].replace(/_/g, "").indexOf(val) > -1)
175175
{
176176
// filter type: ... queries
177-
if (!typeFilter || typeFilter === searchIndex[j].ty) {
177+
if (typeFilter < 0 || typeFilter === searchIndex[j].ty) {
178178
results.push({id: j, index: searchWords[j].replace(/_/g, "").indexOf(val)});
179179
}
180180
}
@@ -405,7 +405,7 @@
405405

406406
shown.push(item);
407407
name = item.name;
408-
type = item.ty;
408+
type = itemTypes[item.ty];
409409

410410
output += '<tr class="' + type + ' result"><td>';
411411

@@ -427,7 +427,7 @@
427427
output += item.path + '::' + myparent.name +
428428
'::<a href="' + rootPath +
429429
item.path.replace(/::/g, '/') +
430-
'/' + myparent.type +
430+
'/' + itemTypes[myparent.type] +
431431
'.' + myparent.name +
432432
'.html' + anchor +
433433
'" class="' + type +
@@ -505,6 +505,32 @@
505505
showResults(results);
506506
}
507507

508+
// This mapping table should match the discriminants of
509+
// `rustdoc::html::item_type::ItemType` type in Rust.
510+
var itemTypes = ["mod",
511+
"struct",
512+
"enum",
513+
"fn",
514+
"typedef",
515+
"static",
516+
"trait",
517+
"impl",
518+
"viewitem",
519+
"tymethod",
520+
"method",
521+
"structfield",
522+
"variant",
523+
"ffi",
524+
"ffs",
525+
"macro"];
526+
527+
function itemTypeFromName(typename) {
528+
for (var i = 0; i < itemTypes.length; ++i) {
529+
if (itemTypes[i] === typename) return i;
530+
}
531+
return -1;
532+
}
533+
508534
function buildIndex(rawSearchIndex) {
509535
searchIndex = [];
510536
var searchWords = [];

src/librustdoc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub mod fold;
4141
pub mod html {
4242
pub mod highlight;
4343
pub mod escape;
44+
pub mod item_type;
4445
pub mod format;
4546
pub mod layout;
4647
pub mod markdown;

0 commit comments

Comments
 (0)