Skip to content

Commit 8bb238b

Browse files
authored
Rollup merge of #91977 - GuillaumeGomez:unify-search-code, r=jsha
Clean up search code and unify function returned values This PR is a cleanup: there is no changes in the search results or in the UI. Depending if it was "literal search" or not, it was either returning booleans or integers. It's pretty bad so instead it all returns integers. Another thing I did was to move the add and checks into a `addIntoResults` function to simplify things. Last thing: I removed a loop in the `sortResults` function and moved its code directly into the first loop. All these changes are done to make #90630 much smaller. r? `@jsha`
2 parents 44ff0f7 + 080b926 commit 8bb238b

File tree

1 file changed

+102
-110
lines changed

1 file changed

+102
-110
lines changed

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

+102-110
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,13 @@ window.initSearch = function(rawSearchIndex) {
176176
var ar = [];
177177
for (var entry in results) {
178178
if (hasOwnPropertyRustdoc(results, entry)) {
179-
ar.push(results[entry]);
179+
var result = results[entry];
180+
result.word = searchWords[result.id];
181+
result.item = searchIndex[result.id] || {};
182+
ar.push(result);
180183
}
181184
}
182185
results = ar;
183-
var i, len, result;
184-
for (i = 0, len = results.length; i < len; ++i) {
185-
result = results[i];
186-
result.word = searchWords[result.id];
187-
result.item = searchIndex[result.id] || {};
188-
}
189186
// if there are no results then return to default and fail
190187
if (results.length === 0) {
191188
return [];
@@ -258,7 +255,7 @@ window.initSearch = function(rawSearchIndex) {
258255
return 0;
259256
});
260257

261-
for (i = 0, len = results.length; i < len; ++i) {
258+
for (var i = 0, len = results.length; i < len; ++i) {
262259
result = results[i];
263260

264261
// this validation does not make sense when searching by types
@@ -344,7 +341,17 @@ window.initSearch = function(rawSearchIndex) {
344341
return MAX_LEV_DISTANCE + 1;
345342
}
346343

347-
// Check for type name and type generics (if any).
344+
/**
345+
* This function checks if the object (`obj`) matches the given type (`val`) and its
346+
* generics (if any).
347+
*
348+
* @param {Object} obj
349+
* @param {string} val
350+
* @param {boolean} literalSearch
351+
*
352+
* @return {integer} - Returns a Levenshtein distance to the best match. If there is
353+
* no match, returns `MAX_LEV_DISTANCE + 1`.
354+
*/
348355
function checkType(obj, val, literalSearch) {
349356
var lev_distance = MAX_LEV_DISTANCE + 1;
350357
var tmp_lev = MAX_LEV_DISTANCE + 1;
@@ -363,24 +370,23 @@ window.initSearch = function(rawSearchIndex) {
363370
elems[obj[GENERICS_DATA][x][NAME]] += 1;
364371
}
365372

366-
var allFound = true;
367373
len = val.generics.length;
368374
for (x = 0; x < len; ++x) {
369375
firstGeneric = val.generics[x];
370376
if (elems[firstGeneric]) {
371377
elems[firstGeneric] -= 1;
372378
} else {
373-
allFound = false;
374-
break;
379+
// Something wasn't found and this is a literal search so
380+
// abort and return a "failing" distance.
381+
return MAX_LEV_DISTANCE + 1;
375382
}
376383
}
377-
if (allFound) {
378-
return true;
379-
}
384+
// Everything was found, success!
385+
return 0;
380386
}
381-
return false;
387+
return MAX_LEV_DISTANCE + 1;
382388
}
383-
return true;
389+
return 0;
384390
} else {
385391
// If the type has generics but don't match, then it won't return at this point.
386392
// Otherwise, `checkGenerics` will return 0 and it'll return.
@@ -392,14 +398,15 @@ window.initSearch = function(rawSearchIndex) {
392398
}
393399
}
394400
} else if (literalSearch) {
401+
var found = false;
395402
if ((!val.generics || val.generics.length === 0) &&
396403
obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
397-
return obj[GENERICS_DATA].some(
404+
found = obj[GENERICS_DATA].some(
398405
function(gen) {
399406
return gen[NAME] === val.name;
400407
});
401408
}
402-
return false;
409+
return found ? 0 : MAX_LEV_DISTANCE + 1;
403410
}
404411
lev_distance = Math.min(levenshtein(obj[NAME], val.name), lev_distance);
405412
if (lev_distance <= MAX_LEV_DISTANCE) {
@@ -430,6 +437,17 @@ window.initSearch = function(rawSearchIndex) {
430437
return Math.min(lev_distance, tmp_lev) + 1;
431438
}
432439

440+
/**
441+
* This function checks if the object (`obj`) has an argument with the given type (`val`).
442+
*
443+
* @param {Object} obj
444+
* @param {string} val
445+
* @param {boolean} literalSearch
446+
* @param {integer} typeFilter
447+
*
448+
* @return {integer} - Returns a Levenshtein distance to the best match. If there is no
449+
* match, returns `MAX_LEV_DISTANCE + 1`.
450+
*/
433451
function findArg(obj, val, literalSearch, typeFilter) {
434452
var lev_distance = MAX_LEV_DISTANCE + 1;
435453

@@ -441,19 +459,15 @@ window.initSearch = function(rawSearchIndex) {
441459
continue;
442460
}
443461
tmp = checkType(tmp, val, literalSearch);
444-
if (literalSearch) {
445-
if (tmp) {
446-
return true;
447-
}
462+
if (tmp === 0) {
463+
return 0;
464+
} else if (literalSearch) {
448465
continue;
449466
}
450467
lev_distance = Math.min(tmp, lev_distance);
451-
if (lev_distance === 0) {
452-
return 0;
453-
}
454468
}
455469
}
456-
return literalSearch ? false : lev_distance;
470+
return literalSearch ? MAX_LEV_DISTANCE + 1 : lev_distance;
457471
}
458472

459473
function checkReturned(obj, val, literalSearch, typeFilter) {
@@ -470,19 +484,15 @@ window.initSearch = function(rawSearchIndex) {
470484
continue;
471485
}
472486
tmp = checkType(tmp, val, literalSearch);
473-
if (literalSearch) {
474-
if (tmp) {
475-
return true;
476-
}
487+
if (tmp === 0) {
488+
return 0;
489+
} else if (literalSearch) {
477490
continue;
478491
}
479492
lev_distance = Math.min(tmp, lev_distance);
480-
if (lev_distance === 0) {
481-
return 0;
482-
}
483493
}
484494
}
485-
return literalSearch ? false : lev_distance;
495+
return literalSearch ? MAX_LEV_DISTANCE + 1 : lev_distance;
486496
}
487497

