diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-12-14 20:33:10 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-14 20:33:10 +0100 |
| commit | 9ec620546f185d3776f312a0b0949bb2612500e6 (patch) | |
| tree | f1d5a21b86ca0c8c8c2b76a7992cbb93b052b7ec | |
| parent | 2ecba0fa00b75e7291978c50bece407f17296f45 (diff) | |
| parent | fc7221689e6dcb32dbf72befa465d851d92263d8 (diff) | |
| download | rust-9ec620546f185d3776f312a0b0949bb2612500e6.tar.gz rust-9ec620546f185d3776f312a0b0949bb2612500e6.zip | |
Rollup merge of #118910 - GuillaumeGomez:js-object-to-map, r=notriddle
[rustdoc] Use Map instead of Object for source files and search index It's cleaner and is also easier to manipulate `Map` rather than `Object` types. r? `@notriddle`
| -rw-r--r-- | src/librustdoc/html/render/search_index.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/html/render/write_shared.rs | 19 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/search.js | 141 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/src-script.js | 8 |
4 files changed, 77 insertions, 93 deletions
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index b3ae720fcf6..a1029320d2d 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -488,7 +488,7 @@ pub(crate) fn build_index<'tcx>( // Collect the index into a string format!( - r#""{}":{}"#, + r#"["{}",{}]"#, krate.name(tcx), serde_json::to_string(&CrateData { doc: crate_doc, diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index b04776e91dc..4b5d1c0d87c 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -167,23 +167,24 @@ pub(super) fn write_shared( let mut krates = Vec::new(); if path.exists() { - let prefix = format!("\"{krate}\""); + let prefix = format!("[\"{krate}\""); for line in BufReader::new(File::open(path)?).lines() { let line = line?; - if !line.starts_with('"') { + if !line.starts_with("[\"") { continue; } if line.starts_with(&prefix) { continue; } - if line.ends_with(",\\") { + if line.ends_with("],\\") { ret.push(line[..line.len() - 2].to_string()); } else { // Ends with "\\" (it's the case for the last added crate line) ret.push(line[..line.len() - 1].to_string()); } krates.push( - line.split('"') + line[1..] // We skip the `[` parent at the beginning of the line. + .split('"') .find(|s| !s.is_empty()) .map(|s| s.to_owned()) .unwrap_or_else(String::new), @@ -285,7 +286,7 @@ pub(super) fn write_shared( let (mut all_sources, _krates) = try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst); all_sources.push(format!( - r#""{}":{}"#, + r#"["{}",{}]"#, &krate.name(cx.tcx()), hierarchy .to_json_string() @@ -296,9 +297,9 @@ pub(super) fn write_shared( .replace("\\\"", "\\\\\"") )); all_sources.sort(); - let mut v = String::from("var srcIndex = JSON.parse('{\\\n"); + let mut v = String::from("const srcIndex = new Map(JSON.parse('[\\\n"); v.push_str(&all_sources.join(",\\\n")); - v.push_str("\\\n}');\ncreateSrcSidebar();\n"); + v.push_str("\\\n]'));\ncreateSrcSidebar();\n"); Ok(v.into_bytes()) }; write_invocation_specific("src-files.js", &make_sources)?; @@ -316,11 +317,11 @@ pub(super) fn write_shared( // with rustdoc running in parallel. all_indexes.sort(); write_invocation_specific("search-index.js", &|| { - let mut v = String::from("var searchIndex = JSON.parse('{\\\n"); + let mut v = String::from("const searchIndex = new Map(JSON.parse('[\\\n"); v.push_str(&all_indexes.join(",\\\n")); v.push_str( r#"\ -}'); +]')); if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; "#, diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 6fce7650b4c..ccb54e14a5c 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -80,10 +80,6 @@ const longItemTypes = [ const TY_GENERIC = itemTypes.indexOf("generic"); const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../"; -function hasOwnPropertyRustdoc(obj, property) { - return Object.prototype.hasOwnProperty.call(obj, property); -} - // In the search display, allows to switch between tabs. function printTab(nb) { let iter = 0; @@ -1074,7 +1070,7 @@ function initSearch(rawSearchIndex) { if (elem && elem.value !== "all crates" && - hasOwnPropertyRustdoc(rawSearchIndex, elem.value) + rawSearchIndex.has(elem.value) ) { return elem.value; } @@ -2524,11 +2520,10 @@ ${item.displayPath}<span class="${type}">${name}</span>\ } let crates = ""; - const crates_list = Object.keys(rawSearchIndex); - if (crates_list.length > 1) { + if (rawSearchIndex.size > 1) { crates = " in <div id=\"crate-search-div\"><select id=\"crate-search\">" + "<option value=\"all crates\">all crates</option>"; - for (const c of crates_list) { + for (const c of rawSearchIndex.keys()) { crates += `<option value="${c}" ${c === filterCrates && "selected"}>${c}</option>`; } crates += "</select></div>"; @@ -2945,81 +2940,70 @@ ${item.displayPath}<span class="${type}">${name}</span>\ // Function type fingerprints are 128-bit bloom filters that are used to // estimate the distance between function and query. // This loop counts the number of items to allocate a fingerprint for. - for (const crate in rawSearchIndex) { - if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) { - continue; - } + for (const crate of rawSearchIndex.values()) { // Each item gets an entry in the fingerprint array, and the crate // does, too - id += rawSearchIndex[crate].t.length + 1; + id += crate.t.length + 1; } functionTypeFingerprint = new Uint32Array((id + 1) * 4); // This loop actually generates the search item indexes, including // normalized names, type signature objects and fingerprints, and aliases. id = 0; - for (const crate in rawSearchIndex) { - if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) { - continue; - } - - let crateSize = 0; - - /** - * The raw search data for a given crate. `n`, `t`, `d`, `i`, and `f` - * are arrays with the same length. `q`, `a`, and `c` use a sparse - * representation for compactness. - * - * `n[i]` contains the name of an item. - * - * `t[i]` contains the type of that item - * (as a string of characters that represent an offset in `itemTypes`). - * - * `d[i]` contains the description of that item. - * - * `q` contains the full paths of the items. For compactness, it is a set of - * (index, path) pairs used to create a map. If a given index `i` is - * not present, this indicates "same as the last index present". - * - * `i[i]` contains an item's parent, usually a module. For compactness, - * it is a set of indexes into the `p` array. - * - * `f[i]` contains function signatures, or `0` if the item isn't a function. - * Functions are themselves encoded as arrays. The first item is a list of - * types representing the function's inputs, and the second list item is a list - * of types representing the function's output. Tuples are flattened. - * Types are also represented as arrays; the first item is an index into the `p` - * array, while the second is a list of types representing any generic parameters. - * - * b[i] contains an item's impl disambiguator. This is only present if an item - * is defined in an impl block and, the impl block's type has more than one associated - * item with the same name. - * - * `a` defines aliases with an Array of pairs: [name, offset], where `offset` - * points into the n/t/d/q/i/f arrays. - * - * `doc` contains the description of the crate. - * - * `p` is a list of path/type pairs. It is used for parents and function parameters. - * - * `c` is an array of item indices that are deprecated. - * - * @type {{ - * doc: string, - * a: Object, - * n: Array<string>, - * t: String, - * d: Array<string>, - * q: Array<[Number, string]>, - * i: Array<Number>, - * f: Array<RawFunctionSearchType>, - * p: Array<Object>, - * b: Array<[Number, String]>, - * c: Array<Number> - * }} - */ - const crateCorpus = rawSearchIndex[crate]; - + /** + * The raw search data for a given crate. `n`, `t`, `d`, `i`, and `f` + * are arrays with the same length. `q`, `a`, and `c` use a sparse + * representation for compactness. + * + * `n[i]` contains the name of an item. + * + * `t[i]` contains the type of that item + * (as a string of characters that represent an offset in `itemTypes`). + * + * `d[i]` contains the description of that item. + * + * `q` contains the full paths of the items. For compactness, it is a set of + * (index, path) pairs used to create a map. If a given index `i` is + * not present, this indicates "same as the last index present". + * + * `i[i]` contains an item's parent, usually a module. For compactness, + * it is a set of indexes into the `p` array. + * + * `f[i]` contains function signatures, or `0` if the item isn't a function. + * Functions are themselves encoded as arrays. The first item is a list of + * types representing the function's inputs, and the second list item is a list + * of types representing the function's output. Tuples are flattened. + * Types are also represented as arrays; the first item is an index into the `p` + * array, while the second is a list of types representing any generic parameters. + * + * b[i] contains an item's impl disambiguator. This is only present if an item + * is defined in an impl block and, the impl block's type has more than one associated + * item with the same name. + * + * `a` defines aliases with an Array of pairs: [name, offset], where `offset` + * points into the n/t/d/q/i/f arrays. + * + * `doc` contains the description of the crate. + * + * `p` is a list of path/type pairs. It is used for parents and function parameters. + * + * `c` is an array of item indices that are deprecated. + * + * @type {{ + * doc: string, + * a: Object, + * n: Array<string>, + * t: String, + * d: Array<string>, + * q: Array<[Number, string]>, + * i: Array<Number>, + * f: Array<RawFunctionSearchType>, + * p: Array<Object>, + * b: Array<[Number, String]>, + * c: Array<Number> + * }} + */ + for (const [crate, crateCorpus] of rawSearchIndex) { searchWords.push(crate); // This object should have exactly the same set of fields as the "row" // object defined below. Your JavaScript runtime will thank you. @@ -3145,14 +3129,13 @@ ${item.displayPath}<span class="${type}">${name}</span>\ id += 1; searchIndex.push(row); lastPath = row.path; - crateSize += 1; } if (aliases) { const currentCrateAliases = new Map(); ALIASES.set(crate, currentCrateAliases); for (const alias_name in aliases) { - if (!hasOwnPropertyRustdoc(aliases, alias_name)) { + if (!Object.prototype.hasOwnProperty.call(aliases, alias_name)) { continue; } @@ -3168,7 +3151,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\ } } } - currentIndex += crateSize; + currentIndex += itemTypes.length; } return searchWords; } @@ -3377,7 +3360,7 @@ if (typeof window !== "undefined") { } else { // Running in Node, not a browser. Run initSearch just to produce the // exports. - initSearch({}); + initSearch(new Map()); } diff --git a/src/librustdoc/html/static/js/src-script.js b/src/librustdoc/html/static/js/src-script.js index 679c2341f02..27b5cf1e2ae 100644 --- a/src/librustdoc/html/static/js/src-script.js +++ b/src/librustdoc/html/static/js/src-script.js @@ -118,10 +118,10 @@ function createSrcSidebar() { title.className = "title"; title.innerText = "Files"; sidebar.appendChild(title); - Object.keys(srcIndex).forEach(key => { - srcIndex[key][NAME_OFFSET] = key; - hasFoundFile = createDirEntry(srcIndex[key], sidebar, "", hasFoundFile); - }); + for (const [key, source] of srcIndex) { + source[NAME_OFFSET] = key; + hasFoundFile = createDirEntry(source, sidebar, "", hasFoundFile); + } container.appendChild(sidebar); // Focus on the current file in the source files sidebar. |
