@@ -176,16 +176,13 @@ window.initSearch = function(rawSearchIndex) {
176
176
var ar = [ ] ;
177
177
for ( var entry in results ) {
178
178
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 ) ;
180
183
}
181
184
}
182
185
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
- }
189
186
// if there are no results then return to default and fail
190
187
if ( results . length === 0 ) {
191
188
return [ ] ;
@@ -258,7 +255,7 @@ window.initSearch = function(rawSearchIndex) {
258
255
return 0 ;
259
256
} ) ;
260
257
261
- for ( i = 0 , len = results . length ; i < len ; ++ i ) {
258
+ for ( var i = 0 , len = results . length ; i < len ; ++ i ) {
262
259
result = results [ i ] ;
263
260
264
261
// this validation does not make sense when searching by types
@@ -344,7 +341,17 @@ window.initSearch = function(rawSearchIndex) {
344
341
return MAX_LEV_DISTANCE + 1 ;
345
342
}
346
343
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
+ */
348
355
function checkType ( obj , val , literalSearch ) {
349
356
var lev_distance = MAX_LEV_DISTANCE + 1 ;
350
357
var tmp_lev = MAX_LEV_DISTANCE + 1 ;
@@ -363,24 +370,23 @@ window.initSearch = function(rawSearchIndex) {
363
370
elems [ obj [ GENERICS_DATA ] [ x ] [ NAME ] ] += 1 ;
364
371
}
365
372
366
- var allFound = true ;
367
373
len = val . generics . length ;
368
374
for ( x = 0 ; x < len ; ++ x ) {
369
375
firstGeneric = val . generics [ x ] ;
370
376
if ( elems [ firstGeneric ] ) {
371
377
elems [ firstGeneric ] -= 1 ;
372
378
} 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 ;
375
382
}
376
383
}
377
- if ( allFound ) {
378
- return true ;
379
- }
384
+ // Everything was found, success!
385
+ return 0 ;
380
386
}
381
- return false ;
387
+ return MAX_LEV_DISTANCE + 1 ;
382
388
}
383
- return true ;
389
+ return 0 ;
384
390
} else {
385
391
// If the type has generics but don't match, then it won't return at this point.
386
392
// Otherwise, `checkGenerics` will return 0 and it'll return.
@@ -392,14 +398,15 @@ window.initSearch = function(rawSearchIndex) {
392
398
}
393
399
}
394
400
} else if ( literalSearch ) {
401
+ var found = false ;
395
402
if ( ( ! val . generics || val . generics . length === 0 ) &&
396
403
obj . length > GENERICS_DATA && obj [ GENERICS_DATA ] . length > 0 ) {
397
- return obj [ GENERICS_DATA ] . some (
404
+ found = obj [ GENERICS_DATA ] . some (
398
405
function ( gen ) {
399
406
return gen [ NAME ] === val . name ;
400
407
} ) ;
401
408
}
402
- return false ;
409
+ return found ? 0 : MAX_LEV_DISTANCE + 1 ;
403
410
}
404
411
lev_distance = Math . min ( levenshtein ( obj [ NAME ] , val . name ) , lev_distance ) ;
405
412
if ( lev_distance <= MAX_LEV_DISTANCE ) {
@@ -430,6 +437,17 @@ window.initSearch = function(rawSearchIndex) {
430
437
return Math . min ( lev_distance , tmp_lev ) + 1 ;
431
438
}
432
439
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
+ */
433
451
function findArg ( obj , val , literalSearch , typeFilter ) {
434
452
var lev_distance = MAX_LEV_DISTANCE + 1 ;
435
453
@@ -441,19 +459,15 @@ window.initSearch = function(rawSearchIndex) {
441
459
continue ;
442
460
}
443
461
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 ) {
448
465
continue ;
449
466
}
450
467
lev_distance = Math . min ( tmp , lev_distance ) ;
451
- if ( lev_distance === 0 ) {
452
- return 0 ;
453
- }
454
468
}
455
469
}
456
- return literalSearch ? false : lev_distance ;
470
+ return literalSearch ? MAX_LEV_DISTANCE + 1 : lev_distance ;
457
471
}
458
472
459
473
function checkReturned ( obj , val , literalSearch , typeFilter ) {
@@ -470,19 +484,15 @@ window.initSearch = function(rawSearchIndex) {
470
484
continue ;
471
485
}
472
486
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 ) {
477
490
continue ;
478
491
}
479
492
lev_distance = Math . min ( tmp , lev_distance ) ;
480
- if ( lev_distance === 0 ) {
481
- return 0 ;
482
- }
483
493
}
484
494
}
485
- return literalSearch ? false : lev_distance ;
495
+ return literalSearch ? MAX_LEV_DISTANCE + 1 : lev_distance ;
486
496
}
487
497
488
498
function checkPath ( contains , lastElem , ty ) {
@@ -612,6 +622,44 @@ window.initSearch = function(rawSearchIndex) {
612
622
onEach ( crateAliases , pushFunc ) ;
613
623
}
614
624
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
+
615
663
// quoted values mean literal search
616
664
var nSearchWords = searchWords . length ;
617
665
var i , it ;
@@ -634,28 +682,11 @@ window.initSearch = function(rawSearchIndex) {
634
682
fullId = ty . id ;
635
683
636
684
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 ) ;
658
687
}
688
+ addIntoResults ( true , results_in_args , fullId , i , - 1 , in_args ) ;
689
+ addIntoResults ( true , results_returned , fullId , i , - 1 , returned ) ;
659
690
}
660
691
query . inputs = [ val ] ;
661
692
query . output = val ;
@@ -684,39 +715,27 @@ window.initSearch = function(rawSearchIndex) {
684
715
fullId = ty . id ;
685
716
686
717
returned = checkReturned ( ty , output , true , NO_TYPE_FILTER ) ;
687
- if ( output . name === "*" || returned ) {
718
+ if ( output . name === "*" || returned === 0 ) {
688
719
in_args = false ;
689
720
var is_module = false ;
690
721
691
722
if ( input === "*" ) {
692
723
is_module = true ;
693
724
} 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
+ }
697
732
}
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 ;
713
734
}
735
+ addIntoResults ( true , results_in_args , fullId , i , - 1 , in_args ) ;
736
+ addIntoResults ( true , results_returned , fullId , i , - 1 , returned ) ;
714
737
if ( is_module ) {
715
- results [ fullId ] = {
716
- id : i ,
717
- index : - 1 ,
718
- dontValidate : true ,
719
- } ;
738
+ addIntoResults ( true , results , fullId , i , - 1 , 0 ) ;
720
739
}
721
740
}
722
741
}
@@ -788,41 +807,14 @@ window.initSearch = function(rawSearchIndex) {
788
807
lev = 0 ;
789
808
}
790
809
}
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 ) ;
813
812
if ( typePassesFilter ( typeFilter , ty . ty ) &&
814
813
( index !== - 1 || lev <= MAX_LEV_DISTANCE ) ) {
815
814
if ( index !== - 1 && paths . length < 2 ) {
816
815
lev = 0 ;
817
816
}
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 ) ;
826
818
}
827
819
}
828
820
}
0 commit comments