Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 699ae36

Browse files
Apply suggestions:
* Forbid generics without a path (so "<p>" is forbidden). * Change `handleSingleArg` so that it takes `results_others`, `results_in_args` and `results_returned` as arguments instead of using the "global" variables. * Change `createQueryElement` so that it returns the newly created element instead of taking `elems` as argument. * Improve documentation
1 parent c7de1a1 commit 699ae36

File tree

6 files changed

+121
-67
lines changed

6 files changed

+121
-67
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ var ResultsTable;
6767

6868
/**
6969
* @typedef {{
70-
* crate: "std"
7170
* desc: string,
7271
* displayPath: string,
7372
* fullPath: string,

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

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ window.initSearch = function(rawSearchIndex) {
193193
* Returns `true` if the current parser position is starting with "::".
194194
*
195195
* @param {ParserState} parserState
196+
*
196197
* @return {boolean}
197198
*/
198199
function isPathStart(parserState) {
@@ -203,6 +204,7 @@ window.initSearch = function(rawSearchIndex) {
203204
* Returns `true` if the current parser position is starting with "->".
204205
*
205206
* @param {ParserState} parserState
207+
*
206208
* @return {boolean}
207209
*/
208210
function isReturnArrow(parserState) {
@@ -212,11 +214,12 @@ window.initSearch = function(rawSearchIndex) {
212214
/**
213215
* @param {ParsedQuery} query
214216
* @param {ParserState} parserState
215-
* @param {Array<QueryElement>} elems - This is where the new {QueryElement} will be added.
216217
* @param {string} name - Name of the query element.
217218
* @param {Array<QueryElement>} generics - List of generics of this query element.
219+
*
220+
* @return {QueryElement} - The newly created `QueryElement`.
218221
*/
219-
function createQueryElement(query, parserState, elems, name, generics) {
222+
function createQueryElement(query, parserState, name, generics) {
220223
if (name === '*' || (name.length === 0 && generics.length === 0)) {
221224
return;
222225
}
@@ -238,18 +241,18 @@ window.initSearch = function(rawSearchIndex) {
238241
}
239242
}
240243
}
241-
// In case we only have something like `<p>`, there is no name but it remains valid.
242-
if (pathSegments.length === 0) {
243-
pathSegments = [""];
244+
// In case we only have something like `<p>`, there is no name.
245+
if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === "")) {
246+
throw new Error("Found generics without a path");
244247
}
245-
elems.push({
248+
parserState.totalElems += 1;
249+
return {
246250
name: name,
247251
fullPath: pathSegments,
248252
pathWithoutLast: pathSegments.slice(0, pathSegments.length - 1),
249253
pathLast: pathSegments[pathSegments.length - 1],
250254
generics: generics,
251-
});
252-
parserState.totalElems += 1;
255+
};
253256
}
254257

255258
/**
@@ -300,12 +303,14 @@ window.initSearch = function(rawSearchIndex) {
300303
if (start >= end && generics.length === 0) {
301304
return;
302305
}
303-
createQueryElement(
304-
query,
305-
parserState,
306-
elems,
307-
parserState.userQuery.slice(start, end),
308-
generics);
306+
elems.push(
307+
createQueryElement(
308+
query,
309+
parserState,
310+
parserState.userQuery.slice(start, end),
311+
generics
312+
)
313+
);
309314
}
310315

311316
/**
@@ -372,8 +377,11 @@ window.initSearch = function(rawSearchIndex) {
372377
if (c === "," || c === " ") {
373378
parserState.pos += 1;
374379
continue;
375-
} else if (c === "-" && isReturnArrow(parserState)) {
376-
break;
380+
} else if (c === "-" || c === ">") {
381+
if (isReturnArrow(parserState)) {
382+
break;
383+
}
384+
throw new Error(`Unexpected \`${c}\` (did you mean \`->\`?)`);
377385
}
378386
} else if (c === ":" &&
379387
parserState.typeFilter === null &&
@@ -424,6 +432,7 @@ window.initSearch = function(rawSearchIndex) {
424432
* Takes the user search input and returns an empty `ParsedQuery`.
425433
*
426434
* @param {string} userQuery
435+
*
427436
* @return {ParsedQuery}
428437
*/
429438
function newParsedQuery(userQuery) {
@@ -445,6 +454,7 @@ window.initSearch = function(rawSearchIndex) {
445454
*
446455
* @param {string} search - The current search being performed.
447456
* @param {string|null} filterCrates - The current filtering crate (if any).
457+
*
448458
* @return {string}
449459
*/
450460
function buildUrl(search, filterCrates) {
@@ -478,17 +488,20 @@ window.initSearch = function(rawSearchIndex) {
478488
*
479489
* The supported syntax by this parser is as follow:
480490
*
481-
* ident = *(ALPHA / DIGIT)
491+
* ident = *(ALPHA / DIGIT / "_")
482492
* path = ident *(DOUBLE-COLON ident)
483493
* arg = path [generics]
484494
* arg-without-generic = path
485-
* nonempty-arg-list = arg *WS *(COMMA *WS arg)
486-
* nonempty-arg-list-without-generics = arg-without-generic *WS *(COMMA *WS arg-without-generic)
487-
* generics = OPEN-ANGLE-BRACKET *WS nonempty-arg-list-without-generics *WS CLOSE-ANGLE-BRACKET
495+
* type-sep = COMMA/WS *(COMMA/WS)
496+
* nonempty-arg-list = arg *(type-sep arg) *(COMMA/WS)
497+
* nonempty-arg-list-without-generics = arg-without-generic *(type-sep arg-without-generic)
498+
* *(COMMA/WS)
499+
* generics = OPEN-ANGLE-BRACKET *WS [ nonempty-arg-list-without-generics ] *WS
500+
* CLOSE-ANGLE-BRACKET
488501
* return-args = RETURN-ARROW *WS nonempty-arg-list
489502
*
490503
* exact-search = [type-filter *WS COLON] *WS QUOTE ident QUOTE *WS [generics]
491-
* type-search = [type-filter *WS COLON] *WS path *WS generics
504+
* type-search = [type-filter *WS COLON] *WS path *WS nonempty-arg-list
492505
*
493506
* query = *WS (exact-search / type-search / return-args) *WS
494507
*
@@ -533,6 +546,7 @@ window.initSearch = function(rawSearchIndex) {
533546
* WS = %x09 / " "
534547
*
535548
* @param {string} val - The user query
549+
*
536550
* @return {ParsedQuery} - The parsed query
537551
*/
538552
function parseQuery(userQuery) {
@@ -567,7 +581,7 @@ window.initSearch = function(rawSearchIndex) {
567581
query.foundElems = query.elems.length + query.returned.length;
568582
if (query.foundElems === 0 && parserState.length !== 0) {
569583
// In this case, we'll simply keep whatever was entered by the user...
570-
createQueryElement(query, parserState, query.elems, userQuery, []);
584+
query.elems.push(createQueryElement(query, parserState, userQuery, []));
571585
query.foundElems += 1;
572586
}
573587
return query;
@@ -580,6 +594,7 @@ window.initSearch = function(rawSearchIndex) {
580594
* @param {Array<Result>} results_returned
581595
* @param {Array<Result>} results_in_args
582596
* @param {ParsedQuery} parsedQuery
597+
*
583598
* @return {ResultsTable}
584599
*/
585600
function createQueryResults(results_in_args, results_returned, results_others, parsedQuery) {
@@ -597,6 +612,7 @@ window.initSearch = function(rawSearchIndex) {
597612
* @param {ParsedQuery} parsedQuery - The parsed user query
598613
* @param {Object} searchWords - The list of search words to query against
599614
* @param {Object} [filterCrates] - Crate to search in if defined
615+
*
600616
* @return {ResultsTable}
601617
*/
602618
function execQuery(parsedQuery, searchWords, filterCrates) {
@@ -634,12 +650,7 @@ window.initSearch = function(rawSearchIndex) {
634650
}
635651

636652
function sortResults(results, isType) {
637-
var nameSplit = null;
638-
if (parsedQuery.elems.length === 1) {
639-
var hasPath = typeof parsedQuery.elems[0].path === "undefined";
640-
nameSplit = hasPath ? null : parsedQuery.elems[0].path;
641-
}
642-
var query = parsedQuery.userQuery;
653+
var userQuery = parsedQuery.userQuery;
643654
var ar = [];
644655
for (var entry in results) {
645656
if (hasOwnPropertyRustdoc(results, entry)) {
@@ -659,8 +670,8 @@ window.initSearch = function(rawSearchIndex) {
659670
var a, b;
660671

661672
// sort by exact match with regard to the last word (mismatch goes later)
662-
a = (aaa.word !== query);
663-
b = (bbb.word !== query);
673+
a = (aaa.word !== userQuery);
674+
b = (bbb.word !== userQuery);
664675
if (a !== b) { return a - b; }
665676

666677
// Sort by non levenshtein results and then levenshtein results by the distance
@@ -722,6 +733,12 @@ window.initSearch = function(rawSearchIndex) {
722733
return 0;
723734
});
724735

736+
var nameSplit = null;
737+
if (parsedQuery.elems.length === 1) {
738+
var hasPath = typeof parsedQuery.elems[0].path === "undefined";
739+
nameSplit = hasPath ? null : parsedQuery.elems[0].path;
740+
}
741+
725742
for (var i = 0, len = results.length; i < len; ++i) {
726743
result = results[i];
727744

@@ -763,7 +780,7 @@ window.initSearch = function(rawSearchIndex) {
763780
// match as well.
764781
var elem_name;
765782
if (elem.generics.length > 0 && row[GENERICS_DATA].length >= elem.generics.length) {
766-
var elems = {};
783+
var elems = Object.create(null);
767784
for (var x = 0, length = row[GENERICS_DATA].length; x < length; ++x) {
768785
elem_name = row[GENERICS_DATA][x][NAME];
769786
if (elem_name === "") {
@@ -935,6 +952,8 @@ window.initSearch = function(rawSearchIndex) {
935952
}
936953

937954
/**
955+
* This function checks if the object (`row`) returns the given type (`elem`).
956+
*
938957
* @param {Row} row
939958
* @param {QueryElement} elem - The element from the parsed query.
940959
* @param {integer} typeFilter
@@ -1103,7 +1122,7 @@ window.initSearch = function(rawSearchIndex) {
11031122
* * `index` is an `integer`` used to sort by the position of the word in the item's name.
11041123
* * `lev` is the main metric used to sort the search results.
11051124
*
1106-
* @param {Object} results
1125+
* @param {Results} results
11071126
* @param {string} fullId
11081127
* @param {integer} id
11091128
* @param {integer} index
@@ -1130,10 +1149,21 @@ window.initSearch = function(rawSearchIndex) {
11301149
* This function is called in case the query is only one element (with or without generics).
11311150
*
11321151
* @param {Row} row
1133-
* @param {integer} pos - Position in the `searchIndex`.
1134-
* @param {QueryElement} elem - The element from the parsed query.
1152+
* @param {integer} pos - Position in the `searchIndex`.
1153+
* @param {QueryElement} elem - The element from the parsed query.
1154+
* @param {Results} results_others - Unqualified results (not in arguments nor in
1155+
* returned values).
1156+
* @param {Results} results_in_args - Matching arguments results.
1157+
* @param {Results} results_returned - Matching returned arguments results.
11351158
*/
1136-
function handleSingleArg(row, pos, elem) {
1159+
function handleSingleArg(
1160+
row,
1161+
pos,
1162+
elem,
1163+
results_others,
1164+
results_in_args,
1165+
results_returned
1166+
) {
11371167
if (!row || (filterCrates !== null && row.crate !== filterCrates)) {
11381168
return;
11391169
}
@@ -1261,7 +1291,14 @@ window.initSearch = function(rawSearchIndex) {
12611291
for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
12621292
// It means we want to check for this element everywhere (in names, args and
12631293
// returned).
1264-
handleSingleArg(searchIndex[i], i, elem);
1294+
handleSingleArg(
1295+
searchIndex[i],
1296+
i,
1297+
elem,
1298+
results_others,
1299+
results_in_args,
1300+
results_returned
1301+
);
12651302
}
12661303
} else if (parsedQuery.returned.length === 1) {
12671304
// We received one returned argument to check, so looking into returned values.
@@ -1315,6 +1352,7 @@ window.initSearch = function(rawSearchIndex) {
13151352
* @param {string} path - The path of the result
13161353
* @param {string} keys - The keys to be used (["file", "open"])
13171354
* @param {Object} parent - The parent of the result
1355+
*
13181356
* @return {boolean} - Whether the result is valid or not
13191357
*/
13201358
function validateResult(name, path, keys, parent) {

src/test/rustdoc-js-std/parser-errors.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
const QUERY = [
2+
'<P>',
3+
'-> <P>',
24
'<"P">',
35
'"P" "P"',
46
'P "P"',
@@ -16,9 +18,29 @@ const QUERY = [
1618
"a b:",
1719
"a (b:",
1820
"{:",
21+
"a-bb",
22+
"a>bb",
1923
];
2024

2125
const PARSED = [
26+
{
27+
elems: [],
28+
foundElems: 0,
29+
original: "<P>",
30+
returned: [],
31+
typeFilter: -1,
32+
userQuery: "<p>",
33+
error: "Found generics without a path",
34+
},
35+
{
36+
elems: [],
37+
foundElems: 0,
38+
original: "-> <P>",
39+
returned: [],
40+
typeFilter: -1,
41+
userQuery: "-> <p>",
42+
error: "Found generics without a path",
43+
},
2244
{
2345
elems: [],
2446
foundElems: 0,
@@ -172,4 +194,22 @@ const PARSED = [
172194
userQuery: "{:",
173195
error: "Unknown type filter `{`",
174196
},
197+
{
198+
elems: [],
199+
foundElems: 0,
200+
original: "a-bb",
201+
returned: [],
202+
typeFilter: -1,
203+
userQuery: "a-bb",
204+
error: "Unexpected `-` (did you mean `->`?)",
205+
},
206+
{
207+
elems: [],
208+
foundElems: 0,
209+
original: "a>bb",
210+
returned: [],
211+
typeFilter: -1,
212+
userQuery: "a>bb",
213+
error: "Unexpected `>` (did you mean `->`?)",
214+
},
175215
];

src/test/rustdoc-js-std/parser-generics.js

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,6 @@
1-
const QUERY = ['<P>', 'A<B<C<D>, E>', 'p<> u8'];
1+
const QUERY = ['A<B<C<D>, E>', 'p<> u8'];
22

33
const PARSED = [
4-
{
5-
elems: [{
6-
name: "",
7-
fullPath: [""],
8-
pathWithoutLast: [],
9-
pathLast: "",
10-
generics: [
11-
{
12-
name: "p",
13-
fullPath: ["p"],
14-
pathWithoutLast: [],
15-
pathLast: "p",
16-
generics: [],
17-
},
18-
],
19-
}],
20-
foundElems: 1,
21-
original: "<P>",
22-
returned: [],
23-
typeFilter: -1,
24-
userQuery: "<p>",
25-
error: null,
26-
},
274
{
285
elems: [],
296
foundElems: 0,

0 commit comments

Comments
 (0)