@@ -499,6 +499,7 @@ function initSearch(rawSearchIndex) {
499499 fullPath : [ "never" ] ,
500500 pathWithoutLast : [ ] ,
501501 pathLast : "never" ,
502+ normalizedPathLast : "never" ,
502503 generics : [ ] ,
503504 bindings : new Map ( ) ,
504505 typeFilter : "primitive" ,
@@ -537,12 +538,14 @@ function initSearch(rawSearchIndex) {
537538 const bindingName = parserState . isInBinding ;
538539 parserState . isInBinding = null ;
539540 const bindings = new Map ( ) ;
541+ const pathLast = pathSegments [ pathSegments . length - 1 ] ;
540542 return {
541543 name : name . trim ( ) ,
542544 id : null ,
543545 fullPath : pathSegments ,
544546 pathWithoutLast : pathSegments . slice ( 0 , pathSegments . length - 1 ) ,
545- pathLast : pathSegments [ pathSegments . length - 1 ] ,
547+ pathLast,
548+ normalizedPathLast : pathLast . replace ( / _ / g, "" ) ,
546549 generics : generics . filter ( gen => {
547550 // Syntactically, bindings are parsed as generics,
548551 // but the query engine treats them differently.
@@ -689,6 +692,7 @@ function initSearch(rawSearchIndex) {
689692 fullPath : [ "[]" ] ,
690693 pathWithoutLast : [ ] ,
691694 pathLast : "[]" ,
695+ normalizedPathLast : "[]" ,
692696 generics,
693697 typeFilter : "primitive" ,
694698 bindingName : isInBinding ,
@@ -1168,13 +1172,12 @@ function initSearch(rawSearchIndex) {
11681172 * Executes the parsed query and builds a {ResultsTable}.
11691173 *
11701174 * @param {ParsedQuery } parsedQuery - The parsed user query
1171- * @param {Object } searchWords - The list of search words to query against
11721175 * @param {Object } [filterCrates] - Crate to search in if defined
11731176 * @param {Object } [currentCrate] - Current crate, to rank results from this crate higher
11741177 *
11751178 * @return {ResultsTable }
11761179 */
1177- function execQuery ( parsedQuery , searchWords , filterCrates , currentCrate ) {
1180+ function execQuery ( parsedQuery , filterCrates , currentCrate ) {
11781181 const results_others = new Map ( ) , results_in_args = new Map ( ) ,
11791182 results_returned = new Map ( ) ;
11801183
@@ -1232,8 +1235,8 @@ function initSearch(rawSearchIndex) {
12321235 const userQuery = parsedQuery . userQuery ;
12331236 const result_list = [ ] ;
12341237 for ( const result of results . values ( ) ) {
1235- result . word = searchWords [ result . id ] ;
1236- result . item = searchIndex [ result . id ] || { } ;
1238+ result . item = searchIndex [ result . id ] ;
1239+ result . word = searchIndex [ result . id ] . word ;
12371240 result_list . push ( result ) ;
12381241 }
12391242
@@ -1928,7 +1931,7 @@ function initSearch(rawSearchIndex) {
19281931 * The `results` map contains information which will be used to sort the search results:
19291932 *
19301933 * * `fullId` is a `string`` used as the key of the object we use for the `results` map.
1931- * * `id` is the index in both `searchWords` and ` searchIndex` arrays for this element.
1934+ * * `id` is the index in the ` searchIndex` array for this element.
19321935 * * `index` is an `integer`` used to sort by the position of the word in the item's name.
19331936 * * `dist` is the main metric used to sort the search results.
19341937 * * `path_dist` is zero if a single-component search query is used, otherwise it's the
@@ -1986,9 +1989,8 @@ function initSearch(rawSearchIndex) {
19861989 if ( ! row || ( filterCrates !== null && row . crate !== filterCrates ) ) {
19871990 return ;
19881991 }
1989- let index = - 1 , path_dist = 0 ;
1992+ let path_dist = 0 ;
19901993 const fullId = row . id ;
1991- const searchWord = searchWords [ pos ] ;
19921994
19931995 // fpDist is a minimum possible type distance, where "type distance" is the number of
19941996 // atoms in the function not present in the query
@@ -2021,19 +2023,10 @@ function initSearch(rawSearchIndex) {
20212023 return ;
20222024 }
20232025
2024- const row_index = row . normalizedName . indexOf ( elem . pathLast ) ;
2025- const word_index = searchWord . indexOf ( elem . pathLast ) ;
2026-
2027- // lower indexes are "better" matches
2028- // rank based on the "best" match
2029- if ( row_index === - 1 ) {
2030- index = word_index ;
2031- } else if ( word_index === - 1 ) {
2032- index = row_index ;
2033- } else if ( word_index < row_index ) {
2034- index = word_index ;
2035- } else {
2036- index = row_index ;
2026+ let index = row . word . indexOf ( elem . pathLast ) ;
2027+ const normalizedIndex = row . normalizedName . indexOf ( elem . pathLast ) ;
2028+ if ( index === - 1 || ( index > normalizedIndex && normalizedIndex !== - 1 ) ) {
2029+ index = normalizedIndex ;
20372030 }
20382031
20392032 if ( elem . fullPath . length > 1 ) {
@@ -2044,13 +2037,13 @@ function initSearch(rawSearchIndex) {
20442037 }
20452038
20462039 if ( parsedQuery . literalSearch ) {
2047- if ( searchWord === elem . name ) {
2040+ if ( row . word === elem . pathLast ) {
20482041 addIntoResults ( results_others , fullId , pos , index , 0 , path_dist ) ;
20492042 }
20502043 return ;
20512044 }
20522045
2053- const dist = editDistance ( searchWord , elem . pathLast , maxEditDistance ) ;
2046+ const dist = editDistance ( row . normalizedName , elem . normalizedPathLast , maxEditDistance ) ;
20542047
20552048 if ( index === - 1 && dist + path_dist > maxEditDistance ) {
20562049 return ;
@@ -2135,15 +2128,15 @@ function initSearch(rawSearchIndex) {
21352128 * @param {boolean } isAssocType
21362129 */
21372130 function convertNameToId ( elem , isAssocType ) {
2138- if ( typeNameIdMap . has ( elem . pathLast ) &&
2139- ( isAssocType || ! typeNameIdMap . get ( elem . pathLast ) . assocOnly ) ) {
2140- elem . id = typeNameIdMap . get ( elem . pathLast ) . id ;
2131+ if ( typeNameIdMap . has ( elem . normalizedPathLast ) &&
2132+ ( isAssocType || ! typeNameIdMap . get ( elem . normalizedPathLast ) . assocOnly ) ) {
2133+ elem . id = typeNameIdMap . get ( elem . normalizedPathLast ) . id ;
21412134 } else if ( ! parsedQuery . literalSearch ) {
21422135 let match = null ;
21432136 let matchDist = maxEditDistance + 1 ;
21442137 let matchName = "" ;
21452138 for ( const [ name , { id, assocOnly} ] of typeNameIdMap ) {
2146- const dist = editDistance ( name , elem . pathLast , maxEditDistance ) ;
2139+ const dist = editDistance ( name , elem . normalizedPathLast , maxEditDistance ) ;
21472140 if ( dist <= matchDist && dist <= maxEditDistance &&
21482141 ( isAssocType || ! assocOnly ) ) {
21492142 if ( dist === matchDist && matchName > name ) {
@@ -2236,7 +2229,7 @@ function initSearch(rawSearchIndex) {
22362229 if ( parsedQuery . foundElems === 1 && parsedQuery . returned . length === 0 ) {
22372230 if ( parsedQuery . elems . length === 1 ) {
22382231 const elem = parsedQuery . elems [ 0 ] ;
2239- for ( let i = 0 , nSearchWords = searchWords . length ; i < nSearchWords ; ++ i ) {
2232+ for ( let i = 0 , nSearchIndex = searchIndex . length ; i < nSearchIndex ; ++ i ) {
22402233 // It means we want to check for this element everywhere (in names, args and
22412234 // returned).
22422235 handleSingleArg (
@@ -2267,7 +2260,7 @@ function initSearch(rawSearchIndex) {
22672260 } ;
22682261 parsedQuery . elems . sort ( sortQ ) ;
22692262 parsedQuery . returned . sort ( sortQ ) ;
2270- for ( let i = 0 , nSearchWords = searchWords . length ; i < nSearchWords ; ++ i ) {
2263+ for ( let i = 0 , nSearchIndex = searchIndex . length ; i < nSearchIndex ; ++ i ) {
22712264 handleArgs ( searchIndex [ i ] , i , results_others ) ;
22722265 }
22732266 }
@@ -2651,7 +2644,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
26512644 updateSearchHistory ( buildUrl ( query . original , filterCrates ) ) ;
26522645
26532646 showResults (
2654- execQuery ( query , searchWords , filterCrates , window . currentCrate ) ,
2647+ execQuery ( query , filterCrates , window . currentCrate ) ,
26552648 params . go_to_first ,
26562649 filterCrates ) ;
26572650 }
@@ -2920,12 +2913,6 @@ ${item.displayPath}<span class="${type}">${name}</span>\
29202913
29212914 function buildIndex ( rawSearchIndex ) {
29222915 searchIndex = [ ] ;
2923- /**
2924- * List of normalized search words (ASCII lowercased, and undescores removed).
2925- *
2926- * @type {Array<string> }
2927- */
2928- const searchWords = [ ] ;
29292916 typeNameIdMap = new Map ( ) ;
29302917 const charA = "A" . charCodeAt ( 0 ) ;
29312918 let currentIndex = 0 ;
@@ -3004,7 +2991,6 @@ ${item.displayPath}<span class="${type}">${name}</span>\
30042991 * }}
30052992 */
30062993 for ( const [ crate , crateCorpus ] of rawSearchIndex ) {
3007- searchWords . push ( crate ) ;
30082994 // This object should have exactly the same set of fields as the "row"
30092995 // object defined below. Your JavaScript runtime will thank you.
30102996 // https://mathiasbynens.be/notes/shapes-ics
@@ -3017,6 +3003,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
30173003 parent : undefined ,
30183004 type : null ,
30193005 id : id ,
3006+ word : crate ,
30203007 normalizedName : crate . indexOf ( "_" ) === - 1 ? crate : crate . replace ( / _ / g, "" ) ,
30213008 deprecated : null ,
30223009 implDisambiguator : null ,
@@ -3084,12 +3071,9 @@ ${item.displayPath}<span class="${type}">${name}</span>\
30843071 len = itemTypes . length ;
30853072 for ( let i = 0 ; i < len ; ++ i ) {
30863073 let word = "" ;
3087- // This object should have exactly the same set of fields as the "crateRow"
3088- // object defined above.
30893074 if ( typeof itemNames [ i ] === "string" ) {
30903075 word = itemNames [ i ] . toLowerCase ( ) ;
30913076 }
3092- searchWords . push ( word ) ;
30933077 const path = itemPaths . has ( i ) ? itemPaths . get ( i ) : lastPath ;
30943078 let type = null ;
30953079 if ( itemFunctionSearchTypes [ i ] !== 0 ) {
@@ -3113,6 +3097,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
31133097 }
31143098 }
31153099 }
3100+ // This object should have exactly the same set of fields as the "crateRow"
3101+ // object defined above.
31163102 const row = {
31173103 crate : crate ,
31183104 ty : itemTypes . charCodeAt ( i ) - charA ,
@@ -3122,6 +3108,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
31223108 parent : itemParentIdxs [ i ] > 0 ? paths [ itemParentIdxs [ i ] - 1 ] : undefined ,
31233109 type,
31243110 id : id ,
3111+ word,
31253112 normalizedName : word . indexOf ( "_" ) === - 1 ? word : word . replace ( / _ / g, "" ) ,
31263113 deprecated : deprecatedItems . has ( i ) ,
31273114 implDisambiguator : implDisambiguator . has ( i ) ? implDisambiguator . get ( i ) : null ,
@@ -3153,7 +3140,6 @@ ${item.displayPath}<span class="${type}">${name}</span>\
31533140 }
31543141 currentIndex += itemTypes . length ;
31553142 }
3156- return searchWords ;
31573143 }
31583144
31593145 /**
@@ -3332,10 +3318,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
33323318 search ( true ) ;
33333319 }
33343320
3335- /**
3336- * @type {Array<string> }
3337- */
3338- const searchWords = buildIndex ( rawSearchIndex ) ;
3321+ buildIndex ( rawSearchIndex ) ;
33393322 if ( typeof window !== "undefined" ) {
33403323 registerSearchEvents ( ) ;
33413324 // If there's a search term in the URL, execute the search now.
@@ -3349,7 +3332,6 @@ ${item.displayPath}<span class="${type}">${name}</span>\
33493332 exports . execQuery = execQuery ;
33503333 exports . parseQuery = parseQuery ;
33513334 }
3352- return searchWords ;
33533335}
33543336
33553337if ( typeof window !== "undefined" ) {
0 commit comments