Skip to content

Commit 5caf9c0

Browse files
committed
rustdoc: allow searches to match against both type and name
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
1 parent d4822c2 commit 5caf9c0

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

src/librustdoc/html/static/js/externs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ let ParserState;
3636
* userQuery: string,
3737
* typeFilter: number,
3838
* elems: Array<QueryElement>,
39-
* args: Array<QueryElement>,
4039
* returned: Array<QueryElement>,
40+
* extraNameElem: QueryElement | null,
4141
* foundElems: number,
4242
* totalElems: number,
4343
* literalSearch: boolean,

src/librustdoc/html/static/js/search.js

+52-3
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ const TY_PRIMITIVE = itemTypes.indexOf("primitive");
6363
const TY_GENERIC = itemTypes.indexOf("generic");
6464
const TY_IMPORT = itemTypes.indexOf("import");
6565
const TY_TRAIT = itemTypes.indexOf("trait");
66+
// used for isType
67+
const TY_STRUCT = itemTypes.indexOf("struct");
68+
const TY_ENUM = itemTypes.indexOf("enum");
69+
const TY_UNION = itemTypes.indexOf("union");
70+
const TY_PRIMATIVE = itemTypes.indexOf("primative");
71+
const TY_FOREIGN_TYPE = itemTypes.indexOf("foreigntype");
6672
const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";
6773

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

259+
function isType(ty) {
260+
return ty === TY_STRUCT || ty === TY_ENUM || ty === TY_UNION ||
261+
ty === TY_PRIMATIVE || ty === TY_FOREIGN_TYPE || ty === -1;
262+
}
263+
264+
/**
265+
* This function removes any queryElem that cannot be a function argument.
266+
*/
267+
function filterOnlyTypes(elems) {
268+
return elems.filter(elem => isType(elem.typeFilter));
269+
}
270+
253271
/**
254272
* Returns `true` if the last element in the `elems` argument has generics.
255273
*
@@ -1870,6 +1888,8 @@ class DocSearch {
18701888
correction: null,
18711889
proposeCorrectionFrom: null,
18721890
proposeCorrectionTo: null,
1891+
// used for type-and-name searches
1892+
extraNameElem: null,
18731893
// bloom filter build from type ids
18741894
typeFingerprint: new Uint32Array(4),
18751895
};
@@ -2002,6 +2022,17 @@ class DocSearch {
20022022
query.literalSearch = parserState.totalElems > 1;
20032023
}
20042024
query.foundElems = query.elems.length + query.returned.length;
2025+
if (query.returned.length > 0 || query.elems.length > 1) {
2026+
for (const elem of query.elems) {
2027+
if (!isType(elem.typeFilter)) {
2028+
query.extraNameElem = elem;
2029+
query.elems = filterOnlyTypes(query.elems);
2030+
query.hasReturnArrow = true;
2031+
console.log(query.elems);
2032+
break;
2033+
}
2034+
}
2035+
}
20052036
query.totalElems = parserState.totalElems;
20062037
return query;
20072038
}
@@ -3687,7 +3718,7 @@ class DocSearch {
36873718
* @param {integer} pos - Position in the `searchIndex`.
36883719
* @param {Object} results
36893720
*/
3690-
function handleArgs(row, pos, results) {
3721+
function handleArgs(row, pos, results, maxEditDistance) {
36913722
if (!row || (filterCrates !== null && row.crate !== filterCrates) || !row.type) {
36923723
return;
36933724
}
@@ -3724,8 +3755,26 @@ class DocSearch {
37243755
return;
37253756
}
37263757

3758+
let name_dist = 0;
3759+
let path_dist = tfpDist;
3760+
const name_elem = parsedQuery.extraNameElem;
3761+
if (name_elem !== null) {
3762+
if (!typePassesFilter(name_elem.typeFilter, row.ty)) {
3763+
return;
3764+
}
3765+
name_dist = editDistance(
3766+
row.normalizedName, name_elem.normalizedPathLast, maxEditDistance);
3767+
if (row.normalizedName.includes(name_elem.normalizedPathLast)) {
3768+
name_dist = name_dist / 3;
3769+
}
3770+
if (name_dist > maxEditDistance) {
3771+
return;
3772+
}
3773+
const real_path_dist = checkPath(name_elem.fullPath, row);
3774+
path_dist = (path_dist + real_path_dist) / 2;
3775+
}
37273776
results.max_dist = Math.max(results.max_dist || 0, tfpDist);
3728-
addIntoResults(results, row.id, pos, 0, tfpDist, 0, Number.MAX_VALUE);
3777+
addIntoResults(results, row.id, pos, name_dist, path_dist, 0, Number.MAX_VALUE);
37293778
}
37303779

37313780
/**
@@ -3928,7 +3977,7 @@ class DocSearch {
39283977
parsedQuery.elems.sort(sortQ);
39293978
parsedQuery.returned.sort(sortQ);
39303979
for (let i = 0, nSearchIndex = this.searchIndex.length; i < nSearchIndex; ++i) {
3931-
handleArgs(this.searchIndex[i], i, results_others);
3980+
handleArgs(this.searchIndex[i], i, results_others, maxEditDistance);
39323981
}
39333982
}
39343983
};

tests/rustdoc-js-std/type-and-name.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const EXPECTED = {
2+
'query': 'method:ascii, char -> bool',
3+
'others': [
4+
{ 'path': 'char', 'name': 'is_ascii_digit' },
5+
{ 'path': 'char', 'name': 'eq_ignore_ascii_case' },
6+
],
7+
}

0 commit comments

Comments
 (0)