Skip to content

Commit 6ff6aed

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 bed75e7 commit 6ff6aed

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-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

+53-3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ const itemTypes = [
5252
// used for special search precedence
5353
const TY_GENERIC = itemTypes.indexOf("generic");
5454
const TY_IMPORT = itemTypes.indexOf("import");
55+
// used for isType
56+
const TY_STRUCT = itemTypes.indexOf("struct");
57+
const TY_ENUM = itemTypes.indexOf("enum");
58+
const TY_UNION = itemTypes.indexOf("union");
59+
const TY_PRIMATIVE = itemTypes.indexOf("primative");
60+
const TY_FOREIGN_TYPE = itemTypes.indexOf("foreigntype");
5561
const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";
5662

5763
// Hard limit on how deep to recurse into generics when doing type-driven search.
@@ -239,6 +245,19 @@ function prevIs(parserState, lookingFor) {
239245
return false;
240246
}
241247

248+
function isType(ty) {
249+
let r = ty === TY_STRUCT || ty === TY_ENUM || ty === TY_UNION ||
250+
ty === TY_PRIMATIVE || ty === TY_FOREIGN_TYPE || ty === -1;
251+
return r;
252+
}
253+
254+
/**
255+
* This function removes any queryElem that cannot be a function argument.
256+
*/
257+
function filterOnlyTypes(elems) {
258+
return elems.filter((elem) => isType(elem.typeFilter));
259+
}
260+
242261
/**
243262
* Returns `true` if the last element in the `elems` argument has generics.
244263
*
@@ -1800,6 +1819,8 @@ class DocSearch {
18001819
correction: null,
18011820
proposeCorrectionFrom: null,
18021821
proposeCorrectionTo: null,
1822+
// used for type-and-name searches
1823+
extraNameElem: null,
18031824
// bloom filter build from type ids
18041825
typeFingerprint: new Uint32Array(4),
18051826
};
@@ -1932,6 +1953,17 @@ class DocSearch {
19321953
query.literalSearch = parserState.totalElems > 1;
19331954
}
19341955
query.foundElems = query.elems.length + query.returned.length;
1956+
if (query.returned.length > 0 || query.elems.length > 1) {
1957+
for (const elem of query.elems) {
1958+
if (!isType(elem.typeFilter)) {
1959+
query.extraNameElem = elem;
1960+
query.elems = filterOnlyTypes(query.elems);
1961+
query.hasReturnArrow = true;
1962+
console.log(query.elems);
1963+
break;
1964+
}
1965+
}
1966+
}
19351967
query.totalElems = parserState.totalElems;
19361968
return query;
19371969
}
@@ -3047,7 +3079,7 @@ class DocSearch {
30473079
* @param {integer} pos - Position in the `searchIndex`.
30483080
* @param {Object} results
30493081
*/
3050-
function handleArgs(row, pos, results) {
3082+
function handleArgs(row, pos, results, maxEditDistance) {
30513083
if (!row || (filterCrates !== null && row.crate !== filterCrates) || !row.type) {
30523084
return;
30533085
}
@@ -3084,8 +3116,26 @@ class DocSearch {
30843116
return;
30853117
}
30863118

3119+
let name_dist = 0;
3120+
let name_elem = parsedQuery.extraNameElem;
3121+
let path_dist = tfpDist;
3122+
if (name_elem !== null) {
3123+
if (!typePassesFilter(name_elem.typeFilter, row.ty)) {
3124+
return;
3125+
}
3126+
name_dist = editDistance(
3127+
row.normalizedName, name_elem.normalizedPathLast, maxEditDistance);
3128+
if (row.normalizedName.includes(name_elem.normalizedPathLast)) {
3129+
name_dist = name_dist / 3;
3130+
}
3131+
if (name_dist > maxEditDistance) {
3132+
return;
3133+
}
3134+
let real_path_dist = checkPath(name_elem.fullPath, row);
3135+
path_dist = (path_dist + real_path_dist)/2;
3136+
}
30873137
results.max_dist = Math.max(results.max_dist || 0, tfpDist);
3088-
addIntoResults(results, row.id, pos, 0, tfpDist, 0, Number.MAX_VALUE);
3138+
addIntoResults(results, row.id, pos, name_dist, path_dist, 0, Number.MAX_VALUE);
30893139
}
30903140

30913141
/**
@@ -3285,7 +3335,7 @@ class DocSearch {
32853335
parsedQuery.elems.sort(sortQ);
32863336
parsedQuery.returned.sort(sortQ);
32873337
for (let i = 0, nSearchIndex = this.searchIndex.length; i < nSearchIndex; ++i) {
3288-
handleArgs(this.searchIndex[i], i, results_others);
3338+
handleArgs(this.searchIndex[i], i, results_others, maxEditDistance);
32893339
}
32903340
}
32913341
};

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)