Skip to content

Commit 8fdad93

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 8fdad93

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
@@ -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,18 @@ function prevIs(parserState, lookingFor) {
239245
return false;
240246
}
241247

248+
function isType(ty) {
249+
return ty === TY_STRUCT || ty === TY_ENUM || ty === TY_UNION ||
250+
ty === TY_PRIMATIVE || ty === TY_FOREIGN_TYPE || ty === -1;
251+
}
252+
253+
/**
254+
* This function removes any queryElem that cannot be a function argument.
255+
*/
256+
function filterOnlyTypes(elems) {
257+
return elems.filter(elem => isType(elem.typeFilter));
258+
}
259+
242260
/**
243261
* Returns `true` if the last element in the `elems` argument has generics.
244262
*
@@ -1800,6 +1818,8 @@ class DocSearch {
18001818
correction: null,
18011819
proposeCorrectionFrom: null,
18021820
proposeCorrectionTo: null,
1821+
// used for type-and-name searches
1822+
extraNameElem: null,
18031823
// bloom filter build from type ids
18041824
typeFingerprint: new Uint32Array(4),
18051825
};
@@ -1932,6 +1952,17 @@ class DocSearch {
19321952
query.literalSearch = parserState.totalElems > 1;
19331953
}
19341954
query.foundElems = query.elems.length + query.returned.length;
1955+
if (query.returned.length > 0 || query.elems.length > 1) {
1956+
for (const elem of query.elems) {
1957+
if (!isType(elem.typeFilter)) {
1958+
query.extraNameElem = elem;
1959+
query.elems = filterOnlyTypes(query.elems);
1960+
query.hasReturnArrow = true;
1961+
console.log(query.elems);
1962+
break;
1963+
}
1964+
}
1965+
}
19351966
query.totalElems = parserState.totalElems;
19361967
return query;
19371968
}
@@ -3047,7 +3078,7 @@ class DocSearch {
30473078
* @param {integer} pos - Position in the `searchIndex`.
30483079
* @param {Object} results
30493080
*/
3050-
function handleArgs(row, pos, results) {
3081+
function handleArgs(row, pos, results, maxEditDistance) {
30513082
if (!row || (filterCrates !== null && row.crate !== filterCrates) || !row.type) {
30523083
return;
30533084
}
@@ -3084,8 +3115,26 @@ class DocSearch {
30843115
return;
30853116
}
30863117

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

30913140
/**
@@ -3285,7 +3334,7 @@ class DocSearch {
32853334
parsedQuery.elems.sort(sortQ);
32863335
parsedQuery.returned.sort(sortQ);
32873336
for (let i = 0, nSearchIndex = this.searchIndex.length; i < nSearchIndex; ++i) {
3288-
handleArgs(this.searchIndex[i], i, results_others);
3337+
handleArgs(this.searchIndex[i], i, results_others, maxEditDistance);
32893338
}
32903339
}
32913340
};

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)