about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2023-02-16 15:32:38 -0700
committerMichael Howell <michael@notriddle.com>2023-02-16 18:16:09 -0700
commit4de9c6d4913a02b5ce19a14e9e2ab0c46ceea771 (patch)
tree4a8d56f30ffd5c60f68262fddb975dbef95ca382
parentc5d1b3ea9665e77e3af2f17b311bf65469eedc19 (diff)
downloadrust-4de9c6d4913a02b5ce19a14e9e2ab0c46ceea771.tar.gz
rust-4de9c6d4913a02b5ce19a14e9e2ab0c46ceea771.zip
rustdoc: search by macro when query ends with `!`
Related to #96399
-rw-r--r--src/librustdoc/html/static/js/search.js28
-rw-r--r--tests/rustdoc-js-std/parser-errors.js20
-rw-r--r--tests/rustdoc-js-std/parser-filter.js47
-rw-r--r--tests/rustdoc-js-std/parser-ident.js40
-rw-r--r--tests/rustdoc-js/macro-search.js10
-rw-r--r--tests/rustdoc-js/macro-search.rs10
6 files changed, 132 insertions, 23 deletions
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 1e6c94d29ba..6a8e93a2436 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -300,20 +300,21 @@ function initSearch(rawSearchIndex) {
      * @return {integer}
      */
     function getIdentEndPosition(parserState) {
+        const start = parserState.pos;
         let end = parserState.pos;
-        let foundExclamation = false;
+        let foundExclamation = -1;
         while (parserState.pos < parserState.length) {
             const c = parserState.userQuery[parserState.pos];
             if (!isIdentCharacter(c)) {
                 if (c === "!") {
-                    if (foundExclamation) {
+                    if (foundExclamation !== -1) {
                         throw new Error("Cannot have more than one `!` in an ident");
                     } else if (parserState.pos + 1 < parserState.length &&
                         isIdentCharacter(parserState.userQuery[parserState.pos + 1])
                     ) {
                         throw new Error("`!` can only be at the end of an ident");
                     }
-                    foundExclamation = true;
+                    foundExclamation = parserState.pos;
                 } else if (isErrorCharacter(c)) {
                     throw new Error(`Unexpected \`${c}\``);
                 } else if (
@@ -326,9 +327,18 @@ function initSearch(rawSearchIndex) {
                     if (!isPathStart(parserState)) {
                         break;
                     }
+                    if (foundExclamation !== -1) {
+                        if (start <= (end - 2)) {
+                            throw new Error("Cannot have associated items in macros");
+                        } else {
+                            // if start == end - 1, we got the never type
+                            // while the never type has no associated macros, we still
+                            // can parse a path like that
+                            foundExclamation = -1;
+                        }
+                    }
                     // Skip current ":".
                     parserState.pos += 1;
-                    foundExclamation = false;
                 } else {
                     throw new Error(`Unexpected \`${c}\``);
                 }
@@ -336,6 +346,16 @@ function initSearch(rawSearchIndex) {
             parserState.pos += 1;
             end = parserState.pos;
         }
+        // if start == end - 1, we got the never type
+        if (foundExclamation !== -1 && start <= (end - 2)) {
+            if (parserState.typeFilter === null) {
+                parserState.typeFilter = "macro";
+            } else if (parserState.typeFilter !== "macro") {
+                throw new Error(`Invalid search type: macro \`!\` and ` +
+                    `\`${parserState.typeFilter}\` both specified`);
+            }
+            end = foundExclamation;
+        }
         return end;
     }
 
diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js
index dc42031e05f..f82a2472063 100644
--- a/tests/rustdoc-js-std/parser-errors.js
+++ b/tests/rustdoc-js-std/parser-errors.js
@@ -37,6 +37,8 @@ const QUERY = [
     "mod : :",
     "a!a",
     "a!!",
+    "mod:a!",
+    "a!::a",
 ];
 
 const PARSED = [
@@ -382,4 +384,22 @@ const PARSED = [
         userQuery: "a!!",
         error: 'Cannot have more than one `!` in an ident',
     },
+    {
+        elems: [],
+        foundElems: 0,
+        original: "mod:a!",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "mod:a!",
+        error: 'Invalid search type: macro `!` and `mod` both specified',
+    },
+    {
+        elems: [],
+        foundElems: 0,
+        original: "a!::a",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "a!::a",
+        error: 'Cannot have associated items in macros',
+    },
 ];
diff --git a/tests/rustdoc-js-std/parser-filter.js b/tests/rustdoc-js-std/parser-filter.js
index e5a87a415ac..01f65b478f8 100644
--- a/tests/rustdoc-js-std/parser-filter.js
+++ b/tests/rustdoc-js-std/parser-filter.js
@@ -1,4 +1,4 @@
-const QUERY = ['fn:foo', 'enum : foo', 'macro<f>:foo'];
+const QUERY = ['fn:foo', 'enum : foo', 'macro<f>:foo', 'macro!', 'macro:mac!', 'a::mac!'];
 
 const PARSED = [
     {
@@ -40,4 +40,49 @@ const PARSED = [
         userQuery: "macro<f>:foo",
         error: "Unexpected `:`",
     },
+    {
+        elems: [{
+            name: "macro",
+            fullPath: ["macro"],
+            pathWithoutLast: [],
+            pathLast: "macro",
+            generics: [],
+        }],
+        foundElems: 1,
+        original: "macro!",
+        returned: [],
+        typeFilter: 14,
+        userQuery: "macro!",
+        error: null,
+    },
+    {
+        elems: [{
+            name: "mac",
+            fullPath: ["mac"],
+            pathWithoutLast: [],
+            pathLast: "mac",
+            generics: [],
+        }],
+        foundElems: 1,
+        original: "macro:mac!",
+        returned: [],
+        typeFilter: 14,
+        userQuery: "macro:mac!",
+        error: null,
+    },
+    {
+        elems: [{
+            name: "a::mac",
+            fullPath: ["a", "mac"],
+            pathWithoutLast: ["a"],
+            pathLast: "mac",
+            generics: [],
+        }],
+        foundElems: 1,
+        original: "a::mac!",
+        returned: [],
+        typeFilter: 14,
+        userQuery: "a::mac!",
+        error: null,
+    },
 ];
diff --git a/tests/rustdoc-js-std/parser-ident.js b/tests/rustdoc-js-std/parser-ident.js
index 4b5ab01ac76..6c17d00f16e 100644
--- a/tests/rustdoc-js-std/parser-ident.js
+++ b/tests/rustdoc-js-std/parser-ident.js
@@ -3,6 +3,7 @@ const QUERY = [
     "!",
     "a!",
     "a!::b",
+    "!::b",
     "a!::b!",
 ];
 
@@ -47,47 +48,50 @@ const PARSED = [
     },
     {
         elems: [{
-            name: "a!",
-            fullPath: ["a!"],
+            name: "a",
+            fullPath: ["a"],
             pathWithoutLast: [],
-            pathLast: "a!",
+            pathLast: "a",
             generics: [],
         }],
         foundElems: 1,
         original: "a!",
         returned: [],
-        typeFilter: -1,
+        typeFilter: 14,
         userQuery: "a!",
         error: null,
     },
     {
-        elems: [{
-            name: "a!::b",
-            fullPath: ["a!", "b"],
-            pathWithoutLast: ["a!"],
-            pathLast: "b",
-            generics: [],
-        }],
-        foundElems: 1,
+        elems: [],
+        foundElems: 0,
         original: "a!::b",
         returned: [],
         typeFilter: -1,
         userQuery: "a!::b",
-        error: null,
+        error: "Cannot have associated items in macros",
     },
     {
         elems: [{
-            name: "a!::b!",
-            fullPath: ["a!", "b!"],
-            pathWithoutLast: ["a!"],
-            pathLast: "b!",
+            name: "!::b",
+            fullPath: ["!", "b"],
+            pathWithoutLast: ["!"],
+            pathLast: "b",
             generics: [],
         }],
         foundElems: 1,
+        original: "!::b",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "!::b",
+        error: null,
+    },
+    {
+        elems: [],
+        foundElems: 0,
         original: "a!::b!",
         returned: [],
         typeFilter: -1,
         userQuery: "a!::b!",
-        error: null,
+        error: "Cannot have associated items in macros",
     },
 ];
diff --git a/tests/rustdoc-js/macro-search.js b/tests/rustdoc-js/macro-search.js
new file mode 100644
index 00000000000..2b179ce146b
--- /dev/null
+++ b/tests/rustdoc-js/macro-search.js
@@ -0,0 +1,10 @@
+// exact-check
+
+const QUERY = 'abracadabra!';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'macro_search', 'name': 'abracadabra' },
+        { 'path': 'macro_search', 'name': 'abracadabra_b' },
+    ],
+};
diff --git a/tests/rustdoc-js/macro-search.rs b/tests/rustdoc-js/macro-search.rs
new file mode 100644
index 00000000000..dc397490cf5
--- /dev/null
+++ b/tests/rustdoc-js/macro-search.rs
@@ -0,0 +1,10 @@
+#[macro_export]
+macro_rules! abracadabra {
+    () => {}
+}
+#[macro_export]
+macro_rules! abracadabra_b {
+    () => {}
+}
+pub fn abracadabra() {}
+pub fn abracadabra_c() {}