@@ -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