Skip to content

Commit

Permalink
rustdoc: allow searches to match against both type and name
Browse files Browse the repository at this point in the history
repurposes existing syntax that previously had a nonsese meaning.

now `fn:add, u8 -> u8` searches for fn items with "add" in the name,
that take a `u8` argument and return a `u8`.

the kind is included in anticipation that type based searches will
soon work on items other than functions and methods.

fixes #131130
  • Loading branch information
lolbinarycat committed Nov 11, 2024
1 parent d4822c2 commit 5caf9c0
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/js/externs.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ let ParserState;
* userQuery: string,
* typeFilter: number,
* elems: Array<QueryElement>,
* args: Array<QueryElement>,
* returned: Array<QueryElement>,
* extraNameElem: QueryElement | null,
* foundElems: number,
* totalElems: number,
* literalSearch: boolean,
Expand Down
55 changes: 52 additions & 3 deletions src/librustdoc/html/static/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ const TY_PRIMITIVE = itemTypes.indexOf("primitive");
const TY_GENERIC = itemTypes.indexOf("generic");
const TY_IMPORT = itemTypes.indexOf("import");
const TY_TRAIT = itemTypes.indexOf("trait");
// used for isType
const TY_STRUCT = itemTypes.indexOf("struct");
const TY_ENUM = itemTypes.indexOf("enum");
const TY_UNION = itemTypes.indexOf("union");
const TY_PRIMATIVE = itemTypes.indexOf("primative");
const TY_FOREIGN_TYPE = itemTypes.indexOf("foreigntype");
const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";

// Hard limit on how deep to recurse into generics when doing type-driven search.
Expand Down Expand Up @@ -250,6 +256,18 @@ function prevIs(parserState, lookingFor) {
return false;
}

function isType(ty) {
return ty === TY_STRUCT || ty === TY_ENUM || ty === TY_UNION ||
ty === TY_PRIMATIVE || ty === TY_FOREIGN_TYPE || ty === -1;
}

/**
* This function removes any queryElem that cannot be a function argument.
*/
function filterOnlyTypes(elems) {
return elems.filter(elem => isType(elem.typeFilter));
}

/**
* Returns `true` if the last element in the `elems` argument has generics.
*
Expand Down Expand Up @@ -1870,6 +1888,8 @@ class DocSearch {
correction: null,
proposeCorrectionFrom: null,
proposeCorrectionTo: null,
// used for type-and-name searches
extraNameElem: null,
// bloom filter build from type ids
typeFingerprint: new Uint32Array(4),
};
Expand Down Expand Up @@ -2002,6 +2022,17 @@ class DocSearch {
query.literalSearch = parserState.totalElems > 1;
}
query.foundElems = query.elems.length + query.returned.length;
if (query.returned.length > 0 || query.elems.length > 1) {
for (const elem of query.elems) {
if (!isType(elem.typeFilter)) {
query.extraNameElem = elem;
query.elems = filterOnlyTypes(query.elems);
query.hasReturnArrow = true;
console.log(query.elems);
break;
}
}
}
query.totalElems = parserState.totalElems;
return query;
}
Expand Down Expand Up @@ -3687,7 +3718,7 @@ class DocSearch {
* @param {integer} pos - Position in the `searchIndex`.
* @param {Object} results
*/
function handleArgs(row, pos, results) {
function handleArgs(row, pos, results, maxEditDistance) {
if (!row || (filterCrates !== null && row.crate !== filterCrates) || !row.type) {
return;
}
Expand Down Expand Up @@ -3724,8 +3755,26 @@ class DocSearch {
return;
}

let name_dist = 0;
let path_dist = tfpDist;
const name_elem = parsedQuery.extraNameElem;
if (name_elem !== null) {
if (!typePassesFilter(name_elem.typeFilter, row.ty)) {
return;
}
name_dist = editDistance(
row.normalizedName, name_elem.normalizedPathLast, maxEditDistance);
if (row.normalizedName.includes(name_elem.normalizedPathLast)) {
name_dist = name_dist / 3;
}
if (name_dist > maxEditDistance) {
return;
}
const real_path_dist = checkPath(name_elem.fullPath, row);
path_dist = (path_dist + real_path_dist) / 2;
}
results.max_dist = Math.max(results.max_dist || 0, tfpDist);
addIntoResults(results, row.id, pos, 0, tfpDist, 0, Number.MAX_VALUE);
addIntoResults(results, row.id, pos, name_dist, path_dist, 0, Number.MAX_VALUE);
}

/**
Expand Down Expand Up @@ -3928,7 +3977,7 @@ class DocSearch {
parsedQuery.elems.sort(sortQ);
parsedQuery.returned.sort(sortQ);
for (let i = 0, nSearchIndex = this.searchIndex.length; i < nSearchIndex; ++i) {
handleArgs(this.searchIndex[i], i, results_others);
handleArgs(this.searchIndex[i], i, results_others, maxEditDistance);
}
}
};
Expand Down
7 changes: 7 additions & 0 deletions tests/rustdoc-js-std/type-and-name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const EXPECTED = {
'query': 'method:ascii, char -> bool',
'others': [
{ 'path': 'char', 'name': 'is_ascii_digit' },
{ 'path': 'char', 'name': 'eq_ignore_ascii_case' },
],
}

0 comments on commit 5caf9c0

Please sign in to comment.