Rollup merge of #132569 - lolbinarycat:rustdoc-search-path-end-empty-v2, r=notriddle

rustdoc search: allow queries to end in an empty path segment

fixes https://github.com/rust-lang/rust/issues/129707

this can be used to show all items in a module,
or all associated items for a type.
currently sufferes slightly due to case insensitivity, so `Option::` will also show items in the `option::` module.

it disables the checking of the last path element, otherwise only items with short names will be shown

r? `@notriddle`
This commit is contained in:
Matthias Krüger 2024-11-16 21:05:45 +01:00 committed by GitHub
commit eff2b7017d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 13 deletions

View File

@ -692,8 +692,6 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
const quadcolon = /::\s*::/.exec(path); const quadcolon = /::\s*::/.exec(path);
if (path.startsWith("::")) { if (path.startsWith("::")) {
throw ["Paths cannot start with ", "::"]; throw ["Paths cannot start with ", "::"];
} else if (path.endsWith("::")) {
throw ["Paths cannot end with ", "::"];
} else if (quadcolon !== null) { } else if (quadcolon !== null) {
throw ["Unexpected ", quadcolon[0]]; throw ["Unexpected ", quadcolon[0]];
} }
@ -3974,18 +3972,19 @@ class DocSearch {
if (parsedQuery.foundElems === 1 && !parsedQuery.hasReturnArrow) { if (parsedQuery.foundElems === 1 && !parsedQuery.hasReturnArrow) {
const elem = parsedQuery.elems[0]; const elem = parsedQuery.elems[0];
for (const id of this.nameTrie.search(elem.normalizedPathLast, this.tailTable)) { // use arrow functions to preserve `this`.
const handleNameSearch = id => {
const row = this.searchIndex[id]; const row = this.searchIndex[id];
if (!typePassesFilter(elem.typeFilter, row.ty) || if (!typePassesFilter(elem.typeFilter, row.ty) ||
(filterCrates !== null && row.crate !== filterCrates)) { (filterCrates !== null && row.crate !== filterCrates)) {
continue; return;
} }
let pathDist = 0; let pathDist = 0;
if (elem.fullPath.length > 1) { if (elem.fullPath.length > 1) {
pathDist = checkPath(elem.pathWithoutLast, row); pathDist = checkPath(elem.pathWithoutLast, row);
if (pathDist === null) { if (pathDist === null) {
continue; return;
} }
} }
@ -4008,9 +4007,20 @@ class DocSearch {
maxEditDistance, maxEditDistance,
); );
} }
};
if (elem.normalizedPathLast !== "") {
const last = elem.normalizedPathLast;
for (const id of this.nameTrie.search(last, this.tailTable)) {
handleNameSearch(id);
}
} }
const length = this.searchIndex.length; const length = this.searchIndex.length;
for (let i = 0, nSearchIndex = length; i < nSearchIndex; ++i) { for (let i = 0, nSearchIndex = length; i < nSearchIndex; ++i) {
// queries that end in :: bypass the trie
if (elem.normalizedPathLast === "") {
handleNameSearch(i);
}
const row = this.searchIndex[i]; const row = this.searchIndex[i];
if (filterCrates !== null && row.crate !== filterCrates) { if (filterCrates !== null && row.crate !== filterCrates) {
continue; continue;

View File

@ -143,14 +143,6 @@ const PARSED = [
returned: [], returned: [],
error: "Unexpected `:: ::`", error: "Unexpected `:: ::`",
}, },
{
query: "a::b::",
elems: [],
foundElems: 0,
userQuery: "a::b::",
returned: [],
error: "Paths cannot end with `::`",
},
{ {
query: ":a", query: ":a",
elems: [], elems: [],

View File

@ -0,0 +1,6 @@
const EXPECTED = {
'query': 'Option::',
'others': [
{ 'path': 'std::option::Option', 'name': 'get_or_insert_default' },
],
}