about summary refs log tree commit diff
path: root/src/librustdoc/html/static
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2021-06-26 12:00:26 -0700
committerMichael Howell <michael@notriddle.com>2021-07-01 06:40:27 -0700
commitcedd2425b6ede6669f47794d85c67af1c43bd877 (patch)
tree9cd6c5311604b61952cd88d13256ee1b6692fced /src/librustdoc/html/static
parent3cb1c1134050c059a15d9ca7a00d4dd89111a373 (diff)
downloadrust-cedd2425b6ede6669f47794d85c67af1c43bd877.tar.gz
rust-cedd2425b6ede6669f47794d85c67af1c43bd877.zip
fix(rustdoc): generics search
This commit adds a test case for generics, re-adds generics data
to the search index, and tweaks function indexing to use less space in JSON.

This reverts commit 14ca89446c076bcf484d3d05bd991a4b7985a409.
Diffstat (limited to 'src/librustdoc/html/static')
-rw-r--r--src/librustdoc/html/static/search.js80
1 files changed, 62 insertions, 18 deletions
diff --git a/src/librustdoc/html/static/search.js b/src/librustdoc/html/static/search.js
index f6343e4c3d2..a7fc0b831f4 100644
--- a/src/librustdoc/html/static/search.js
+++ b/src/librustdoc/html/static/search.js
@@ -106,7 +106,7 @@ function levenshtein(s1, s2) {
 window.initSearch = function(rawSearchIndex) {
     var MAX_LEV_DISTANCE = 3;
     var MAX_RESULTS = 200;
-    var GENERICS_DATA = 1;
+    var GENERICS_DATA = 2;
     var NAME = 0;
     var INPUTS_DATA = 0;
     var OUTPUT_DATA = 1;
@@ -306,6 +306,9 @@ window.initSearch = function(rawSearchIndex) {
                     var elems = Object.create(null);
                     var elength = obj[GENERICS_DATA].length;
                     for (var x = 0; x < elength; ++x) {
+                        if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) {
+                            elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0;
+                        }
                         elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1;
                     }
                     var total = 0;
@@ -354,10 +357,13 @@ window.initSearch = function(rawSearchIndex) {
                 if (literalSearch) {
                     if (val.generics && val.generics.length !== 0) {
                         if (obj.length > GENERICS_DATA &&
-                              obj[GENERICS_DATA].length >= val.generics.length) {
+                             obj[GENERICS_DATA].length > 0) {
                             var elems = Object.create(null);
                             len = obj[GENERICS_DATA].length;
                             for (x = 0; x < len; ++x) {
+                                if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) {
+                                    elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0;
+                                }
                                 elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1;
                             }
 
@@ -375,26 +381,23 @@ window.initSearch = function(rawSearchIndex) {
                             if (allFound) {
                                 return true;
                             }
-                        } else {
-                            return false;
                         }
+                        return false;
                     }
                     return true;
-                }
-                // If the type has generics but don't match, then it won't return at this point.
-                // Otherwise, `checkGenerics` will return 0 and it'll return.
-                if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) {
-                    var tmp_lev = checkGenerics(obj, val);
-                    if (tmp_lev <= MAX_LEV_DISTANCE) {
-                        return tmp_lev;
-                    }
                 } else {
-                    return 0;
+                    // If the type has generics but don't match, then it won't return at this point.
+                    // Otherwise, `checkGenerics` will return 0 and it'll return.
+                    if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) {
+                        var tmp_lev = checkGenerics(obj, val);
+                        if (tmp_lev <= MAX_LEV_DISTANCE) {
+                            return tmp_lev;
+                        }
+                    }
                 }
-            }
-            // Names didn't match so let's check if one of the generic types could.
-            if (literalSearch) {
-                 if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
+            } else if (literalSearch) {
+                if ((!val.generics || val.generics.length === 0) &&
+                      obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
                     return obj[GENERICS_DATA].some(
                         function(name) {
                             return name === val.name;
@@ -1167,7 +1170,48 @@ window.initSearch = function(rawSearchIndex) {
             return ret;
         }
 
-        var queries = query.raw.split(",");
+        // Split search query by ",", while respecting angle bracket nesting.
+        // Since "<" is an alias for the Ord family of traits, it also uses
+        // lookahead to distinguish "<"-as-less-than from "<"-as-angle-bracket.
+        //
+        // tokenizeQuery("A<B, C>, D") == ["A<B, C>", "D"]
+        // tokenizeQuery("A<B, C, D") == ["A<B", "C", "D"]
+        function tokenizeQuery(raw) {
+            var i, matched;
+            var l = raw.length;
+            var depth = 0;
+            var nextAngle = /(<|>)/g;
+            var ret = [];
+            var start = 0;
+            for (i = 0; i < l; ++i) {
+                switch (raw[i]) {
+                    case "<":
+                        nextAngle.lastIndex = i + 1;
+                        matched = nextAngle.exec(raw);
+                        if (matched && matched[1] === '>') {
+                            depth += 1;
+                        }
+                        break;
+                    case ">":
+                        if (depth > 0) {
+                            depth -= 1;
+                        }
+                        break;
+                    case ",":
+                        if (depth === 0) {
+                            ret.push(raw.substring(start, i));
+                            start = i + 1;
+                        }
+                        break;
+                }
+            }
+            if (start !== i) {
+                ret.push(raw.substring(start, i));
+            }
+            return ret;
+        }
+
+        var queries = tokenizeQuery(query.raw);
         var results = {
             "in_args": [],
             "returned": [],