diff options
| author | Guillaume Gomez <guillaume.gomez@huawei.com> | 2022-01-04 15:44:00 +0100 |
|---|---|---|
| committer | Guillaume Gomez <guillaume.gomez@huawei.com> | 2022-04-18 20:59:08 +0200 |
| commit | 264064df36e055c19af2c82145bbbe616b32fb02 (patch) | |
| tree | ae9031f6c90138a37624c8ccbd75be38a97a6795 | |
| parent | 99c5394ecc92190db16fc8dce1260658cbeedeb1 (diff) | |
| download | rust-264064df36e055c19af2c82145bbbe616b32fb02.tar.gz rust-264064df36e055c19af2c82145bbbe616b32fb02.zip | |
* Greatly improve the rustdoc search parser source code
* Move all functions outside parseQuery
| -rw-r--r-- | src/librustdoc/html/static/js/externs.js | 44 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/search.js | 851 | ||||
| -rw-r--r-- | src/test/rustdoc-gui/search-result-color.goml | 2 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-errors.js | 25 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-filter.js | 9 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-generics.js | 35 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-in_args.js | 6 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-invalid.js | 12 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-literal.js | 3 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-paths.js | 12 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-quote.js | 6 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/parser-returned.js | 6 | ||||
| -rw-r--r-- | src/test/rustdoc-js-std/vec-new.js | 2 | ||||
| -rw-r--r-- | src/test/rustdoc-js/doc-alias-whitespace.js | 2 | ||||
| -rw-r--r-- | src/test/rustdoc-js/doc-alias.js | 42 | ||||
| -rw-r--r-- | src/tools/rustdoc-js/tester.js | 16 |
16 files changed, 563 insertions, 510 deletions
diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js index 15665b1f31a..1fdd3068a03 100644 --- a/src/librustdoc/html/static/js/externs.js +++ b/src/librustdoc/html/static/js/externs.js @@ -8,7 +8,6 @@ function initSearch(searchIndex){} /** * @typedef {{ - * isExact: boolean, * name: string, * fullPath: Array<string>, * pathWithoutLast: Array<string>, @@ -20,18 +19,23 @@ var QueryElement; /** * @typedef {{ + * pos: number, + * totalElems: number, + * typeFilter: (null|string), + * userQuery: string, + * }} + */ +var ParserState; + +/** + * @typedef {{ * original: string, * userQuery: string, - * length: number, - * pos: number, * typeFilter: number, * elems: Array<QueryElement>, - * elemName: (string|null), * args: Array<QueryElement>, * returned: Array<QueryElement>, * foundElems: number, - * id: string, - * nameSplit: (string|null), * }} */ var ParsedQuery; @@ -50,3 +54,31 @@ var ParsedQuery; * }} */ var Row; + +/** + * @typedef {{ + * in_args: Array<Object>, + * returned: Array<Object>, + * others: Array<Object>, + * query: ParsedQuery, + * }} + */ +var ResultsTable; + +/** + * @typedef {{ + * crate: "std" + * desc: string, + * displayPath: string, + * fullPath: string, + * href: string, + * id: number, + * lev: number, + * name: string, + * normalizedName: string, + * parent: (Object|undefined), + * path: string, + * ty: number, + * }} + */ +var Results; diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 469551f2092..7f21fa8bea6 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -124,6 +124,302 @@ window.initSearch = function(rawSearchIndex) { searchState.input.value = params.search || ""; } + function isWhitespace(c) { + return " \t\n\r".indexOf(c) !== -1; + } + + function isSpecialStartCharacter(c) { + return "(<\"".indexOf(c) !== -1; + } + + function isStopCharacter(c) { + return isWhitespace(c) || "),>-=".indexOf(c) !== -1; + } + + function removeEmptyStringsFromArray(arr) { + for (var i = 0, len = arr.length; i < len; ++i) { + if (arr[i] === "") { + arr.splice(i, 1); + i -= 1; + } + } + } + + function itemTypeFromName(typename) { + for (var i = 0, len = itemTypes.length; i < len; ++i) { + if (itemTypes[i] === typename) { + return i; + } + } + return NO_TYPE_FILTER; + } + + /** + * If we encounter a `"`, then we try to extract the string from it until we find another `"`. + * + * This function will throw an error in the following cases: + * * There is already another string element. + * * We are parsing a generic argument. + * * There is more than one element. + * * There is no closing `"`. + * + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {boolean} isInGenerics + */ + function getStringElem(query, parserState, isInGenerics) { + if (isInGenerics) { + throw new Error("`\"` cannot be used in generics"); + } else if (query.literalSearch) { + throw new Error("Cannot have more than one literal search element"); + } else if (parserState.totalElems !== 0) { + throw new Error("Cannot use literal search when there is more than one element"); + } + parserState.pos += 1; + while (parserState.pos < parserState.length && + parserState.userQuery[parserState.pos] !== "\"") + { + parserState.pos += 1; + } + if (parserState.pos >= parserState.length) { + throw new Error("Unclosed `\"`"); + } + // To skip the quote at the end. + parserState.pos += 1; + query.literalSearch = true; + } + + /** + * Increase the parser position as long as the character is a whitespace. This check is + * performed with the `isWhitespace` function. + * + * @param {ParserState} parserState + */ + function skipWhitespaces(parserState) { + while (parserState.pos < parserState.length) { + var c = parserState.userQuery[parserState.pos]; + if (!isWhitespace(c)) { + break; + } + parserState.pos += 1; + } + } + + /** + * Returns `true` if the current parser position is starting with "::". + * + * @param {ParserState} parserState + * @return {boolean} + */ + function isPathStart(parserState) { + return parserState.userQuery.slice(parserState.pos, parserState.pos + 2) == '::'; + } + + /** + * Returns `true` if the current parser position is starting with "->". + * + * @param {ParserState} parserState + * @return {boolean} + */ + function isReturnArrow(parserState) { + return parserState.userQuery.slice(parserState.pos, parserState.pos + 2) == '->'; + } + + /** + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {Array<QueryElement>} elems - This is where the new {QueryElement} will be added. + * @param {string} name - Name of the query element. + * @param {Array<QueryElement>} generics - List of generics of this query element. + */ + function createQueryElement(query, parserState, elems, name, generics) { + removeEmptyStringsFromArray(generics); + if (name === '*' || (name.length === 0 && generics.length === 0)) { + return; + } + if (query.literalSearch && parserState.totalElems > 0) { + throw new Error("You cannot have more than one element if you use quotes"); + } + var pathSegments = name.split("::"); + removeEmptyStringsFromArray(pathSegments); + // In case we only have something like `<p>`, there is no name but it remains valid. + if (pathSegments.length === 0) { + pathSegments = [""]; + } + elems.push({ + name: name, + fullPath: pathSegments, + pathWithoutLast: pathSegments.slice(0, pathSegments.length - 1), + pathLast: pathSegments[pathSegments.length - 1], + generics: generics, + }); + parserState.totalElems += 1; + } + + /** + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {Array<QueryElement>} elems - This is where the new {QueryElement} will be added. + * @param {boolean} isInGenerics + */ + function getNextElem(query, parserState, elems, isInGenerics) { + var generics = []; + + var start = parserState.pos; + var end = start; + // We handle the strings on their own mostly to make code easier to follow. + if (parserState.userQuery[parserState.pos] === "\"") { + start += 1; + getStringElem(query, parserState, isInGenerics); + end = parserState.pos - 1; + skipWhitespaces(parserState); + } else { + while (parserState.pos < parserState.length) { + var c = parserState.userQuery[parserState.pos]; + if (isStopCharacter(c) || isSpecialStartCharacter(c)) { + break; + } + // If we allow paths ("str::string" for example). + else if (c === ":") { + if (!isPathStart(parserState)) { + break; + } + // Skip current ":". + parserState.pos += 1; + } + parserState.pos += 1; + end = parserState.pos; + skipWhitespaces(parserState); + } + } + if (parserState.pos < parserState.length && + parserState.userQuery[parserState.pos] === "<") + { + parserState.pos += 1; + getItemsBefore(query, parserState, generics, ">"); + } + if (start >= end && generics.length === 0) { + return; + } + createQueryElement( + query, + parserState, + elems, + parserState.userQuery.slice(start, end), + generics); + } + + /** + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {Array<QueryElement>} elems - This is where the new {QueryElement} will be added. + * @param {string} limit - This function will stop when it'll encounter this + * character. + */ + function getItemsBefore(query, parserState, elems, limit) { + while (parserState.pos < parserState.length) { + var c = parserState.userQuery[parserState.pos]; + if (c === limit) { + break; + } else if (c === '(' || c === ":") { + // Something weird is going on in here. Ignoring it! + parserState.pos += 1; + continue; + } + var posBefore = parserState.pos; + getNextElem(query, parserState, elems, limit === ">"); + if (posBefore === parserState.pos) { + parserState.pos += 1; + } + } + // We skip the "limit". + parserState.pos += 1; + } + + /** + * @param {ParsedQuery} query + * @param {ParserState} parserState + */ + function parseInput(query, parserState) { + var c, before; + + while (parserState.pos < parserState.length) { + c = parserState.userQuery[parserState.pos]; + if (isStopCharacter(c)) { + if (c === "," || c === " ") { + parserState.pos += 1; + continue; + } else if (c === "-" && isReturnArrow(parserState)) { + break; + } + } else if (c == "(") { + break; + } else if (c === ":" && + parserState.typeFilter === null && + !isPathStart(parserState) && + query.elems.length === 1) + { + if (query.literalSearch) { + throw new Error("You cannot use quotes on type filter"); + } + // The type filter doesn't count as an element since it's a modifier. + parserState.typeFilter = query.elems.pop().name; + parserState.pos += 1; + parserState.totalElems = 0; + query.literalSearch = false; + continue; + } + before = query.elems.length; + getNextElem(query, parserState, query.elems, false); + if (query.elems.length === before) { + // Nothing was added, let's check it's not because of a solo ":"! + if (parserState.pos >= parserState.length || + parserState.userQuery[parserState.pos] !== ":") + { + break; + } + parserState.pos += 1; + } + } + while (parserState.pos < parserState.length) { + c = parserState.userQuery[parserState.pos]; + if (query.args.length === 0 && c === "(") { + parserState.pos += 1; + // Check for function/method arguments. + getItemsBefore(query, parserState, query.args, ")"); + } else if (isReturnArrow(parserState)) { + parserState.pos += 2; + // Get returned elements. + getItemsBefore(query, parserState, query.returned, ""); + // Nothing can come afterward! + break; + } else { + parserState.pos += 1; + } + } + } + + /** + * Takes the user search input and returns an empty `ParsedQuery`. + * + * @param {string} userQuery + * @return {ParsedQuery} + */ + function newParsedQuery(userQuery) { + return { + original: userQuery, + userQuery: userQuery.toLowerCase(), + typeFilter: NO_TYPE_FILTER, + elems: [], + args: [], + returned: [], + // Total number of "top" elements (does not include generics). + foundElems: 0, + literalSearch: false, + error: null, + }; + } + /** * Build an URL with search parameters. * @@ -158,7 +454,7 @@ window.initSearch = function(rawSearchIndex) { } /** - * Executes the query and builds an index of results + * Parses the query. * * The supported syntax by this parser is as follow: * @@ -222,274 +518,39 @@ window.initSearch = function(rawSearchIndex) { * @return {ParsedQuery} - The parsed query */ function parseQuery(userQuery) { - function isWhitespace(c) { - return " \t\n\r".indexOf(c) !== -1; - } - function isSpecialStartCharacter(c) { - return "(<\"".indexOf(c) !== -1; - } - function isStopCharacter(c) { - return isWhitespace(c) || "),>-=".indexOf(c) !== -1; - } - function getStringElem(query, isInGenerics) { - if (isInGenerics) { - throw new Error("`\"` cannot be used in generics"); - } else if (query.literalSearch) { - throw new Error("Cannot have more than one literal search element"); - } else if (query.totalElems !== 0) { - throw new Error("Cannot use literal search when there is more than one element"); - } - query.pos += 1; - while (query.pos < query.length && query.userQuery[query.pos] !== "\"") { - if (query.userQuery[query.pos] === "\\") { - // We ignore the next coming character. - query.pos += 1; - } - query.pos += 1; - } - if (query.pos >= query.length) { - throw new Error("Unclosed `\"`"); - } - // To skip the quote at the end. - query.pos += 1; - query.literalSearch = true; - } - function skipWhitespaces(query) { - while (query.pos < query.length) { - var c = query.userQuery[query.pos]; - if (!isWhitespace(c)) { - break; - } - query.pos += 1; - } - } - function skipStopCharacters(query) { - while (query.pos < query.length) { - var c = query.userQuery[query.pos]; - if (!isStopCharacter(c)) { - break; - } - query.pos += 1; - } - } - function isPathStart(query) { - var pos = query.pos; - return pos + 1 < query.length && query.userQuery[pos] === ':' && - query.userQuery[pos + 1] === ':'; - } - function isReturnArrow(query) { - var pos = query.pos; - return pos + 1 < query.length && query.userQuery[pos] === '-' && - query.userQuery[pos + 1] === '>'; - } - function removeEmptyStringsFromArray(x) { - for (var i = 0, len = x.length; i < len; ++i) { - if (x[i] === "") { - x.splice(i, 1); - i -= 1; - } - } - } - function createQueryElement(query, elems, name, generics) { - removeEmptyStringsFromArray(generics); - if (name === '*' || (name.length === 0 && generics.length === 0)) { - return; - } - if (query.literalSearch && query.totalElems > 0) { - throw new Error("You cannot have more than one element if you use quotes"); - } - var paths = name.split("::"); - removeEmptyStringsFromArray(paths); - // In case we only have something like `<p>`, there is no name but it remains valid. - if (paths.length === 0) { - paths = [""]; - } - elems.push({ - name: name, - fullPath: paths, - pathWithoutLast: paths.slice(0, paths.length - 1), - pathLast: paths[paths.length - 1], - generics: generics, - }); - query.totalElems += 1; - } - function getNextElem(query, elems, isInGenerics) { - var generics = []; - - skipStopCharacters(query); - var start = query.pos; - var end = start; - // We handle the strings on their own mostly to make code easier to follow. - if (query.userQuery[query.pos] === "\"") { - start += 1; - getStringElem(query, isInGenerics); - end = query.pos - 1; - skipWhitespaces(query); - } else { - while (query.pos < query.length) { - var c = query.userQuery[query.pos]; - if (isStopCharacter(c) || isSpecialStartCharacter(c)) { - break; - } - // If we allow paths ("str::string" for example). - else if (c === ":") { - if (!isPathStart(query)) { - break; - } - // Skip current ":". - query.pos += 1; - } - query.pos += 1; - end = query.pos; - skipWhitespaces(query); - } - } - if (query.pos < query.length && query.userQuery[query.pos] === "<") { - getItemsBefore(query, generics, ">"); - } - if (start >= end && generics.length === 0) { - return; - } - createQueryElement(query, elems, query.userQuery.slice(start, end), generics); - } - function getItemsBefore(query, elems, limit) { - while (query.pos < query.length) { - var c = query.userQuery[query.pos]; - if (c === limit) { - break; - } else if (isSpecialStartCharacter(c) || c === ":") { - // Something weird is going on in here. Ignoring it! - query.pos += 1; - } - getNextElem(query, elems, limit === ">"); - } - // We skip the "limit". - query.pos += 1; - } - function parseInput(query) { - var c, before; - - while (query.pos < query.length) { - c = query.userQuery[query.pos]; - if (isStopCharacter(c)) { - if (c === ",") { - query.pos += 1; - continue; - } else if (c === "-" && isReturnArrow(query)) { - break; - } - } else if (c == "(") { - break; - } else if (c === ":" && query.typeFilter === null && !isPathStart(query) && - query.elems.length === 1) - { - if (query.literalSearch) { - throw new Error("You cannot use quotes on type filter"); - } - // The type filter doesn't count as an element since it's a modifier. - query.typeFilter = query.elems.pop().name; - query.pos += 1; - query.totalElems = 0; - query.literalSearch = false; - continue; - } - before = query.elems.length; - getNextElem(query, query.elems, false); - if (query.elems.length === before) { - // Nothing was added, let's check it's not because of a solo ":"! - if (query.pos >= query.length || query.userQuery[query.pos] !== ":") { - break; - } - query.pos += 1; - } - } - while (query.pos < query.length) { - c = query.userQuery[query.pos]; - if (query.args.length === 0 && c === "(") { - if (query.elemName === null && query.elems.length === 1) { - query.elemName = query.elems.pop(); - } - // Check for function/method arguments. - getItemsBefore(query, query.args, ")"); - } else if (isReturnArrow(query)) { - // Get returned elements. - getItemsBefore(query, query.returned, ""); - // Nothing can come afterward! - break; - } else { - query.pos += 1; - } - } - } - function itemTypeFromName(typename) { - for (var i = 0, len = itemTypes.length; i < len; ++i) { - if (itemTypes[i] === typename) { - return i; - } - } - return NO_TYPE_FILTER; - } - userQuery = userQuery.trim(); - var query = { - original: userQuery, - userQuery: userQuery.toLowerCase(), + var parserState = { length: userQuery.length, pos: 0, - typeFilter: null, - elems: [], - elemName: null, - args: [], - returned: [], // Total number of elements (includes generics). totalElems: 0, - // Total number of "top" elements (does not include generics). - foundElems: 0, - // This field is used to check if it's needed to re-run a search or not. - id: "", - // This field is used in `sortResults`. - nameSplit: null, - literalSearch: false, - error: null, + typeFilter: null, + userQuery: userQuery.toLowerCase(), }; - query.id = userQuery; + var query = newParsedQuery(userQuery); + try { - parseInput(query); + parseInput(query, parserState); } catch (err) { + query = newParsedQuery(userQuery); query.error = err.message; - query.elems = []; - query.returned = []; - query.args = []; return query; } - query.foundElems = query.elems.length + query.args.length + query.returned.length; + if (!query.literalSearch) { // If there is more than one element in the query, we switch to literalSearch in any // case. - query.literalSearch = query.totalElems > 1; - } - if (query.elemName !== null) { - query.foundElems += 1; + query.literalSearch = parserState.totalElems > 1; } - if (query.foundElems === 0 && userQuery.length !== 0) { + query.foundElems = query.elems.length + query.args.length + query.returned.length; + if (query.foundElems === 0 && parserState.length !== 0) { // In this case, we'll simply keep whatever was entered by the user... - createQueryElement(query, query.elems, userQuery, []); + createQueryElement(query, parserState, query.elems, userQuery, []); query.foundElems += 1; } - if (query.typeFilter !== null) { - query.typeFilter = query.typeFilter.replace(/^const$/, "constant"); - query.typeFilter = itemTypeFromName(query.typeFilter); - } else { - query.typeFilter = NO_TYPE_FILTER; - } - // In case we only have one argument, we move it back to `elems` to keep things simple. - if (query.foundElems === 1 && query.elemName !== null) { - query.elems.push(query.elemName); - query.elemName = null; - } - if (query.elemName !== null || query.elems.length === 1) { - userQuery = query.elemName || query.elems[0]; - query.nameSplit = typeof userQuery.path === "undefined" ? null : userQuery.path; + if (parserState.typeFilter !== null) { + var typeFilter = parserState.typeFilter.replace(/^const$/, "constant"); + query.typeFilter = itemTypeFromName(typeFilter); } return query; } @@ -497,32 +558,32 @@ window.initSearch = function(rawSearchIndex) { /** * Creates the query results. * - * @param {Array<Object>} results_in_args - * @param {Array<Object>} results_returned - * @param {Array<Object>} results_in_args - * @param {ParsedQuery} queryInfo - * @return {Object} - A search index of results + * @param {Array<Result>} results_in_args + * @param {Array<Result>} results_returned + * @param {Array<Result>} results_in_args + * @param {ParsedQuery} parsedQuery + * @return {ResultsTable} */ - function createQueryResults(results_in_args, results_returned, results_others, queryInfo) { + function createQueryResults(results_in_args, results_returned, results_others, parsedQuery) { return { "in_args": results_in_args, "returned": results_returned, "others": results_others, - "query": queryInfo, + "query": parsedQuery, }; } /** - * Executes the query and builds an index of results + * Executes the parsed query and builds a {ResultsTable}. * - * @param {ParsedQuery} query - The user query - * @param {Object} searchWords - The list of search words to query against - * @param {Object} filterCrates - Crate to search in if defined - * @return {Object} - A search index of results + * @param {ParsedQuery} parsedQuery - The parsed user query + * @param {Object} searchWords - The list of search words to query against + * @param {Object} [filterCrates] - Crate to search in if defined + * @return {ResultsTable} */ - function execQuery(queryInfo, searchWords, filterCrates) { - if (queryInfo.error !== null) { - createQueryResults([], [], [], queryInfo); + function execQuery(parsedQuery, searchWords, filterCrates) { + if (parsedQuery.error !== null) { + createQueryResults([], [], [], parsedQuery); } var results_others = {}, results_in_args = {}, results_returned = {}; @@ -558,8 +619,12 @@ window.initSearch = function(rawSearchIndex) { } function sortResults(results, isType) { - var nameSplit = queryInfo.nameSplit; - var query = queryInfo.userQuery; + var nameSplit = null; + if (parsedQuery.elems.length === 1) { + var hasPath = typeof parsedQuery.elems[0].path === "undefined"; + nameSplit = hasPath ? null : parsedQuery.elems[0].path; + } + var query = parsedQuery.userQuery; var ar = []; for (var entry in results) { if (hasOwnPropertyRustdoc(results, entry)) { @@ -661,26 +726,26 @@ window.initSearch = function(rawSearchIndex) { } /** - * This function checks if the object (`obj`) generics match the given type (`val`) - * generics. If there are no generics on `obj`, `defaultLev` is returned. + * This function checks if the object (`row`) generics match the given type (`elem`) + * generics. If there are no generics on `row`, `defaultLev` is returned. * - * @param {Row} obj - The object to check. - * @param {QueryElement} val - The element from the parsed query. + * @param {Row} row - The object to check. + * @param {QueryElement} elem - The element from the parsed query. * @param {integer} defaultLev - This is the value to return in case there are no generics. * * @return {integer} - Returns the best match (if any) or `MAX_LEV_DISTANCE + 1`. */ - function checkGenerics(obj, val, defaultLev) { - if (obj.length <= GENERICS_DATA || obj[GENERICS_DATA].length === 0) { - return val.generics.length === 0 ? defaultLev : MAX_LEV_DISTANCE + 1; + function checkGenerics(row, elem, defaultLev) { + if (row.length <= GENERICS_DATA || row[GENERICS_DATA].length === 0) { + return elem.generics.length === 0 ? defaultLev : MAX_LEV_DISTANCE + 1; } // The names match, but we need to be sure that all generics kinda // match as well. var elem_name; - if (val.generics.length > 0 && obj[GENERICS_DATA].length >= val.generics.length) { + if (elem.generics.length > 0 && row[GENERICS_DATA].length >= elem.generics.length) { var elems = {}; - for (var x = 0, length = obj[GENERICS_DATA].length; x < length; ++x) { - elem_name = obj[GENERICS_DATA][x][NAME]; + for (var x = 0, length = row[GENERICS_DATA].length; x < length; ++x) { + elem_name = row[GENERICS_DATA][x][NAME]; if (!elems[elem_name]) { elems[elem_name] = 0; } @@ -688,8 +753,8 @@ window.initSearch = function(rawSearchIndex) { } // We need to find the type that matches the most to remove it in order // to move forward. - for (x = 0, length = val.generics.length; x < length; ++x) { - var generic = val.generics[x]; + for (x = 0, length = elem.generics.length; x < length; ++x) { + var generic = elem.generics[x]; var match = null; if (elems[generic.name]) { match = generic.name; @@ -718,19 +783,19 @@ window.initSearch = function(rawSearchIndex) { } /** - * This function checks if the object (`obj`) matches the given type (`val`) and its + * This function checks if the object (`row`) matches the given type (`elem`) and its * generics (if any). * - * @param {Row} obj - * @param {QueryElement} val - The element from the parsed query. + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. * * @return {integer} - Returns a Levenshtein distance to the best match. */ - function checkIfInGenerics(obj, val) { + function checkIfInGenerics(row, elem) { var lev = MAX_LEV_DISTANCE + 1; - for (var x = 0, length = obj[GENERICS_DATA].length; x < length && lev !== 0; ++x) { + for (var x = 0, length = row[GENERICS_DATA].length; x < length && lev !== 0; ++x) { lev = Math.min( - checkType(obj[GENERICS_DATA][x], val, true), + checkType(row[GENERICS_DATA][x], elem, true), lev ); } @@ -738,51 +803,51 @@ window.initSearch = function(rawSearchIndex) { } /** - * This function checks if the object (`obj`) matches the given type (`val`) and its + * This function checks if the object (`row`) matches the given type (`elem`) and its * generics (if any). * - * @param {Row} obj - * @param {QueryElement} val - The element from the parsed query. + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. * @param {boolean} literalSearch * * @return {integer} - Returns a Levenshtein distance to the best match. If there is * no match, returns `MAX_LEV_DISTANCE + 1`. */ - function checkType(obj, val, literalSearch) { - if (val.name.length === 0 || obj[NAME].length === 0) { + function checkType(row, elem, literalSearch) { + if (elem.name.length === 0 || row[NAME].length === 0) { // This is a pure "generic" search, no need to run other checks. - if (obj.length > GENERICS_DATA) { - return checkIfInGenerics(obj, val); + if (row.length > GENERICS_DATA) { + return checkIfInGenerics(row, elem); } return MAX_LEV_DISTANCE + 1; } - var lev = levenshtein(obj[NAME], val.name); + var lev = levenshtein(row[NAME], elem.name); if (literalSearch) { if (lev !== 0) { // The name didn't match, let's try to check if the generics do. - if (val.generics.length === 0) { - var checkGeneric = (obj.length > GENERICS_DATA && - obj[GENERICS_DATA].length > 0); - if (checkGeneric && obj[GENERICS_DATA].findIndex(function(elem) { - return elem[NAME] === val.name; + if (elem.generics.length === 0) { + var checkGeneric = (row.length > GENERICS_DATA && + row[GENERICS_DATA].length > 0); + if (checkGeneric && row[GENERICS_DATA].findIndex(function(tmp_elem) { + return tmp_elem[NAME] === elem.name; }) !== -1) { return 0; } } return MAX_LEV_DISTANCE + 1; - } else if (val.generics.length > 0) { - return checkGenerics(obj, val, MAX_LEV_DISTANCE + 1); + } else if (elem.generics.length > 0) { + return checkGenerics(row, elem, MAX_LEV_DISTANCE + 1); } return 0; - } else if (obj.length > GENERICS_DATA) { - if (val.generics.length === 0) { + } else if (row.length > GENERICS_DATA) { + if (elem.generics.length === 0) { if (lev === 0) { return 0; } // The name didn't match so we now check if the type we're looking for is inside // the generics! - lev = checkIfInGenerics(obj, val); + lev = checkIfInGenerics(row, elem); // Now whatever happens, the returned distance is "less good" so we should mark // it as such, and so we add 0.5 to the distance to make it "less good". return lev + 0.5; @@ -791,18 +856,18 @@ window.initSearch = function(rawSearchIndex) { // // Maybe it's present in a sub generic? For example "f<A<B<C>>>()", if we're // looking for "B<C>", we'll need to go down. - return checkIfInGenerics(obj, val); + return checkIfInGenerics(row, elem); } else { // At this point, the name kinda match and we have generics to check, so // let's go! - var tmp_lev = checkGenerics(obj, val, lev); + var tmp_lev = checkGenerics(row, elem, lev); if (tmp_lev > MAX_LEV_DISTANCE) { return MAX_LEV_DISTANCE + 1; } // We compute the median value of both checks and return it. return (tmp_lev + lev) / 2; } - } else if (val.generics.length > 0) { + } else if (elem.generics.length > 0) { // In this case, we were expecting generics but there isn't so we simply reject this // one. return MAX_LEV_DISTANCE + 1; @@ -813,64 +878,62 @@ window.initSearch = function(rawSearchIndex) { } /** - * This function checks if the object (`obj`) has an argument with the given type (`val`). + * This function checks if the object (`row`) has an argument with the given type (`elem`). * - * @param {Row} obj - * @param {QueryElement} val - The element from the parsed query. + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. * @param {integer} typeFilter * * @return {integer} - Returns a Levenshtein distance to the best match. If there is no * match, returns `MAX_LEV_DISTANCE + 1`. */ - function findArg(obj, val, typeFilter) { + function findArg(row, elem, typeFilter) { var lev = MAX_LEV_DISTANCE + 1; - var tmp; - if (obj && obj.type && obj.type[INPUTS_DATA] && obj.type[INPUTS_DATA].length > 0) { - var length = obj.type[INPUTS_DATA].length; + if (row && row.type && row.type[INPUTS_DATA] && row.type[INPUTS_DATA].length > 0) { + var length = row.type[INPUTS_DATA].length; for (var i = 0; i < length; i++) { - tmp = obj.type[INPUTS_DATA][i]; + var tmp = row.type[INPUTS_DATA][i]; if (!typePassesFilter(typeFilter, tmp[1])) { continue; } - lev = Math.min(lev, checkType(tmp, val, queryInfo.literalSearch)); + lev = Math.min(lev, checkType(tmp, elem, parsedQuery.literalSearch)); if (lev === 0) { return 0; } } } - return queryInfo.literalSearch ? MAX_LEV_DISTANCE + 1 : lev; + return parsedQuery.literalSearch ? MAX_LEV_DISTANCE + 1 : lev; } /** - * @param {Row} obj - * @param {QueryElement} val - The element from the parsed query. + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. * @param {integer} typeFilter * * @return {integer} - Returns a Levenshtein distance to the best match. If there is no * match, returns `MAX_LEV_DISTANCE + 1`. */ - function checkReturned(obj, val, typeFilter) { + function checkReturned(row, elem, typeFilter) { var lev = MAX_LEV_DISTANCE + 1; - var tmp; - if (obj && obj.type && obj.type.length > OUTPUT_DATA) { - var ret = obj.type[OUTPUT_DATA]; + if (row && row.type && row.type.length > OUTPUT_DATA) { + var ret = row.type[OUTPUT_DATA]; if (typeof ret[0] === "string") { ret = [ret]; } for (var x = 0, len = ret.length; x < len; ++x) { - tmp = ret[x]; + var tmp = ret[x]; if (!typePassesFilter(typeFilter, tmp[1])) { continue; } - lev = Math.min(lev, checkType(tmp, val, queryInfo.literalSearch)); + lev = Math.min(lev, checkType(tmp, elem, parsedQuery.literalSearch)); if (lev === 0) { return 0; } } } - return queryInfo.literalSearch ? MAX_LEV_DISTANCE + 1 : lev; + return parsedQuery.literalSearch ? MAX_LEV_DISTANCE + 1 : lev; } function checkPath(contains, lastElem, ty) { @@ -945,13 +1008,14 @@ window.initSearch = function(rawSearchIndex) { } function handleAliases(ret, query, filterCrates) { + var lowerQuery = query.toLowerCase(); // We separate aliases and crate aliases because we want to have current crate // aliases to be before the others in the displayed results. var aliases = []; var crateAliases = []; if (filterCrates !== null) { - if (ALIASES[filterCrates] && ALIASES[filterCrates][query]) { - var query_aliases = ALIASES[filterCrates][query]; + if (ALIASES[filterCrates] && ALIASES[filterCrates][lowerQuery]) { + var query_aliases = ALIASES[filterCrates][lowerQuery]; var len = query_aliases.length; for (var i = 0; i < len; ++i) { aliases.push(createAliasFromItem(searchIndex[query_aliases[i]])); @@ -959,9 +1023,9 @@ window.initSearch = function(rawSearchIndex) { } } else { Object.keys(ALIASES).forEach(function(crate) { - if (ALIASES[crate][query]) { + if (ALIASES[crate][lowerQuery]) { var pushTo = crate === window.currentCrate ? crateAliases : aliases; - var query_aliases = ALIASES[crate][query]; + var query_aliases = ALIASES[crate][lowerQuery]; var len = query_aliases.length; for (var i = 0; i < len; ++i) { pushTo.push(createAliasFromItem(searchIndex[query_aliases[i]])); @@ -998,37 +1062,37 @@ window.initSearch = function(rawSearchIndex) { } /** - * This function adds the given result into the provided `res` map if it matches the + * This function adds the given result into the provided `results` map if it matches the * following condition: * - * * If it is a "literal search" (`queryInfo.literalSearch`), then `lev` must be 0. + * * If it is a "literal search" (`parsedQuery.literalSearch`), then `lev` must be 0. * * If it is not a "literal search", `lev` must be <= `MAX_LEV_DISTANCE`. * - * The `res` map contains information which will be used to sort the search results: + * The `results` map contains information which will be used to sort the search results: * - * * `fullId` is a `string`` used as the key of the object we use for the `res` map. + * * `fullId` is a `string`` used as the key of the object we use for the `results` map. * * `id` is the index in both `searchWords` and `searchIndex` arrays for this element. * * `index` is an `integer`` used to sort by the position of the word in the item's name. * * `lev` is the main metric used to sort the search results. * - * @param {Object} res + * @param {Object} results * @param {string} fullId * @param {integer} id * @param {integer} index * @param {integer} lev */ - function addIntoResults(res, fullId, id, index, lev) { - if (lev === 0 || (!queryInfo.literalSearch && lev <= MAX_LEV_DISTANCE)) { - if (res[fullId] !== undefined) { - var result = res[fullId]; + function addIntoResults(results, fullId, id, index, lev) { + if (lev === 0 || (!parsedQuery.literalSearch && lev <= MAX_LEV_DISTANCE)) { + if (results[fullId] !== undefined) { + var result = results[fullId]; if (result.dontValidate || result.lev <= lev) { return; } } - res[fullId] = { + results[fullId] = { id: id, index: index, - dontValidate: queryInfo.literalSearch, + dontValidate: parsedQuery.literalSearch, lev: lev, }; } @@ -1037,29 +1101,29 @@ window.initSearch = function(rawSearchIndex) { /** * This function is called in case the query is only one element (with or without generics). * - * @param {Row} ty + * @param {Row} row * @param {integer} pos - Position in the `searchIndex`. * @param {QueryElement} elem - The element from the parsed query. */ - function handleSingleArg(ty, pos, elem) { - if (!ty || (filterCrates !== null && ty.crate !== filterCrates)) { + function handleSingleArg(row, pos, elem) { + if (!row || (filterCrates !== null && row.crate !== filterCrates)) { return; } var lev, lev_add = 0, index = -1; - var fullId = ty.id; + var fullId = row.id; - var in_args = findArg(ty, elem, queryInfo.typeFilter); - var returned = checkReturned(ty, elem, queryInfo.typeFilter); + var in_args = findArg(row, elem, parsedQuery.typeFilter); + var returned = checkReturned(row, elem, parsedQuery.typeFilter); addIntoResults(results_in_args, fullId, pos, index, in_args); addIntoResults(results_returned, fullId, pos, index, returned); - if (!typePassesFilter(queryInfo.typeFilter, ty.ty)) { + if (!typePassesFilter(parsedQuery.typeFilter, row.ty)) { return; } var searchWord = searchWords[pos]; - if (queryInfo.literalSearch) { + if (parsedQuery.literalSearch) { if (searchWord === elem.name) { addIntoResults(results_others, fullId, pos, -1, 0); } @@ -1068,16 +1132,16 @@ window.initSearch = function(rawSearchIndex) { // No need to check anything else if it's a "pure" generics search. if (elem.name.length === 0) { - if (ty.type !== null) { - lev = checkGenerics(ty.type, elem, MAX_LEV_DISTANCE + 1); + if (row.type !== null) { + lev = checkGenerics(row.type, elem, MAX_LEV_DISTANCE + 1); addIntoResults(results_others, fullId, pos, index, lev); } return; } if (elem.fullPath.length > 1) { - lev = checkPath(elem.pathWithoutLast, elem.pathLast, ty); - if (lev > MAX_LEV_DISTANCE || (queryInfo.literalSearch && lev !== 0)) { + lev = checkPath(elem.pathWithoutLast, elem.pathLast, row); + if (lev > MAX_LEV_DISTANCE || (parsedQuery.literalSearch && lev !== 0)) { return; } else if (lev > 0) { lev_add = lev / 10; @@ -1085,16 +1149,16 @@ window.initSearch = function(rawSearchIndex) { } if (searchWord.indexOf(elem.pathLast) > -1 || - ty.normalizedName.indexOf(elem.pathLast) > -1) + row.normalizedName.indexOf(elem.pathLast) > -1) { // filter type: ... queries if (!results_others[fullId] !== undefined) { - index = ty.normalizedName.indexOf(elem.pathLast); + index = row.normalizedName.indexOf(elem.pathLast); } } lev = levenshtein(searchWord, elem.pathLast); lev += lev_add; - if (lev > 0 && elem.pathLast.length > 3 && searchWord.indexOf(elem.pathLast) > -1) + if (lev > 0 && elem.pathLast.length > 2 && searchWord.indexOf(elem.pathLast) > -1) { if (elem.pathLast.length < 6) { lev = 1; @@ -1116,27 +1180,25 @@ window.initSearch = function(rawSearchIndex) { /** * This function is called in case the query has more than one element. * - * @param {Object} ty - * @param {integer} pos - Position in the `searchIndex`. - * @param {Object} elem - The element from the parsed query. + * @param {Row} row + * @param {integer} pos - Position in the `searchIndex`. + * @param {Object} results */ - function handleArgs(ty, pos, results) { - if (!ty || (filterCrates !== null && ty.crate !== filterCrates)) { + function handleArgs(row, pos, results) { + if (!row || (filterCrates !== null && row.crate !== filterCrates)) { return; } var totalLev = 0; var nbLev = 0; var lev; - var i, len; - var el; // If the result is too "bad", we return false and it ends this search. - function checkArgs(args, callback) { - for (i = 0, len = args.length; i < len; ++i) { - el = args[i]; + function checkArgs(elems, callback) { + for (var i = 0, len = elems.length; i < len; ++i) { + var elem = elems[i]; // There is more than one parameter to the query so all checks should be "exact" - lev = callback(ty, el, NO_TYPE_FILTER); + lev = callback(row, elem, NO_TYPE_FILTER); if (lev <= 1) { nbLev += 1; totalLev += lev; @@ -1146,13 +1208,13 @@ window.initSearch = function(rawSearchIndex) { } return true; } - if (!checkArgs(queryInfo.elems, findArg)) { + if (!checkArgs(parsedQuery.elems, findArg)) { return; } - if (!checkArgs(queryInfo.args, findArg)) { + if (!checkArgs(parsedQuery.args, findArg)) { return; } - if (!checkArgs(queryInfo.returned, checkReturned)) { + if (!checkArgs(parsedQuery.returned, checkReturned)) { return; } @@ -1160,43 +1222,43 @@ window.initSearch = function(rawSearchIndex) { return; } lev = Math.round(totalLev / nbLev); - addIntoResults(results, ty.id, pos, 0, lev); + addIntoResults(results, row.id, pos, 0, lev); } function innerRunQuery() { - var elem, i, nSearchWords, in_args, in_returned, ty; + var elem, i, nSearchWords, in_args, in_returned, row; - if (queryInfo.foundElems === 1) { - if (queryInfo.elems.length === 1) { - elem = queryInfo.elems[0]; + if (parsedQuery.foundElems === 1) { + if (parsedQuery.elems.length === 1) { + elem = parsedQuery.elems[0]; for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { // It means we want to check for this element everywhere (in names, args and // returned). handleSingleArg(searchIndex[i], i, elem); } - } else if (queryInfo.args.length === 1) { + } else if (parsedQuery.args.length === 1) { // We received one argument to check, so looking into args. - elem = queryInfo.args[0]; + elem = parsedQuery.args[0]; for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { - ty = searchIndex[i]; - in_args = findArg(ty, elem, queryInfo.typeFilter); - addIntoResults(results_in_args, ty.id, i, -1, in_args); + row = searchIndex[i]; + in_args = findArg(row, elem, parsedQuery.typeFilter); + addIntoResults(results_in_args, row.id, i, -1, in_args); } - } else if (queryInfo.returned.length === 1) { + } else if (parsedQuery.returned.length === 1) { // We received one returned argument to check, so looking into returned values. - elem = queryInfo.returned[0]; + elem = parsedQuery.returned[0]; for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { - ty = searchIndex[i]; - in_returned = checkReturned(ty, elem, queryInfo.typeFilter); - addIntoResults(results_returned, ty.id, i, -1, in_returned); + row = searchIndex[i]; + in_returned = checkReturned(row, elem, parsedQuery.typeFilter); + addIntoResults(results_returned, row.id, i, -1, in_returned); } } - } else if (queryInfo.foundElems > 0) { + } else if (parsedQuery.foundElems > 0) { var container = results_others; // In the special case where only a "returned" information is available, we want to // put the information into the "results_returned" dict. - if (queryInfo.returned.length !== 0 && queryInfo.elemName === null && - queryInfo.args.length === 0 && queryInfo.elems.length === 0) + if (parsedQuery.returned.length !== 0 && parsedQuery.args.length === 0 && + parsedQuery.elems.length === 0) { container = results_returned; } @@ -1211,8 +1273,8 @@ window.initSearch = function(rawSearchIndex) { sortResults(results_in_args, true), sortResults(results_returned, true), sortResults(results_others, false), - queryInfo); - handleAliases(ret, queryInfo.original.replace(/"/g, "").toLowerCase(), filterCrates); + parsedQuery); + handleAliases(ret, parsedQuery.original.replace(/"/g, ""), filterCrates); return ret; } @@ -1434,6 +1496,11 @@ window.initSearch = function(rawSearchIndex) { return "<button>" + text + " <div class=\"count\">(" + nbElems + ")</div></button>"; } + /** + * @param {ResultsTable} results + * @param {boolean} go_to_first + * @param {string} filterCrates + */ function showResults(results, go_to_first, filterCrates) { var search = searchState.outputElement(); if (go_to_first || (results.others.length === 1 @@ -1455,7 +1522,7 @@ window.initSearch = function(rawSearchIndex) { results.query = parseQuery(searchState.input.value); } - currentResults = results.query.id; + currentResults = results.query.userQuery; var ret_others = addTab(results.others, results.query, true); var ret_in_args = addTab(results.in_args, results.query, false); @@ -1535,7 +1602,7 @@ window.initSearch = function(rawSearchIndex) { e.preventDefault(); } - if (!forced && query.id === currentResults) { + if (!forced && query.userQuery === currentResults) { if (query.userQuery.length > 0) { putBackSearch(); } diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml index 828c20860a6..901634fe0e6 100644 --- a/src/test/rustdoc-gui/search-result-color.goml +++ b/src/test/rustdoc-gui/search-result-color.goml @@ -1,5 +1,5 @@ // The goal of this test is to ensure the color of the text is the one expected. -goto: file://|DOC_PATH|/test_docs/index.html?search=cook +goto: file://|DOC_PATH|/test_docs/index.html?search=coo // This is needed so that the text color is computed. show-text: true diff --git a/src/test/rustdoc-js-std/parser-errors.js b/src/test/rustdoc-js-std/parser-errors.js index c5d106120ad..887ac38f417 100644 --- a/src/test/rustdoc-js-std/parser-errors.js +++ b/src/test/rustdoc-js-std/parser-errors.js @@ -3,66 +3,51 @@ const QUERY = ['<"P">', '"P" "P"', 'P "P"', '"p" p', '"const": p']; const PARSED = [ { args: [], - elemName: null, elems: [], foundElems: 0, - id: "<\"P\">", - nameSplit: null, original: "<\"P\">", returned: [], - typeFilter: null, + typeFilter: -1, userQuery: "<\"p\">", error: "`\"` cannot be used in generics", }, { args: [], - elemName: null, elems: [], foundElems: 0, - id: "\"P\" \"P\"", - nameSplit: null, original: "\"P\" \"P\"", returned: [], - typeFilter: null, + typeFilter: -1, userQuery: "\"p\" \"p\"", error: "Cannot have more than one literal search element", }, { args: [], - elemName: null, elems: [], foundElems: 0, - id: "P \"P\"", - nameSplit: null, original: "P \"P\"", returned: [], - typeFilter: null, + typeFilter: -1, userQuery: "p \"p\"", error: "Cannot use literal search when there is more than one element", }, { args: [], - elemName: null, elems: [], foundElems: 0, - id: "\"p\" p", - nameSplit: null, original: "\"p\" p", returned: [], - typeFilter: null, + typeFilter: -1, userQuery: "\"p\" p", error: "You cannot have more than one element if you use quotes", }, { args: [], - elemName: null, elems: [], foundElems: 0, - id: "\"const\": p", - nameSplit: null, original: "\"const\": p", returned: [], - typeFilter: null, + typeFilter: -1, userQuery: "\"const\": p", error: "You cannot use quotes on type filter", }, diff --git a/src/test/rustdoc-js-std/parser-filter.js b/src/test/rustdoc-js-std/parser-filter.js index 60eb8aa92b2..49fa66b5bb3 100644 --- a/src/test/rustdoc-js-std/parser-filter.js +++ b/src/test/rustdoc-js-std/parser-filter.js @@ -3,7 +3,6 @@ const QUERY = ['fn:foo', 'enum : foo', 'macro<f>:foo']; const PARSED = [ { args: [], - elemName: null, elems: [{ name: "foo", fullPath: ["foo"], @@ -12,8 +11,6 @@ const PARSED = [ generics: [], }], foundElems: 1, - id: "fn:foo", - nameSplit: null, original: "fn:foo", returned: [], typeFilter: 5, @@ -22,7 +19,6 @@ const PARSED = [ }, { args: [], - elemName: null, elems: [{ name: "foo", fullPath: ["foo"], @@ -31,8 +27,6 @@ const PARSED = [ generics: [], }], foundElems: 1, - id: "enum : foo", - nameSplit: null, original: "enum : foo", returned: [], typeFilter: 4, @@ -41,7 +35,6 @@ const PARSED = [ }, { args: [], - elemName: null, elems: [{ name: "foo", fullPath: ["foo"], @@ -50,8 +43,6 @@ const PARSED = [ generics: [], }], foundElems: 1, - id: "macro<f>:foo", - nameSplit: null, original: "macro<f>:foo", returned: [], typeFilter: 14, diff --git a/src/test/rustdoc-js-std/parser-generics.js b/src/test/rustdoc-js-std/parser-generics.js index d21adf767de..34d33ed4d67 100644 --- a/src/test/rustdoc-js-std/parser-generics.js +++ b/src/test/rustdoc-js-std/parser-generics.js @@ -1,9 +1,8 @@ -const QUERY = ['<P>', 'A<B<C<D>, E>']; +const QUERY = ['<P>', 'A<B<C<D>, E>', 'p<> u8']; const PARSED = [ { args: [], - elemName: null, elems: [{ name: "", fullPath: [""], @@ -20,8 +19,6 @@ const PARSED = [ ], }], foundElems: 1, - id: "<P>", - nameSplit: null, original: "<P>", returned: [], typeFilter: -1, @@ -30,7 +27,6 @@ const PARSED = [ }, { args: [], - elemName: null, elems: [{ name: "a", fullPath: ["a"], @@ -70,12 +66,35 @@ const PARSED = [ ], }], foundElems: 1, - id: 'A<B<C<D>, E>', - nameSplit: null, original: 'A<B<C<D>, E>', returned: [], typeFilter: -1, userQuery: 'a<b<c<d>, e>', error: null, - } + }, + { + args: [], + elems: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }, + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [], + }, + ], + foundElems: 2, + original: "p<> u8", + returned: [], + typeFilter: -1, + userQuery: "p<> u8", + error: null, + }, ]; diff --git a/src/test/rustdoc-js-std/parser-in_args.js b/src/test/rustdoc-js-std/parser-in_args.js index 88761771d9d..e74e423ceed 100644 --- a/src/test/rustdoc-js-std/parser-in_args.js +++ b/src/test/rustdoc-js-std/parser-in_args.js @@ -9,11 +9,8 @@ const PARSED = [ pathLast: "whatever", generics: [], }], - elemName: null, elems: [], foundElems: 1, - id: "(whatever)", - nameSplit: null, original: "(whatever)", returned: [], typeFilter: -1, @@ -36,11 +33,8 @@ const PARSED = [ }, ], }], - elemName: null, elems: [], foundElems: 1, - id: "(<P>)", - nameSplit: null, original: "(<P>)", returned: [], typeFilter: -1, diff --git a/src/test/rustdoc-js-std/parser-invalid.js b/src/test/rustdoc-js-std/parser-invalid.js index b5d96e9f507..5e7be3c73b0 100644 --- a/src/test/rustdoc-js-std/parser-invalid.js +++ b/src/test/rustdoc-js-std/parser-invalid.js @@ -6,11 +6,8 @@ const QUERY = ['-> <P> (p2)', '(p -> p2', 'a b', 'a,b(c)']; const PARSED = [ { args: [], - elemName: null, elems: [], foundElems: 2, - id: "-> <P> (p2)", - nameSplit: null, original: "-> <P> (p2)", returned: [ { @@ -57,11 +54,8 @@ const PARSED = [ generics: [], }, ], - elemName: null, elems: [], foundElems: 2, - id: "(p -> p2", - nameSplit: null, original: "(p -> p2", returned: [], typeFilter: -1, @@ -70,7 +64,6 @@ const PARSED = [ }, { args: [], - elemName: null, elems: [ { name: "a b", @@ -81,8 +74,6 @@ const PARSED = [ }, ], foundElems: 1, - id: "a b", - nameSplit: null, original: "a b", returned: [], typeFilter: -1, @@ -99,7 +90,6 @@ const PARSED = [ generics: [], }, ], - elemName: null, elems: [ { name: "a", @@ -117,8 +107,6 @@ const PARSED = [ }, ], foundElems: 3, - id: "a,b(c)", - nameSplit: null, original: "a,b(c)", returned: [], typeFilter: -1, diff --git a/src/test/rustdoc-js-std/parser-literal.js b/src/test/rustdoc-js-std/parser-literal.js index f1713fbaf88..f8c73672922 100644 --- a/src/test/rustdoc-js-std/parser-literal.js +++ b/src/test/rustdoc-js-std/parser-literal.js @@ -3,7 +3,6 @@ const QUERY = ['R<P>']; const PARSED = [ { args: [], - elemName: null, elems: [{ name: "r", fullPath: ["r"], @@ -20,8 +19,6 @@ const PARSED = [ ], }], foundElems: 1, - id: "R<P>", - nameSplit: null, original: "R<P>", returned: [], typeFilter: -1, diff --git a/src/test/rustdoc-js-std/parser-paths.js b/src/test/rustdoc-js-std/parser-paths.js index 980a396ba7f..1bd3bb61dc9 100644 --- a/src/test/rustdoc-js-std/parser-paths.js +++ b/src/test/rustdoc-js-std/parser-paths.js @@ -3,7 +3,6 @@ const QUERY = ['A::B', '::A::B', 'A::B::,C', 'A::B::<f>,C']; const PARSED = [ { args: [], - elemName: null, elems: [{ name: "a::b", fullPath: ["a", "b"], @@ -12,8 +11,6 @@ const PARSED = [ generics: [], }], foundElems: 1, - id: "A::B", - nameSplit: null, original: "A::B", returned: [], typeFilter: -1, @@ -22,7 +19,6 @@ const PARSED = [ }, { args: [], - elemName: null, elems: [{ name: "::a::b", fullPath: ["a", "b"], @@ -31,8 +27,6 @@ const PARSED = [ generics: [], }], foundElems: 1, - id: '::A::B', - nameSplit: null, original: '::A::B', returned: [], typeFilter: -1, @@ -41,7 +35,6 @@ const PARSED = [ }, { args: [], - elemName: null, elems: [ { name: "a::b::", @@ -59,8 +52,6 @@ const PARSED = [ }, ], foundElems: 2, - id: 'A::B::,C', - nameSplit: null, original: 'A::B::,C', returned: [], typeFilter: -1, @@ -69,7 +60,6 @@ const PARSED = [ }, { args: [], - elemName: null, elems: [ { name: "a::b::", @@ -95,8 +85,6 @@ const PARSED = [ }, ], foundElems: 2, - id: 'A::B::<f>,C', - nameSplit: null, original: 'A::B::<f>,C', returned: [], typeFilter: -1, diff --git a/src/test/rustdoc-js-std/parser-quote.js b/src/test/rustdoc-js-std/parser-quote.js index 1c59a3d50ee..07af9249172 100644 --- a/src/test/rustdoc-js-std/parser-quote.js +++ b/src/test/rustdoc-js-std/parser-quote.js @@ -3,11 +3,8 @@ const QUERY = ['-> "p"', '("p")']; const PARSED = [ { args: [], - elemName: null, elems: [], foundElems: 1, - id: "-> \"p\"", - nameSplit: null, original: "-> \"p\"", returned: [{ name: "p", @@ -28,11 +25,8 @@ const PARSED = [ pathLast: "p", generics: [], }], - elemName: null, elems: [], foundElems: 1, - id: "(\"p\")", - nameSplit: null, original: "(\"p\")", returned: [], typeFilter: -1, diff --git a/src/test/rustdoc-js-std/parser-returned.js b/src/test/rustdoc-js-std/parser-returned.js index ceecda67050..face0a7461d 100644 --- a/src/test/rustdoc-js-std/parser-returned.js +++ b/src/test/rustdoc-js-std/parser-returned.js @@ -3,11 +3,8 @@ const QUERY = ['-> <P>', '-> P']; const PARSED = [ { args: [], - elemName: null, elems: [], foundElems: 1, - id: "-> <P>", - nameSplit: null, original: "-> <P>", returned: [{ name: "", @@ -30,11 +27,8 @@ const PARSED = [ }, { args: [], - elemName: null, elems: [], foundElems: 1, - id: "-> P", - nameSplit: null, original: "-> P", returned: [{ name: "p", diff --git a/src/test/rustdoc-js-std/vec-new.js b/src/test/rustdoc-js-std/vec-new.js index e1a3256876b..cd0e8e7b4a9 100644 --- a/src/test/rustdoc-js-std/vec-new.js +++ b/src/test/rustdoc-js-std/vec-new.js @@ -4,6 +4,6 @@ const EXPECTED = { 'others': [ { 'path': 'std::vec::Vec', 'name': 'new' }, { 'path': 'std::vec::Vec', 'name': 'ne' }, - { 'path': 'std::rc::Rc', 'name': 'ne' }, + { 'path': 'alloc::vec::Vec', 'name': 'ne' }, ], }; diff --git a/src/test/rustdoc-js/doc-alias-whitespace.js b/src/test/rustdoc-js/doc-alias-whitespace.js index 3ee55fe455d..c9fc0c4311f 100644 --- a/src/test/rustdoc-js/doc-alias-whitespace.js +++ b/src/test/rustdoc-js/doc-alias-whitespace.js @@ -10,7 +10,7 @@ const EXPECTED = [ { 'path': 'doc_alias_whitespace', 'name': 'Struct', - 'alias': 'demon lord', + 'alias': 'Demon Lord', 'href': '../doc_alias_whitespace/struct.Struct.html', 'is_alias': true }, diff --git a/src/test/rustdoc-js/doc-alias.js b/src/test/rustdoc-js/doc-alias.js index f450bf97981..7bb0cbe388f 100644 --- a/src/test/rustdoc-js/doc-alias.js +++ b/src/test/rustdoc-js/doc-alias.js @@ -32,7 +32,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Struct', - 'alias': 'structitem', + 'alias': 'StructItem', 'href': '../doc_alias/struct.Struct.html', 'is_alias': true }, @@ -44,7 +44,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Struct', 'name': 'field', - 'alias': 'structfielditem', + 'alias': 'StructFieldItem', 'href': '../doc_alias/struct.Struct.html#structfield.field', 'is_alias': true }, @@ -56,7 +56,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Struct', 'name': 'method', - 'alias': 'structmethoditem', + 'alias': 'StructMethodItem', 'href': '../doc_alias/struct.Struct.html#method.method', 'is_alias': true }, @@ -72,7 +72,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Struct', 'name': 'ImplConstItem', - 'alias': 'structimplconstitem', + 'alias': 'StructImplConstItem', 'href': '../doc_alias/struct.Struct.html#associatedconstant.ImplConstItem', 'is_alias': true }, @@ -84,7 +84,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Struct', 'name': 'function', - 'alias': 'impltraitfunction', + 'alias': 'ImplTraitFunction', 'href': '../doc_alias/struct.Struct.html#method.function', 'is_alias': true }, @@ -96,7 +96,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Enum', - 'alias': 'enumitem', + 'alias': 'EnumItem', 'href': '../doc_alias/enum.Enum.html', 'is_alias': true }, @@ -108,7 +108,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Enum', 'name': 'Variant', - 'alias': 'variantitem', + 'alias': 'VariantItem', 'href': '../doc_alias/enum.Enum.html#variant.Variant', 'is_alias': true }, @@ -120,7 +120,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Enum', 'name': 'method', - 'alias': 'enummethoditem', + 'alias': 'EnumMethodItem', 'href': '../doc_alias/enum.Enum.html#method.method', 'is_alias': true }, @@ -132,7 +132,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Typedef', - 'alias': 'typedefitem', + 'alias': 'TypedefItem', 'href': '../doc_alias/type.Typedef.html', 'is_alias': true }, @@ -144,7 +144,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Trait', - 'alias': 'traititem', + 'alias': 'TraitItem', 'href': '../doc_alias/trait.Trait.html', 'is_alias': true }, @@ -156,7 +156,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Trait', 'name': 'Target', - 'alias': 'traittypeitem', + 'alias': 'TraitTypeItem', 'href': '../doc_alias/trait.Trait.html#associatedtype.Target', 'is_alias': true }, @@ -168,7 +168,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Trait', 'name': 'AssociatedConst', - 'alias': 'associatedconstitem', + 'alias': 'AssociatedConstItem', 'href': '../doc_alias/trait.Trait.html#associatedconstant.AssociatedConst', 'is_alias': true }, @@ -180,7 +180,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Trait', 'name': 'function', - 'alias': 'traitfunctionitem', + 'alias': 'TraitFunctionItem', 'href': '../doc_alias/trait.Trait.html#tymethod.function', 'is_alias': true }, @@ -192,7 +192,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'function', - 'alias': 'functionitem', + 'alias': 'FunctionItem', 'href': '../doc_alias/fn.function.html', 'is_alias': true }, @@ -204,7 +204,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Module', - 'alias': 'moduleitem', + 'alias': 'ModuleItem', 'href': '../doc_alias/Module/index.html', 'is_alias': true }, @@ -216,7 +216,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Const', - 'alias': 'constitem', + 'alias': 'ConstItem', 'href': '../doc_alias/constant.Const.html', 'is_alias': true }, @@ -232,7 +232,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Static', - 'alias': 'staticitem', + 'alias': 'StaticItem', 'href': '../doc_alias/static.Static.html', 'is_alias': true }, @@ -244,7 +244,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Union', - 'alias': 'unionitem', + 'alias': 'UnionItem', 'href': '../doc_alias/union.Union.html', 'is_alias': true }, @@ -262,7 +262,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Union', 'name': 'union_item', - 'alias': 'unionfielditem', + 'alias': 'UnionFieldItem', 'href': '../doc_alias/union.Union.html#structfield.union_item', 'is_alias': true }, @@ -274,7 +274,7 @@ const EXPECTED = [ { 'path': 'doc_alias::Union', 'name': 'method', - 'alias': 'unionmethoditem', + 'alias': 'UnionMethodItem', 'href': '../doc_alias/union.Union.html#method.method', 'is_alias': true }, @@ -286,7 +286,7 @@ const EXPECTED = [ { 'path': 'doc_alias', 'name': 'Macro', - 'alias': 'macroitem', + 'alias': 'MacroItem', 'href': '../doc_alias/macro.Macro.html', 'is_alias': true }, diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 5b051523cea..4ef08f53dab 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -270,7 +270,12 @@ function loadSearchJsAndIndex(searchJs, searchIndex, storageJs, crate) { // execQuery last parameter is built in buildIndex. // buildIndex requires the hashmap from search-index. var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", - "buildIndex", "execQuery", "parseQuery", "createQueryResults"]; + "buildIndex", "execQuery", "parseQuery", "createQueryResults", + "isWhitespace", "isSpecialStartCharacter", "isStopCharacter", + "removeEmptyStringsFromArray", "parseInput", "getItemsBefore", + "getNextElem", "createQueryElement", "isReturnArrow", "isPathStart", + "skipWhitespaces", "getStringElem", "itemTypeFromName", + "newParsedQuery"]; const functions = ["hasOwnPropertyRustdoc", "onEach"]; ALIASES = {}; @@ -286,13 +291,12 @@ function loadSearchJsAndIndex(searchJs, searchIndex, storageJs, crate) { return [loaded, index]; } -function checkFieldNeededFields(fullPath, expected, error_text, queryName, position) { +// This function checks if `expected` has all the required fields needed for the checks. +function checkNeededFields(fullPath, expected, error_text, queryName, position) { let fieldsToCheck; if (fullPath.length === 0) { fieldsToCheck = [ "foundElems", - "id", - "nameSplit", "original", "returned", "typeFilter", @@ -328,7 +332,7 @@ function checkFieldNeededFields(fullPath, expected, error_text, queryName, posit function valueCheck(fullPath, expected, result, error_text, queryName) { if (Array.isArray(expected)) { for (var i = 0; i < expected.length; ++i) { - checkFieldNeededFields(fullPath, expected[i], error_text, queryName, i); + checkNeededFields(fullPath, expected[i], error_text, queryName, i); if (i >= result.length) { error_text.push(`${queryName}==> EXPECTED has extra value in array from field ` + `\`${fullPath}\` (position ${i}): \`${JSON.stringify(expected[i])}\``); @@ -367,7 +371,7 @@ function valueCheck(fullPath, expected, result, error_text, queryName) { function runParser(query, expected, loaded, loadedFile, queryName) { var error_text = []; - checkFieldNeededFields("", expected, error_text, queryName, null); + checkNeededFields("", expected, error_text, queryName, null); if (error_text.length === 0) { valueCheck('', expected, loaded.parseQuery(query), error_text, queryName); } |
