Rollup merge of #108143 - notriddle:notriddle/filter-exclamation-macro, r=GuillaumeGomez

rustdoc: search by macro when query ends with `!`

Related to #96399

Note: the `never` type alias is tested in [`/tests/rustdoc-js-std/alias-3.js`](08ad401633/tests/rustdoc-js-std/alias-3.js)

## Before

![image](https://user-images.githubusercontent.com/1593513/219504192-54cc0753-ff97-4a37-ad4a-8ae915181325.png)

## After

![image](https://user-images.githubusercontent.com/1593513/219504251-589a7e11-1e7b-4b7b-879d-1b564080017c.png)
This commit is contained in:
Dylan DPC 2023-03-01 23:40:18 +05:30 committed by GitHub
commit f03e5345aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 137 additions and 25 deletions

View File

@ -84,6 +84,9 @@ When typing in the search bar, you can prefix your search term with a type
followed by a colon (such as `mod:`) to restrict the results to just that followed by a colon (such as `mod:`) to restrict the results to just that
kind of item. (The available items are listed in the help popup.) kind of item. (The available items are listed in the help popup.)
Searching for `println!` will search for a macro named `println`, just like
searching for `macro:println` does.
### Changing displayed theme ### Changing displayed theme
You can change the displayed theme by opening the settings menu (the gear You can change the displayed theme by opening the settings menu (the gear

View File

@ -300,20 +300,21 @@ function initSearch(rawSearchIndex) {
* @return {integer} * @return {integer}
*/ */
function getIdentEndPosition(parserState) { function getIdentEndPosition(parserState) {
const start = parserState.pos;
let end = parserState.pos; let end = parserState.pos;
let foundExclamation = false; let foundExclamation = -1;
while (parserState.pos < parserState.length) { while (parserState.pos < parserState.length) {
const c = parserState.userQuery[parserState.pos]; const c = parserState.userQuery[parserState.pos];
if (!isIdentCharacter(c)) { if (!isIdentCharacter(c)) {
if (c === "!") { if (c === "!") {
if (foundExclamation) { if (foundExclamation !== -1) {
throw new Error("Cannot have more than one `!` in an ident"); throw new Error("Cannot have more than one `!` in an ident");
} else if (parserState.pos + 1 < parserState.length && } else if (parserState.pos + 1 < parserState.length &&
isIdentCharacter(parserState.userQuery[parserState.pos + 1]) isIdentCharacter(parserState.userQuery[parserState.pos + 1])
) { ) {
throw new Error("`!` can only be at the end of an ident"); throw new Error("`!` can only be at the end of an ident");
} }
foundExclamation = true; foundExclamation = parserState.pos;
} else if (isErrorCharacter(c)) { } else if (isErrorCharacter(c)) {
throw new Error(`Unexpected \`${c}\``); throw new Error(`Unexpected \`${c}\``);
} else if ( } else if (
@ -326,9 +327,18 @@ function initSearch(rawSearchIndex) {
if (!isPathStart(parserState)) { if (!isPathStart(parserState)) {
break; 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 ":". // Skip current ":".
parserState.pos += 1; parserState.pos += 1;
foundExclamation = false;
} else { } else {
throw new Error(`Unexpected \`${c}\``); throw new Error(`Unexpected \`${c}\``);
} }
@ -336,6 +346,16 @@ function initSearch(rawSearchIndex) {
parserState.pos += 1; parserState.pos += 1;
end = parserState.pos; 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; return end;
} }
@ -589,8 +609,8 @@ function initSearch(rawSearchIndex) {
* *
* The supported syntax by this parser is as follow: * The supported syntax by this parser is as follow:
* *
* ident = *(ALPHA / DIGIT / "_") [!] * ident = *(ALPHA / DIGIT / "_")
* path = ident *(DOUBLE-COLON ident) * path = ident *(DOUBLE-COLON ident) [!]
* arg = path [generics] * arg = path [generics]
* arg-without-generic = path * arg-without-generic = path
* type-sep = COMMA/WS *(COMMA/WS) * type-sep = COMMA/WS *(COMMA/WS)

View File

@ -37,6 +37,8 @@ const QUERY = [
"mod : :", "mod : :",
"a!a", "a!a",
"a!!", "a!!",
"mod:a!",
"a!::a",
]; ];
const PARSED = [ const PARSED = [
@ -382,4 +384,22 @@ const PARSED = [
userQuery: "a!!", userQuery: "a!!",
error: 'Cannot have more than one `!` in an ident', 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',
},
]; ];

View File

@ -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 = [ const PARSED = [
{ {
@ -40,4 +40,49 @@ const PARSED = [
userQuery: "macro<f>:foo", userQuery: "macro<f>:foo",
error: "Unexpected `:`", 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,
},
]; ];

View File

@ -3,6 +3,7 @@ const QUERY = [
"!", "!",
"a!", "a!",
"a!::b", "a!::b",
"!::b",
"a!::b!", "a!::b!",
]; ];
@ -47,47 +48,50 @@ const PARSED = [
}, },
{ {
elems: [{ elems: [{
name: "a!", name: "a",
fullPath: ["a!"], fullPath: ["a"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "a!", pathLast: "a",
generics: [], generics: [],
}], }],
foundElems: 1, foundElems: 1,
original: "a!", original: "a!",
returned: [], returned: [],
typeFilter: -1, typeFilter: 14,
userQuery: "a!", userQuery: "a!",
error: null, error: null,
}, },
{ {
elems: [{ elems: [],
name: "a!::b", foundElems: 0,
fullPath: ["a!", "b"],
pathWithoutLast: ["a!"],
pathLast: "b",
generics: [],
}],
foundElems: 1,
original: "a!::b", original: "a!::b",
returned: [], returned: [],
typeFilter: -1, typeFilter: -1,
userQuery: "a!::b", userQuery: "a!::b",
error: null, error: "Cannot have associated items in macros",
}, },
{ {
elems: [{ elems: [{
name: "a!::b!", name: "!::b",
fullPath: ["a!", "b!"], fullPath: ["!", "b"],
pathWithoutLast: ["a!"], pathWithoutLast: ["!"],
pathLast: "b!", pathLast: "b",
generics: [], generics: [],
}], }],
foundElems: 1, foundElems: 1,
original: "!::b",
returned: [],
typeFilter: -1,
userQuery: "!::b",
error: null,
},
{
elems: [],
foundElems: 0,
original: "a!::b!", original: "a!::b!",
returned: [], returned: [],
typeFilter: -1, typeFilter: -1,
userQuery: "a!::b!", userQuery: "a!::b!",
error: null, error: "Cannot have associated items in macros",
}, },
]; ];

View File

@ -0,0 +1,10 @@
// exact-check
const QUERY = 'abracadabra!';
const EXPECTED = {
'others': [
{ 'path': 'macro_search', 'name': 'abracadabra' },
{ 'path': 'macro_search', 'name': 'abracadabra_b' },
],
};

View File

@ -0,0 +1,10 @@
#[macro_export]
macro_rules! abracadabra {
() => {}
}
#[macro_export]
macro_rules! abracadabra_b {
() => {}
}
pub fn abracadabra() {}
pub fn abracadabra_c() {}