Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustdoc: search by macro when query ends with ! #108143

Merged
merged 4 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/doc/rustdoc/src/how-to-read-rustdoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
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

You can change the displayed theme by opening the settings menu (the gear
Expand Down
32 changes: 26 additions & 6 deletions src/librustdoc/html/static/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -326,16 +327,35 @@ 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}\``);
}
}
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;
}

Expand Down Expand Up @@ -591,8 +611,8 @@ function initSearch(rawSearchIndex) {
*
* The supported syntax by this parser is as follow:
*
* ident = *(ALPHA / DIGIT / "_") [!]
* path = ident *(DOUBLE-COLON ident)
* ident = *(ALPHA / DIGIT / "_")
* path = ident *(DOUBLE-COLON ident) [!]
notriddle marked this conversation as resolved.
Show resolved Hide resolved
* arg = path [generics]
* arg-without-generic = path
* type-sep = COMMA/WS *(COMMA/WS)
Expand Down
20 changes: 20 additions & 0 deletions tests/rustdoc-js-std/parser-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const QUERY = [
"mod : :",
"a!a",
"a!!",
"mod:a!",
"a!::a",
];

const PARSED = [
Expand Down Expand Up @@ -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',
},
];
47 changes: 46 additions & 1 deletion tests/rustdoc-js-std/parser-filter.js
Original file line number Diff line number Diff line change
@@ -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 = [
{
Expand Down Expand Up @@ -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,
},
];
40 changes: 22 additions & 18 deletions tests/rustdoc-js-std/parser-ident.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const QUERY = [
"!",
"a!",
"a!::b",
"!::b",
"a!::b!",
];

Expand Down Expand Up @@ -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",
},
];
10 changes: 10 additions & 0 deletions tests/rustdoc-js/macro-search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// exact-check

const QUERY = 'abracadabra!';

const EXPECTED = {
'others': [
{ 'path': 'macro_search', 'name': 'abracadabra' },
{ 'path': 'macro_search', 'name': 'abracadabra_b' },
],
};
10 changes: 10 additions & 0 deletions tests/rustdoc-js/macro-search.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[macro_export]
macro_rules! abracadabra {
() => {}
}
#[macro_export]
macro_rules! abracadabra_b {
() => {}
}
pub fn abracadabra() {}
pub fn abracadabra_c() {}