Skip to content

Commit ba824ec

Browse files
Clean up search code and unify function returned values
1 parent 3ee016a commit ba824ec

File tree

1 file changed

+96
-108
lines changed

1 file changed

+96
-108
lines changed

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

+96-108
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,23 @@ 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++) {
725+
var allFound = 0;
726+
for (it = 0, len = inputs.length; allFound === 0 && it < len; it++) {
696727
allFound = checkType(type, inputs[it], true);
697728
}
698729
in_args = allFound;
699730
}
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-
};
713-
}
731+
addIntoResults(true, results_in_args, fullId, i, -1, in_args);
732+
addIntoResults(true, results_returned, fullId, i, -1, returned);
714733
if (is_module) {
715-
results[fullId] = {
716-
id: i,
717-
index: -1,
718-
dontValidate: true,
719-
};
734+
addIntoResults(true, results, fullId, i, -1, 0);
720735
}
721736
}
722737
}
@@ -788,41 +803,14 @@ window.initSearch = function(rawSearchIndex) {
788803
lev = 0;
789804
}
790805
}
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-
}
806+
addIntoResults(false, results_in_args, fullId, j, index, in_args);
807+
addIntoResults(false, results_returned, fullId, j, index, returned);
813808
if (typePassesFilter(typeFilter, ty.ty) &&
814809
(index !== -1 || lev <= MAX_LEV_DISTANCE)) {
815810
if (index !== -1 && paths.length < 2) {
816811
lev = 0;
817812
}
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);
813+
addIntoResults(false, results, fullId, j, index, lev);
826814
}
827815
}
828816
}

0 commit comments

Comments
 (0)