about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume.gomez@huawei.com>2022-03-20 15:03:17 +0100
committerGuillaume Gomez <guillaume.gomez@huawei.com>2022-04-18 20:59:09 +0200
commit699ae365dfadabb3d26f957341a9f176d73bc8af (patch)
tree1dbb52f4b0a7990602b1577142b7d36b750cad7f
parentc7de1a16f89b9aa3205f50c9cf2b9f6792ac6e4b (diff)
downloadrust-699ae365dfadabb3d26f957341a9f176d73bc8af.tar.gz
rust-699ae365dfadabb3d26f957341a9f176d73bc8af.zip
Apply suggestions:
 * Forbid generics without a path (so "<p>" is forbidden).
 * Change `handleSingleArg` so that it takes `results_others`, `results_in_args` and `results_returned` as arguments instead of using the "global" variables.
 * Change `createQueryElement` so that it returns the newly created element instead of taking `elems` as argument.
 * Improve documentation
-rw-r--r--src/librustdoc/html/static/js/externs.js1
-rw-r--r--src/librustdoc/html/static/js/search.js110
-rw-r--r--src/test/rustdoc-js-std/parser-errors.js40
-rw-r--r--src/test/rustdoc-js-std/parser-generics.js25
-rw-r--r--src/test/rustdoc-js-std/parser-returned.js12
-rw-r--r--src/test/rustdoc-js-std/parser-weird-queries.js (renamed from src/test/rustdoc-js-std/parser-invalid.js)0
6 files changed, 121 insertions, 67 deletions
diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js
index 1fdd3068a03..0fe0fdadbd2 100644
--- a/src/librustdoc/html/static/js/externs.js
+++ b/src/librustdoc/html/static/js/externs.js
@@ -67,7 +67,6 @@ var ResultsTable;
 
 /**
  * @typedef {{
- * crate: "std"
  *     desc: string,
  *     displayPath: string,
  *     fullPath: string,
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 43a59ed85e0..92a8279791d 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -193,6 +193,7 @@ window.initSearch = function(rawSearchIndex) {
      * Returns `true` if the current parser position is starting with "::".
      *
      * @param {ParserState} parserState
+     *
      * @return {boolean}
      */
     function isPathStart(parserState) {
@@ -203,6 +204,7 @@ window.initSearch = function(rawSearchIndex) {
      * Returns `true` if the current parser position is starting with "->".
      *
      * @param {ParserState} parserState
+     *
      * @return {boolean}
      */
     function isReturnArrow(parserState) {
@@ -212,11 +214,12 @@ window.initSearch = function(rawSearchIndex) {
     /**
      * @param {ParsedQuery} query
      * @param {ParserState} parserState
-     * @param {Array<QueryElement>} elems    - This is where the new {QueryElement} will be added.
      * @param {string} name                  - Name of the query element.
      * @param {Array<QueryElement>} generics - List of generics of this query element.
+     *
+     * @return {QueryElement}                - The newly created `QueryElement`.
      */
-    function createQueryElement(query, parserState, elems, name, generics) {
+    function createQueryElement(query, parserState, name, generics) {
         if (name === '*' || (name.length === 0 && generics.length === 0)) {
             return;
         }
@@ -238,18 +241,18 @@ window.initSearch = function(rawSearchIndex) {
                 }
             }
         }
-        // In case we only have something like `<p>`, there is no name but it remains valid.
-        if (pathSegments.length === 0) {
-            pathSegments = [""];
+        // In case we only have something like `<p>`, there is no name.
+        if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === "")) {
+            throw new Error("Found generics without a path");
         }
-        elems.push({
+        parserState.totalElems += 1;
+        return {
             name: name,
             fullPath: pathSegments,
             pathWithoutLast: pathSegments.slice(0, pathSegments.length - 1),
             pathLast: pathSegments[pathSegments.length - 1],
             generics: generics,
-        });
-        parserState.totalElems += 1;
+        };
     }
 
     /**
@@ -300,12 +303,14 @@ window.initSearch = function(rawSearchIndex) {
         if (start >= end && generics.length === 0) {
             return;
         }
-        createQueryElement(
-            query,
-            parserState,
-            elems,
-            parserState.userQuery.slice(start, end),
-            generics);
+        elems.push(
+            createQueryElement(
+                query,
+                parserState,
+                parserState.userQuery.slice(start, end),
+                generics
+            )
+        );
     }
 
     /**
@@ -372,8 +377,11 @@ window.initSearch = function(rawSearchIndex) {
                 if (c === "," || c === " ") {
                     parserState.pos += 1;
                     continue;
-                } else if (c === "-" && isReturnArrow(parserState)) {
-                    break;
+                } else if (c === "-" || c === ">") {
+                    if (isReturnArrow(parserState)) {
+                        break;
+                    }
+                    throw new Error(`Unexpected \`${c}\` (did you mean \`->\`?)`);
                 }
             } else if (c === ":" &&
                 parserState.typeFilter === null &&
@@ -424,6 +432,7 @@ window.initSearch = function(rawSearchIndex) {
      * Takes the user search input and returns an empty `ParsedQuery`.
      *
      * @param {string} userQuery
+     *
      * @return {ParsedQuery}
      */
     function newParsedQuery(userQuery) {
@@ -445,6 +454,7 @@ window.initSearch = function(rawSearchIndex) {
      *
      * @param {string} search            - The current search being performed.
      * @param {string|null} filterCrates - The current filtering crate (if any).
+     *
      * @return {string}
      */
     function buildUrl(search, filterCrates) {
@@ -478,17 +488,20 @@ window.initSearch = function(rawSearchIndex) {
      *
      * The supported syntax by this parser is as follow:
      *
-     * ident = *(ALPHA / DIGIT)
+     * ident = *(ALPHA / DIGIT / "_")
      * path = ident *(DOUBLE-COLON ident)
      * arg = path [generics]
      * arg-without-generic = path
-     * nonempty-arg-list = arg *WS *(COMMA *WS arg)
-     * nonempty-arg-list-without-generics = arg-without-generic *WS *(COMMA *WS arg-without-generic)
-     * generics = OPEN-ANGLE-BRACKET *WS nonempty-arg-list-without-generics *WS CLOSE-ANGLE-BRACKET
+     * type-sep = COMMA/WS *(COMMA/WS)
+     * nonempty-arg-list = arg *(type-sep arg) *(COMMA/WS)
+     * nonempty-arg-list-without-generics = arg-without-generic *(type-sep arg-without-generic)
+     *                                      *(COMMA/WS)
+     * generics = OPEN-ANGLE-BRACKET *WS [ nonempty-arg-list-without-generics ] *WS
+     *            CLOSE-ANGLE-BRACKET
      * return-args = RETURN-ARROW *WS nonempty-arg-list
      *
      * exact-search = [type-filter *WS COLON] *WS QUOTE ident QUOTE *WS [generics]
-     * type-search = [type-filter *WS COLON] *WS path *WS generics
+     * type-search = [type-filter *WS COLON] *WS path *WS nonempty-arg-list
      *
      * query = *WS (exact-search / type-search / return-args) *WS
      *
@@ -533,6 +546,7 @@ window.initSearch = function(rawSearchIndex) {
      * WS = %x09 / " "
      *
      * @param  {string} val     - The user query
+     *
      * @return {ParsedQuery}    - The parsed query
      */
     function parseQuery(userQuery) {
@@ -567,7 +581,7 @@ window.initSearch = function(rawSearchIndex) {
         query.foundElems = query.elems.length + query.returned.length;
         if (query.foundElems === 0 && parserState.length !== 0) {
             // In this case, we'll simply keep whatever was entered by the user...
-            createQueryElement(query, parserState, query.elems, userQuery, []);
+            query.elems.push(createQueryElement(query, parserState, userQuery, []));
             query.foundElems += 1;
         }
         return query;
@@ -580,6 +594,7 @@ window.initSearch = function(rawSearchIndex) {
      * @param {Array<Result>} results_returned
      * @param {Array<Result>} results_in_args
      * @param {ParsedQuery} parsedQuery
+     *
      * @return {ResultsTable}
      */
     function createQueryResults(results_in_args, results_returned, results_others, parsedQuery) {
@@ -597,6 +612,7 @@ window.initSearch = function(rawSearchIndex) {
      * @param  {ParsedQuery} parsedQuery - The parsed user query
      * @param  {Object} searchWords      - The list of search words to query against
      * @param  {Object} [filterCrates]   - Crate to search in if defined
+     *
      * @return {ResultsTable}
      */
     function execQuery(parsedQuery, searchWords, filterCrates) {
@@ -634,12 +650,7 @@ window.initSearch = function(rawSearchIndex) {
         }
 
         function sortResults(results, isType) {
-            var nameSplit = null;
-            if (parsedQuery.elems.length === 1) {
-                var hasPath = typeof parsedQuery.elems[0].path === "undefined";
-                nameSplit = hasPath ? null : parsedQuery.elems[0].path;
-            }
-            var query = parsedQuery.userQuery;
+            var userQuery = parsedQuery.userQuery;
             var ar = [];
             for (var entry in results) {
                 if (hasOwnPropertyRustdoc(results, entry)) {
@@ -659,8 +670,8 @@ window.initSearch = function(rawSearchIndex) {
                 var a, b;
 
                 // sort by exact match with regard to the last word (mismatch goes later)
-                a = (aaa.word !== query);
-                b = (bbb.word !== query);
+                a = (aaa.word !== userQuery);
+                b = (bbb.word !== userQuery);
                 if (a !== b) { return a - b; }
 
                 // Sort by non levenshtein results and then levenshtein results by the distance
@@ -722,6 +733,12 @@ window.initSearch = function(rawSearchIndex) {
                 return 0;
             });
 
+            var nameSplit = null;
+            if (parsedQuery.elems.length === 1) {
+                var hasPath = typeof parsedQuery.elems[0].path === "undefined";
+                nameSplit = hasPath ? null : parsedQuery.elems[0].path;
+            }
+
             for (var i = 0, len = results.length; i < len; ++i) {
                 result = results[i];
 
@@ -763,7 +780,7 @@ window.initSearch = function(rawSearchIndex) {
             // match as well.
             var elem_name;
             if (elem.generics.length > 0 && row[GENERICS_DATA].length >= elem.generics.length) {
-                var elems = {};
+                var elems = Object.create(null);
                 for (var x = 0, length = row[GENERICS_DATA].length; x < length; ++x) {
                     elem_name = row[GENERICS_DATA][x][NAME];
                     if (elem_name === "") {
@@ -935,6 +952,8 @@ window.initSearch = function(rawSearchIndex) {
         }
 
         /**
+         * This function checks if the object (`row`) returns the given type (`elem`).
+         *
          * @param {Row} row
          * @param {QueryElement} elem   - The element from the parsed query.
          * @param {integer} typeFilter
@@ -1103,7 +1122,7 @@ window.initSearch = function(rawSearchIndex) {
          * * `index` is an `integer`` used to sort by the position of the word in the item's name.
          * * `lev` is the main metric used to sort the search results.
          *
-         * @param {Object} results
+         * @param {Results} results
          * @param {string} fullId
          * @param {integer} id
          * @param {integer} index
@@ -1130,10 +1149,21 @@ window.initSearch = function(rawSearchIndex) {
          * This function is called in case the query is only one element (with or without generics).
          *
          * @param {Row} row
-         * @param {integer} pos           - Position in the `searchIndex`.
-         * @param {QueryElement} elem     - The element from the parsed query.
+         * @param {integer} pos              - Position in the `searchIndex`.
+         * @param {QueryElement} elem        - The element from the parsed query.
+         * @param {Results} results_others   - Unqualified results (not in arguments nor in
+         *                                     returned values).
+         * @param {Results} results_in_args  - Matching arguments results.
+         * @param {Results} results_returned - Matching returned arguments results.
          */
-        function handleSingleArg(row, pos, elem) {
+        function handleSingleArg(
+            row,
+            pos,
+            elem,
+            results_others,
+            results_in_args,
+            results_returned
+        ) {
             if (!row || (filterCrates !== null && row.crate !== filterCrates)) {
                 return;
             }
@@ -1261,7 +1291,14 @@ window.initSearch = function(rawSearchIndex) {
                     for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
                         // It means we want to check for this element everywhere (in names, args and
                         // returned).
-                        handleSingleArg(searchIndex[i], i, elem);
+                        handleSingleArg(
+                            searchIndex[i],
+                            i,
+                            elem,
+                            results_others,
+                            results_in_args,
+                            results_returned
+                        );
                     }
                 } else if (parsedQuery.returned.length === 1) {
                     // We received one returned argument to check, so looking into returned values.
@@ -1315,6 +1352,7 @@ window.initSearch = function(rawSearchIndex) {
      * @param  {string} path   - The path of the result
      * @param  {string} keys   - The keys to be used (["file", "open"])
      * @param  {Object} parent - The parent of the result
+     *
      * @return {boolean}       - Whether the result is valid or not
      */
     function validateResult(name, path, keys, parent) {
diff --git a/src/test/rustdoc-js-std/parser-errors.js b/src/test/rustdoc-js-std/parser-errors.js
index d4cd9facf17..080f82b41ec 100644
--- a/src/test/rustdoc-js-std/parser-errors.js
+++ b/src/test/rustdoc-js-std/parser-errors.js
@@ -1,4 +1,6 @@
 const QUERY = [
+    '<P>',
+    '-> <P>',
     '<"P">',
     '"P" "P"',
     'P "P"',
@@ -16,12 +18,32 @@ const QUERY = [
     "a b:",
     "a (b:",
     "{:",
+    "a-bb",
+    "a>bb",
 ];
 
 const PARSED = [
     {
         elems: [],
         foundElems: 0,
+        original: "<P>",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "<p>",
+        error: "Found generics without a path",
+    },
+    {
+        elems: [],
+        foundElems: 0,
+        original: "-> <P>",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "-> <p>",
+        error: "Found generics without a path",
+    },
+    {
+        elems: [],
+        foundElems: 0,
         original: "<\"P\">",
         returned: [],
         typeFilter: -1,
@@ -172,4 +194,22 @@ const PARSED = [
         userQuery: "{:",
         error: "Unknown type filter `{`",
     },
+    {
+        elems: [],
+        foundElems: 0,
+        original: "a-bb",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "a-bb",
+        error: "Unexpected `-` (did you mean `->`?)",
+    },
+    {
+        elems: [],
+        foundElems: 0,
+        original: "a>bb",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "a>bb",
+        error: "Unexpected `>` (did you mean `->`?)",
+    },
 ];
diff --git a/src/test/rustdoc-js-std/parser-generics.js b/src/test/rustdoc-js-std/parser-generics.js
index cf8d99ef22a..cc92f2333d2 100644
--- a/src/test/rustdoc-js-std/parser-generics.js
+++ b/src/test/rustdoc-js-std/parser-generics.js
@@ -1,30 +1,7 @@
-const QUERY = ['<P>', 'A<B<C<D>,  E>', 'p<> u8'];
+const QUERY = ['A<B<C<D>,  E>', 'p<> u8'];
 
 const PARSED = [
     {
-        elems: [{
-            name: "",
-            fullPath: [""],
-            pathWithoutLast: [],
-            pathLast: "",
-            generics: [
-                {
-                    name: "p",
-                    fullPath: ["p"],
-                    pathWithoutLast: [],
-                    pathLast: "p",
-                    generics: [],
-                },
-            ],
-        }],
-        foundElems: 1,
-        original: "<P>",
-        returned: [],
-        typeFilter: -1,
-        userQuery: "<p>",
-        error: null,
-    },
-    {
         elems: [],
         foundElems: 0,
         original: 'A<B<C<D>,  E>',
diff --git a/src/test/rustdoc-js-std/parser-returned.js b/src/test/rustdoc-js-std/parser-returned.js
index db64b03c0b3..8910275c91e 100644
--- a/src/test/rustdoc-js-std/parser-returned.js
+++ b/src/test/rustdoc-js-std/parser-returned.js
@@ -1,15 +1,15 @@
-const QUERY = ['-> <P>', '-> P'];
+const QUERY = ['-> F<P>', '-> P'];
 
 const PARSED = [
     {
         elems: [],
         foundElems: 1,
-        original: "-> <P>",
+        original: "-> F<P>",
         returned: [{
-            name: "",
-            fullPath: [""],
+            name: "f",
+            fullPath: ["f"],
             pathWithoutLast: [],
-            pathLast: "",
+            pathLast: "f",
             generics: [
                 {
                     name: "p",
@@ -21,7 +21,7 @@ const PARSED = [
             ],
         }],
         typeFilter: -1,
-        userQuery: "-> <p>",
+        userQuery: "-> f<p>",
         error: null,
     },
     {
diff --git a/src/test/rustdoc-js-std/parser-invalid.js b/src/test/rustdoc-js-std/parser-weird-queries.js
index 87ebe21c49b..87ebe21c49b 100644
--- a/src/test/rustdoc-js-std/parser-invalid.js
+++ b/src/test/rustdoc-js-std/parser-weird-queries.js