488498
function checkPath(contains, lastElem, ty) {
@@ -612,6 +622,44 @@ window.initSearch = function(rawSearchIndex) {
612622
onEach(crateAliases, pushFunc);
613623
}
614624

625+
/**
626+
* This function adds the given result into the provided `res` map if it matches the
627+
* following condition:
628+
*
629+
* * If it is a "literal search" (`isExact`), then `lev` must be 0.
630+
* * If it is not a "literal search", `lev` must be <= `MAX_LEV_DISTANCE`.
631+
*
632+
* The `res` map contains information which will be used to sort the search results:
633+
*
634+
* * `fullId` is a `string`` used as the key of the object we use for the `res` map.
635+
* * `id` is the index in both `searchWords` and `searchIndex` arrays for this element.
636+
* * `index` is an `integer`` used to sort by the position of the word in the item's name.
637+
* * `lev` is the main metric used to sort the search results.
638+
*
639+
* @param {boolean} isExact
640+
* @param {Object} res
641+
* @param {string} fullId
642+
* @param {integer} id
643+
* @param {integer} index
644+
* @param {integer} lev
645+
*/
646+
function addIntoResults(isExact, res, fullId, id, index, lev) {
647+
if (lev === 0 || (!isExact && lev <= MAX_LEV_DISTANCE)) {
648+
if (res[fullId] !== undefined) {
649+
var result = res[fullId];
650+
if (result.dontValidate || result.lev <= lev) {
651+
return;
652+
}
653+
}
654+
res[fullId] = {
655+
id: id,
656+
index: index,
657+
dontValidate: isExact,
658+
lev: lev,
659+
};
660+
}
661+
}
662+
615663
// quoted values mean literal search
616664
var nSearchWords = searchWords.length;
617665
var i, it;
@@ -634,28 +682,11 @@ window.initSearch = function(rawSearchIndex) {
634682
fullId = ty.id;
635683

636684
if (searchWords[i] === val.name
637-
&& typePassesFilter(typeFilter, searchIndex[i].ty)
638-
&& results[fullId] === undefined) {
639-
results[fullId] = {
640-
id: i,
641-
index: -1,
642-
dontValidate: true,
643-
};
644-
}
645-
if (in_args && results_in_args[fullId] === undefined) {
646-
results_in_args[fullId] = {
647-
id: i,
648-
index: -1,
649-
dontValidate: true,
650-
};
651-
}
652-
if (returned && results_returned[fullId] === undefined) {
653-
results_returned[fullId] = {
654-
id: i,
655-
index: -1,
656-
dontValidate: true,
657-
};
685+
&& typePassesFilter(typeFilter, searchIndex[i].ty)) {
686+
addIntoResults(true, results, fullId, i, -1, 0);
658687
}
688+
addIntoResults(true, results_in_args, fullId, i, -1, in_args);
689+
addIntoResults(true, results_returned, fullId, i, -1, returned);
659690
}
660691
query.inputs = [val];
661692
query.output = val;
@@ -684,39 +715,27 @@ window.initSearch = function(rawSearchIndex) {
684715
fullId = ty.id;
685716

686717
returned = checkReturned(ty, output, true, NO_TYPE_FILTER);
687-
if (output.name === "*" || returned) {
718+
if (output.name === "*" || returned === 0) {
688719
in_args = false;
689720
var is_module = false;
690721

691722
if (input === "*") {
692723
is_module = true;
693724
} else {
694-
var allFound = true;
695-
for (it = 0, len = inputs.length; allFound && it < len; it++) {
696-
allFound = checkType(type, inputs[it], true);
725+
var firstNonZeroDistance = 0;
726+
for (it = 0, len = inputs.length; it < len; it++) {
727+
var distance = checkType(type, inputs[it], true);
728+
if (distance > 0) {
729+
firstNonZeroDistance = distance;
730+
break;
731+
}
697732
}
698-
in_args = allFound;
699-
}
700-
if (in_args) {
701-
results_in_args[fullId] = {
702-
id: i,
703-
index: -1,
704-
dontValidate: true,
705-
};
706-
}
707-
if (returned) {
708-
results_returned[fullId] = {
709-
id: i,
710-
index: -1,
711-
dontValidate: true,
712-
};
733+
in_args = firstNonZeroDistance;
713734
}
735+
addIntoResults(true, results_in_args, fullId, i, -1, in_args);
736+
addIntoResults(true, results_returned, fullId, i, -1, returned);
714737
if (is_module) {
715-
results[fullId] = {
716-
id: i,
717-
index: -1,
718-
dontValidate: true,
719-
};
738+
addIntoResults(true, results, fullId, i, -1, 0);
720739
}
721740
}
722741
}
@@ -788,41 +807,14 @@ window.initSearch = function(rawSearchIndex) {
788807
lev = 0;
789808
}
790809
}
791-
if (in_args <= MAX_LEV_DISTANCE) {
792-
if (results_in_args[fullId] === undefined) {
793-
results_in_args[fullId] = {
794-
id: j,
795-
index: index,
796-
lev: in_args,
797-
};
798-
}
799-
results_in_args[fullId].lev =
800-
Math.min(results_in_args[fullId].lev, in_args);
801-
}
802-
if (returned <= MAX_LEV_DISTANCE) {
803-
if (results_returned[fullId] === undefined) {
804-
results_returned[fullId] = {
805-
id: j,
806-
index: index,
807-
lev: returned,
808-
};
809-
}
810-
results_returned[fullId].lev =
811-
Math.min(results_returned[fullId].lev, returned);
812-
}
810+
addIntoResults(false, results_in_args, fullId, j, index, in_args);
811+
addIntoResults(false, results_returned, fullId, j, index, returned);
813812
if (typePassesFilter(typeFilter, ty.ty) &&
814813
(index !== -1 || lev <= MAX_LEV_DISTANCE)) {
815814
if (index !== -1 && paths.length < 2) {
816815
lev = 0;
817816
}
818-
if (results[fullId] === undefined) {
819-
results[fullId] = {
820-
id: j,
821-
index: index,
822-
lev: lev,
823-
};
824-
}
825-
results[fullId].lev = Math.min(results[fullId].lev, lev);
817+
addIntoResults(false, results, fullId, j, index, lev);
826818
}
827819
}
828820
}

0 commit comments

Comments
 (0)