mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
rustdoc-search: add search query syntax Fn(T) -> U
This is implemented, in addition to the ML-style one, because Rust does it. If we don't, we'll never hear the end of it. This commit also refactors some duplicate parts of the parser into a dedicated function.
This commit is contained in:
parent
23e931fd07
commit
7b926555b7
@ -153,16 +153,26 @@ will match these queries:
|
||||
|
||||
But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`.
|
||||
|
||||
To search for a function that accepts a function as a parameter,
|
||||
like `Iterator::all`, wrap the nested signature in parenthesis,
|
||||
as in [`Iterator<T>, (T -> bool) -> bool`][iterator-all].
|
||||
You can also search for a specific closure trait,
|
||||
such as `Iterator<T>, (FnMut(T) -> bool) -> bool`,
|
||||
but you need to know which one you want.
|
||||
|
||||
[iterator-all]: ../../std/vec/struct.Vec.html?search=Iterator<T>%2C+(T+->+bool)+->+bool&filter-crate=std
|
||||
|
||||
### Primitives with Special Syntax
|
||||
|
||||
| Shorthand | Explicit names |
|
||||
| --------- | ------------------------------------------------ |
|
||||
| `[]` | `primitive:slice` and/or `primitive:array` |
|
||||
| `[T]` | `primitive:slice<T>` and/or `primitive:array<T>` |
|
||||
| `()` | `primitive:unit` and/or `primitive:tuple` |
|
||||
| `(T)` | `T` |
|
||||
| `(T,)` | `primitive:tuple<T>` |
|
||||
| `!` | `primitive:never` |
|
||||
| Shorthand | Explicit names |
|
||||
| ---------------- | ------------------------------------------------- |
|
||||
| `[]` | `primitive:slice` and/or `primitive:array` |
|
||||
| `[T]` | `primitive:slice<T>` and/or `primitive:array<T>` |
|
||||
| `()` | `primitive:unit` and/or `primitive:tuple` |
|
||||
| `(T)` | `T` |
|
||||
| `(T,)` | `primitive:tuple<T>` |
|
||||
| `!` | `primitive:never` |
|
||||
| `(T, U -> V, W)` | `fn(T, U) -> (V, W)`, `Fn`, `FnMut`, and `FnOnce` |
|
||||
|
||||
When searching for `[]`, Rustdoc will return search results with either slices
|
||||
or arrays. If you know which one you want, you can force it to return results
|
||||
@ -182,6 +192,10 @@ results for types that match tuples, even though it also matches the type on
|
||||
its own. That is, `(u32)` matches `(u32,)` for the exact same reason that it
|
||||
also matches `Result<u32, Error>`.
|
||||
|
||||
The `->` operator has lower precedence than comma. If it's not wrapped
|
||||
in brackets, it delimits the return value for the function being searched for.
|
||||
To search for functions that take functions as parameters, use parenthesis.
|
||||
|
||||
### Limitations and quirks of type-based search
|
||||
|
||||
Type-based search is still a buggy, experimental, work-in-progress feature.
|
||||
@ -220,9 +234,6 @@ Most of these limitations should be addressed in future version of Rustdoc.
|
||||
|
||||
* Searching for lifetimes is not supported.
|
||||
|
||||
* It's impossible to search for closures based on their parameters or
|
||||
return values.
|
||||
|
||||
* It's impossible to search based on the length of an array.
|
||||
|
||||
## Item filtering
|
||||
@ -239,19 +250,21 @@ Item filters can be used in both name-based and type signature-based searches.
|
||||
|
||||
```text
|
||||
ident = *(ALPHA / DIGIT / "_")
|
||||
path = ident *(DOUBLE-COLON ident) [!]
|
||||
path = ident *(DOUBLE-COLON ident) [BANG]
|
||||
slice-like = OPEN-SQUARE-BRACKET [ nonempty-arg-list ] CLOSE-SQUARE-BRACKET
|
||||
tuple-like = OPEN-PAREN [ nonempty-arg-list ] CLOSE-PAREN
|
||||
arg = [type-filter *WS COLON *WS] (path [generics] / slice-like / tuple-like / [!])
|
||||
arg = [type-filter *WS COLON *WS] (path [generics] / slice-like / tuple-like)
|
||||
type-sep = COMMA/WS *(COMMA/WS)
|
||||
nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep)
|
||||
nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep) [ return-args ]
|
||||
generic-arg-list = *(type-sep) arg [ EQUAL arg ] *(type-sep arg [ EQUAL arg ]) *(type-sep)
|
||||
generics = OPEN-ANGLE-BRACKET [ generic-arg-list ] *(type-sep)
|
||||
normal-generics = OPEN-ANGLE-BRACKET [ generic-arg-list ] *(type-sep)
|
||||
CLOSE-ANGLE-BRACKET
|
||||
fn-like-generics = OPEN-PAREN [ nonempty-arg-list ] CLOSE-PAREN [ RETURN-ARROW arg ]
|
||||
generics = normal-generics / fn-like-generics
|
||||
return-args = RETURN-ARROW *(type-sep) nonempty-arg-list
|
||||
|
||||
exact-search = [type-filter *WS COLON] [ RETURN-ARROW ] *WS QUOTE ident QUOTE [ generics ]
|
||||
type-search = [ nonempty-arg-list ] [ return-args ]
|
||||
type-search = [ nonempty-arg-list ]
|
||||
|
||||
query = *WS (exact-search / type-search) *WS
|
||||
|
||||
@ -296,6 +309,7 @@ QUOTE = %x22
|
||||
COMMA = ","
|
||||
RETURN-ARROW = "->"
|
||||
EQUAL = "="
|
||||
BANG = "!"
|
||||
|
||||
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
|
||||
DIGIT = %x30-39
|
||||
|
@ -1,3 +1,4 @@
|
||||
// ignore-tidy-filelength
|
||||
/* global addClass, getNakedUrl, getSettingValue */
|
||||
/* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi, exports */
|
||||
|
||||
@ -578,7 +579,10 @@ function initSearch(rawSearchIndex) {
|
||||
// Syntactically, bindings are parsed as generics,
|
||||
// but the query engine treats them differently.
|
||||
if (gen.bindingName !== null) {
|
||||
bindings.set(gen.bindingName.name, [gen, ...gen.bindingName.generics]);
|
||||
if (gen.name !== null) {
|
||||
gen.bindingName.generics.unshift(gen);
|
||||
}
|
||||
bindings.set(gen.bindingName.name, gen.bindingName.generics);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -678,6 +682,38 @@ function initSearch(rawSearchIndex) {
|
||||
return end;
|
||||
}
|
||||
|
||||
function getFilteredNextElem(query, parserState, elems, isInGenerics) {
|
||||
const start = parserState.pos;
|
||||
if (parserState.userQuery[parserState.pos] === ":" && !isPathStart(parserState)) {
|
||||
throw ["Expected type filter before ", ":"];
|
||||
}
|
||||
getNextElem(query, parserState, elems, isInGenerics);
|
||||
if (parserState.userQuery[parserState.pos] === ":" && !isPathStart(parserState)) {
|
||||
if (parserState.typeFilter !== null) {
|
||||
throw [
|
||||
"Unexpected ",
|
||||
":",
|
||||
" (expected path after type filter ",
|
||||
parserState.typeFilter + ":",
|
||||
")",
|
||||
];
|
||||
}
|
||||
if (elems.length === 0) {
|
||||
throw ["Expected type filter before ", ":"];
|
||||
} else if (query.literalSearch) {
|
||||
throw ["Cannot use quotes on type filter"];
|
||||
}
|
||||
// The type filter doesn't count as an element since it's a modifier.
|
||||
const typeFilterElem = elems.pop();
|
||||
checkExtraTypeFilterCharacters(start, parserState);
|
||||
parserState.typeFilter = typeFilterElem.name;
|
||||
parserState.pos += 1;
|
||||
parserState.totalElems -= 1;
|
||||
query.literalSearch = false;
|
||||
getNextElem(query, parserState, elems, isInGenerics);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ParsedQuery} query
|
||||
* @param {ParserState} parserState
|
||||
@ -752,6 +788,32 @@ function initSearch(rawSearchIndex) {
|
||||
}
|
||||
parserState.pos += 1;
|
||||
getItemsBefore(query, parserState, generics, ">");
|
||||
} else if (parserState.pos < parserState.length &&
|
||||
parserState.userQuery[parserState.pos] === "("
|
||||
) {
|
||||
if (start >= end) {
|
||||
throw ["Found generics without a path"];
|
||||
}
|
||||
if (parserState.isInBinding) {
|
||||
throw ["Unexpected ", "(", " after ", "="];
|
||||
}
|
||||
parserState.pos += 1;
|
||||
const typeFilter = parserState.typeFilter;
|
||||
parserState.typeFilter = null;
|
||||
getItemsBefore(query, parserState, generics, ")");
|
||||
skipWhitespace(parserState);
|
||||
if (isReturnArrow(parserState)) {
|
||||
parserState.pos += 2;
|
||||
skipWhitespace(parserState);
|
||||
getFilteredNextElem(query, parserState, generics, isInGenerics);
|
||||
generics[generics.length - 1].bindingName = makePrimitiveElement("output");
|
||||
} else {
|
||||
generics.push(makePrimitiveElement(null, {
|
||||
bindingName: makePrimitiveElement("output"),
|
||||
typeFilter: null,
|
||||
}));
|
||||
}
|
||||
parserState.typeFilter = typeFilter;
|
||||
}
|
||||
if (isStringElem) {
|
||||
skipWhitespace(parserState);
|
||||
@ -811,7 +873,6 @@ function initSearch(rawSearchIndex) {
|
||||
function getItemsBefore(query, parserState, elems, endChar) {
|
||||
let foundStopChar = true;
|
||||
let foundSeparator = false;
|
||||
let start = parserState.pos;
|
||||
|
||||
// If this is a generic, keep the outer item's type filter around.
|
||||
const oldTypeFilter = parserState.typeFilter;
|
||||
@ -874,24 +935,6 @@ function initSearch(rawSearchIndex) {
|
||||
continue;
|
||||
} else if (c === ":" && isPathStart(parserState)) {
|
||||
throw ["Unexpected ", "::", ": paths cannot start with ", "::"];
|
||||
} else if (c === ":") {
|
||||
if (parserState.typeFilter !== null) {
|
||||
throw ["Unexpected ", ":"];
|
||||
}
|
||||
if (elems.length === 0) {
|
||||
throw ["Expected type filter before ", ":"];
|
||||
} else if (query.literalSearch) {
|
||||
throw ["Cannot use quotes on type filter"];
|
||||
}
|
||||
// The type filter doesn't count as an element since it's a modifier.
|
||||
const typeFilterElem = elems.pop();
|
||||
checkExtraTypeFilterCharacters(start, parserState);
|
||||
parserState.typeFilter = typeFilterElem.name;
|
||||
parserState.pos += 1;
|
||||
parserState.totalElems -= 1;
|
||||
query.literalSearch = false;
|
||||
foundStopChar = true;
|
||||
continue;
|
||||
} else if (isEndCharacter(c)) {
|
||||
throw ["Unexpected ", c, " after ", extra];
|
||||
}
|
||||
@ -926,8 +969,7 @@ function initSearch(rawSearchIndex) {
|
||||
];
|
||||
}
|
||||
const posBefore = parserState.pos;
|
||||
start = parserState.pos;
|
||||
getNextElem(query, parserState, elems, endChar !== "");
|
||||
getFilteredNextElem(query, parserState, elems, endChar !== "");
|
||||
if (endChar !== "" && parserState.pos >= parserState.length) {
|
||||
throw ["Unclosed ", extra];
|
||||
}
|
||||
@ -1004,7 +1046,6 @@ function initSearch(rawSearchIndex) {
|
||||
*/
|
||||
function parseInput(query, parserState) {
|
||||
let foundStopChar = true;
|
||||
let start = parserState.pos;
|
||||
|
||||
while (parserState.pos < parserState.length) {
|
||||
const c = parserState.userQuery[parserState.pos];
|
||||
@ -1022,29 +1063,6 @@ function initSearch(rawSearchIndex) {
|
||||
throw ["Unexpected ", c, " after ", parserState.userQuery[parserState.pos - 1]];
|
||||
}
|
||||
throw ["Unexpected ", c];
|
||||
} else if (c === ":" && !isPathStart(parserState)) {
|
||||
if (parserState.typeFilter !== null) {
|
||||
throw [
|
||||
"Unexpected ",
|
||||
":",
|
||||
" (expected path after type filter ",
|
||||
parserState.typeFilter + ":",
|
||||
")",
|
||||
];
|
||||
} else if (query.elems.length === 0) {
|
||||
throw ["Expected type filter before ", ":"];
|
||||
} else if (query.literalSearch) {
|
||||
throw ["Cannot use quotes on type filter"];
|
||||
}
|
||||
// The type filter doesn't count as an element since it's a modifier.
|
||||
const typeFilterElem = query.elems.pop();
|
||||
checkExtraTypeFilterCharacters(start, parserState);
|
||||
parserState.typeFilter = typeFilterElem.name;
|
||||
parserState.pos += 1;
|
||||
parserState.totalElems -= 1;
|
||||
query.literalSearch = false;
|
||||
foundStopChar = true;
|
||||
continue;
|
||||
} else if (c === " ") {
|
||||
skipWhitespace(parserState);
|
||||
continue;
|
||||
@ -1080,8 +1098,7 @@ function initSearch(rawSearchIndex) {
|
||||
];
|
||||
}
|
||||
const before = query.elems.length;
|
||||
start = parserState.pos;
|
||||
getNextElem(query, parserState, query.elems, false);
|
||||
getFilteredNextElem(query, parserState, query.elems, false);
|
||||
if (query.elems.length === before) {
|
||||
// Nothing was added, weird... Let's increase the position to not remain stuck.
|
||||
parserState.pos += 1;
|
||||
|
@ -195,7 +195,7 @@ const PARSED = [
|
||||
original: "a (b:",
|
||||
returned: [],
|
||||
userQuery: "a (b:",
|
||||
error: "Expected `,`, `:` or `->`, found `(`",
|
||||
error: "Unclosed `(`",
|
||||
},
|
||||
{
|
||||
query: "_:",
|
||||
@ -357,7 +357,16 @@ const PARSED = [
|
||||
original: "a,:",
|
||||
returned: [],
|
||||
userQuery: "a,:",
|
||||
error: 'Unexpected `,` in type filter (before `:`)',
|
||||
error: 'Expected type filter before `:`',
|
||||
},
|
||||
{
|
||||
query: "a!:",
|
||||
elems: [],
|
||||
foundElems: 0,
|
||||
original: "a!:",
|
||||
returned: [],
|
||||
userQuery: "a!:",
|
||||
error: 'Unexpected `!` in type filter (before `:`)',
|
||||
},
|
||||
{
|
||||
query: " a<> :",
|
||||
@ -366,7 +375,7 @@ const PARSED = [
|
||||
original: "a<> :",
|
||||
returned: [],
|
||||
userQuery: "a<> :",
|
||||
error: 'Unexpected `<` in type filter (before `:`)',
|
||||
error: 'Expected `,`, `:` or `->` after `>`, found `:`',
|
||||
},
|
||||
{
|
||||
query: "mod : :",
|
||||
|
@ -1,4 +1,5 @@
|
||||
const PARSED = [
|
||||
// ML-style HOF
|
||||
{
|
||||
query: "(-> F<P>)",
|
||||
elems: [{
|
||||
@ -373,4 +374,339 @@ const PARSED = [
|
||||
userQuery: "x, trait:(aaaaa, b -> a)",
|
||||
error: null,
|
||||
},
|
||||
// Rust-style HOF
|
||||
{
|
||||
query: "Fn () -> F<P>",
|
||||
elems: [{
|
||||
name: "fn",
|
||||
fullPath: ["fn"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "fn",
|
||||
generics: [],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[{
|
||||
name: "f",
|
||||
fullPath: ["f"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "f",
|
||||
generics: [
|
||||
{
|
||||
name: "p",
|
||||
fullPath: ["p"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "p",
|
||||
generics: [],
|
||||
},
|
||||
],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
],
|
||||
],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
foundElems: 1,
|
||||
original: "Fn () -> F<P>",
|
||||
returned: [],
|
||||
userQuery: "fn () -> f<p>",
|
||||
error: null,
|
||||
},
|
||||
{
|
||||
query: "FnMut() -> P",
|
||||
elems: [{
|
||||
name: "fnmut",
|
||||
fullPath: ["fnmut"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "fnmut",
|
||||
generics: [],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[{
|
||||
name: "p",
|
||||
fullPath: ["p"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "p",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
],
|
||||
],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
foundElems: 1,
|
||||
original: "FnMut() -> P",
|
||||
returned: [],
|
||||
userQuery: "fnmut() -> p",
|
||||
error: null,
|
||||
},
|
||||
{
|
||||
query: "(FnMut() -> P)",
|
||||
elems: [{
|
||||
name: "fnmut",
|
||||
fullPath: ["fnmut"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "fnmut",
|
||||
generics: [],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[{
|
||||
name: "p",
|
||||
fullPath: ["p"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "p",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
],
|
||||
],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
foundElems: 1,
|
||||
original: "(FnMut() -> P)",
|
||||
returned: [],
|
||||
userQuery: "(fnmut() -> p)",
|
||||
error: null,
|
||||
},
|
||||
{
|
||||
query: "Fn(F<P>)",
|
||||
elems: [{
|
||||
name: "fn",
|
||||
fullPath: ["fn"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "fn",
|
||||
generics: [{
|
||||
name: "f",
|
||||
fullPath: ["f"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "f",
|
||||
generics: [
|
||||
{
|
||||
name: "p",
|
||||
fullPath: ["p"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "p",
|
||||
generics: [],
|
||||
},
|
||||
],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[],
|
||||
],
|
||||
],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
foundElems: 1,
|
||||
original: "Fn(F<P>)",
|
||||
returned: [],
|
||||
userQuery: "fn(f<p>)",
|
||||
error: null,
|
||||
},
|
||||
{
|
||||
query: "primitive:fnonce(aaaaa, b) -> a",
|
||||
elems: [{
|
||||
name: "fnonce",
|
||||
fullPath: ["fnonce"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "fnonce",
|
||||
generics: [
|
||||
{
|
||||
name: "aaaaa",
|
||||
fullPath: ["aaaaa"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "aaaaa",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
},
|
||||
{
|
||||
name: "b",
|
||||
fullPath: ["b"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "b",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
},
|
||||
],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[{
|
||||
name: "a",
|
||||
fullPath: ["a"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "a",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
],
|
||||
],
|
||||
typeFilter: 1,
|
||||
}],
|
||||
foundElems: 1,
|
||||
original: "primitive:fnonce(aaaaa, b) -> a",
|
||||
returned: [],
|
||||
userQuery: "primitive:fnonce(aaaaa, b) -> a",
|
||||
error: null,
|
||||
},
|
||||
{
|
||||
query: "primitive:fnonce(aaaaa, keyword:b) -> trait:a",
|
||||
elems: [{
|
||||
name: "fnonce",
|
||||
fullPath: ["fnonce"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "fnonce",
|
||||
generics: [
|
||||
{
|
||||
name: "aaaaa",
|
||||
fullPath: ["aaaaa"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "aaaaa",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
},
|
||||
{
|
||||
name: "b",
|
||||
fullPath: ["b"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "b",
|
||||
generics: [],
|
||||
typeFilter: 0,
|
||||
},
|
||||
],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[{
|
||||
name: "a",
|
||||
fullPath: ["a"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "a",
|
||||
generics: [],
|
||||
typeFilter: 10,
|
||||
}],
|
||||
],
|
||||
],
|
||||
typeFilter: 1,
|
||||
}],
|
||||
foundElems: 1,
|
||||
original: "primitive:fnonce(aaaaa, keyword:b) -> trait:a",
|
||||
returned: [],
|
||||
userQuery: "primitive:fnonce(aaaaa, keyword:b) -> trait:a",
|
||||
error: null,
|
||||
},
|
||||
{
|
||||
query: "x, trait:fn(aaaaa, b -> a)",
|
||||
elems: [
|
||||
{
|
||||
name: "x",
|
||||
fullPath: ["x"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "x",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
},
|
||||
{
|
||||
name: "fn",
|
||||
fullPath: ["fn"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "fn",
|
||||
generics: [
|
||||
{
|
||||
name: "->",
|
||||
fullPath: ["->"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "->",
|
||||
generics: [
|
||||
{
|
||||
name: "aaaaa",
|
||||
fullPath: ["aaaaa"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "aaaaa",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
},
|
||||
{
|
||||
name: "b",
|
||||
fullPath: ["b"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "b",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
},
|
||||
],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[{
|
||||
name: "a",
|
||||
fullPath: ["a"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "a",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
],
|
||||
],
|
||||
typeFilter: -1,
|
||||
},
|
||||
],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[],
|
||||
]
|
||||
],
|
||||
typeFilter: 10,
|
||||
}
|
||||
],
|
||||
foundElems: 2,
|
||||
original: "x, trait:fn(aaaaa, b -> a)",
|
||||
returned: [],
|
||||
userQuery: "x, trait:fn(aaaaa, b -> a)",
|
||||
error: null,
|
||||
},
|
||||
{
|
||||
query: 'a,b(c)',
|
||||
elems: [
|
||||
{
|
||||
name: "a",
|
||||
fullPath: ["a"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "a",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
},
|
||||
{
|
||||
name: "b",
|
||||
fullPath: ["b"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "b",
|
||||
generics: [{
|
||||
name: "c",
|
||||
fullPath: ["c"],
|
||||
pathWithoutLast: [],
|
||||
pathLast: "c",
|
||||
generics: [],
|
||||
typeFilter: -1,
|
||||
}],
|
||||
bindings: [
|
||||
[
|
||||
"output",
|
||||
[],
|
||||
]
|
||||
],
|
||||
typeFilter: -1,
|
||||
}
|
||||
],
|
||||
foundElems: 2,
|
||||
original: "a,b(c)",
|
||||
returned: [],
|
||||
userQuery: "a,b(c)",
|
||||
error: null,
|
||||
},
|
||||
];
|
||||
|
@ -37,15 +37,6 @@ const PARSED = [
|
||||
userQuery: "a b",
|
||||
error: null,
|
||||
},
|
||||
{
|
||||
query: 'a,b(c)',
|
||||
elems: [],
|
||||
foundElems: 0,
|
||||
original: "a,b(c)",
|
||||
returned: [],
|
||||
userQuery: "a,b(c)",
|
||||
error: "Expected `,`, `:` or `->`, found `(`",
|
||||
},
|
||||
{
|
||||
query: 'aaa,a',
|
||||
elems: [
|
||||
|
@ -1,6 +1,12 @@
|
||||
// exact-check
|
||||
|
||||
const EXPECTED = [
|
||||
// not a HOF query
|
||||
{
|
||||
'query': 'u32 -> !',
|
||||
'others': [],
|
||||
},
|
||||
|
||||
// ML-style higher-order function notation
|
||||
{
|
||||
'query': 'bool, (u32 -> !) -> ()',
|
||||
@ -53,11 +59,6 @@ const EXPECTED = [
|
||||
{"path": "hof", "name": "fn_once"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'u32 -> !',
|
||||
// not a HOF query
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': '(str, str -> i8) -> ()',
|
||||
'others': [
|
||||
@ -91,4 +92,85 @@ const EXPECTED = [
|
||||
// params and return are not the same
|
||||
'others': [],
|
||||
},
|
||||
|
||||
// Rust-style higher-order function notation
|
||||
{
|
||||
'query': 'bool, fn(u32) -> ! -> ()',
|
||||
'others': [
|
||||
{"path": "hof", "name": "fn_ptr"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'u8, fnonce(u32) -> ! -> ()',
|
||||
'others': [
|
||||
{"path": "hof", "name": "fn_once"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'u8, fn(u32) -> ! -> ()',
|
||||
// fnonce != fn
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': 'i8, fnmut(u32) -> ! -> ()',
|
||||
'others': [
|
||||
{"path": "hof", "name": "fn_mut"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'i8, fn(u32) -> ! -> ()',
|
||||
// fnmut != fn
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': 'char, fn(u32) -> ! -> ()',
|
||||
'others': [
|
||||
{"path": "hof", "name": "fn_"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'char, fnmut(u32) -> ! -> ()',
|
||||
// fn != fnmut
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': 'fn(first<u32>) -> ! -> ()',
|
||||
'others': [
|
||||
{"path": "hof", "name": "fn_ptr"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'fnonce(second<u32>) -> ! -> ()',
|
||||
'others': [
|
||||
{"path": "hof", "name": "fn_once"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'fnmut(third<u32>) -> ! -> ()',
|
||||
'others': [
|
||||
{"path": "hof", "name": "fn_mut"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'fn(u32) -> ! -> ()',
|
||||
'others': [
|
||||
// fn matches primitive:fn and trait:Fn
|
||||
{"path": "hof", "name": "fn_"},
|
||||
{"path": "hof", "name": "fn_ptr"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'trait:fn(u32) -> ! -> ()',
|
||||
'others': [
|
||||
// fn matches primitive:fn and trait:Fn
|
||||
{"path": "hof", "name": "fn_"},
|
||||
],
|
||||
},
|
||||
{
|
||||
'query': 'primitive:fn(u32) -> ! -> ()',
|
||||
'others': [
|
||||
// fn matches primitive:fn and trait:Fn
|
||||
{"path": "hof", "name": "fn_ptr"},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
Loading…
Reference in New Issue
Block a user