mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-07 20:39:31 +08:00
This change makes it easier to run the script from directly `roll_py.deps` without having to fetch the dependencies first. This also makes it easier to track which dependencies our tooling have. Change-Id: I1ce55074ee6a1fffa6f2a2f05a56d0d74b4aca90 Bug: 1255619 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3431346 Reviewed-by: Mathias Bynens <mathias@chromium.org> Commit-Queue: Johan Bay <jobay@chromium.org>
117 lines
3.3 KiB
JavaScript
117 lines
3.3 KiB
JavaScript
import { Base } from "./base.js";
|
|
import {
|
|
type_with_extended_attributes,
|
|
autoParenter,
|
|
argument_list,
|
|
} from "./helpers.js";
|
|
|
|
export class IterableLike extends Base {
|
|
/**
|
|
* @param {import("../tokeniser.js").Tokeniser} tokeniser
|
|
*/
|
|
static parse(tokeniser) {
|
|
const start_position = tokeniser.position;
|
|
const tokens = {};
|
|
const ret = autoParenter(
|
|
new IterableLike({ source: tokeniser.source, tokens })
|
|
);
|
|
tokens.readonly = tokeniser.consume("readonly");
|
|
if (!tokens.readonly) {
|
|
tokens.async = tokeniser.consume("async");
|
|
}
|
|
tokens.base = tokens.readonly
|
|
? tokeniser.consume("maplike", "setlike")
|
|
: tokens.async
|
|
? tokeniser.consume("iterable")
|
|
: tokeniser.consume("iterable", "maplike", "setlike");
|
|
if (!tokens.base) {
|
|
tokeniser.unconsume(start_position);
|
|
return;
|
|
}
|
|
|
|
const { type } = ret;
|
|
const secondTypeRequired = type === "maplike";
|
|
const secondTypeAllowed = secondTypeRequired || type === "iterable";
|
|
const argumentAllowed = ret.async && type === "iterable";
|
|
|
|
tokens.open =
|
|
tokeniser.consume("<") ||
|
|
tokeniser.error(`Missing less-than sign \`<\` in ${type} declaration`);
|
|
const first =
|
|
type_with_extended_attributes(tokeniser) ||
|
|
tokeniser.error(`Missing a type argument in ${type} declaration`);
|
|
ret.idlType = [first];
|
|
ret.arguments = [];
|
|
|
|
if (secondTypeAllowed) {
|
|
first.tokens.separator = tokeniser.consume(",");
|
|
if (first.tokens.separator) {
|
|
ret.idlType.push(type_with_extended_attributes(tokeniser));
|
|
} else if (secondTypeRequired) {
|
|
tokeniser.error(`Missing second type argument in ${type} declaration`);
|
|
}
|
|
}
|
|
|
|
tokens.close =
|
|
tokeniser.consume(">") ||
|
|
tokeniser.error(`Missing greater-than sign \`>\` in ${type} declaration`);
|
|
|
|
if (tokeniser.probe("(")) {
|
|
if (argumentAllowed) {
|
|
tokens.argsOpen = tokeniser.consume("(");
|
|
ret.arguments.push(...argument_list(tokeniser));
|
|
tokens.argsClose =
|
|
tokeniser.consume(")") ||
|
|
tokeniser.error("Unterminated async iterable argument list");
|
|
} else {
|
|
tokeniser.error(`Arguments are only allowed for \`async iterable\``);
|
|
}
|
|
}
|
|
|
|
tokens.termination =
|
|
tokeniser.consume(";") ||
|
|
tokeniser.error(`Missing semicolon after ${type} declaration`);
|
|
|
|
return ret.this;
|
|
}
|
|
|
|
get type() {
|
|
return this.tokens.base.value;
|
|
}
|
|
get readonly() {
|
|
return !!this.tokens.readonly;
|
|
}
|
|
get async() {
|
|
return !!this.tokens.async;
|
|
}
|
|
|
|
*validate(defs) {
|
|
for (const type of this.idlType) {
|
|
yield* type.validate(defs);
|
|
}
|
|
for (const argument of this.arguments) {
|
|
yield* argument.validate(defs);
|
|
}
|
|
}
|
|
|
|
/** @param {import("../writer.js").Writer} w */
|
|
write(w) {
|
|
return w.ts.definition(
|
|
w.ts.wrap([
|
|
this.extAttrs.write(w),
|
|
w.token(this.tokens.readonly),
|
|
w.token(this.tokens.async),
|
|
w.token(this.tokens.base, w.ts.generic),
|
|
w.token(this.tokens.open),
|
|
w.ts.wrap(this.idlType.map((t) => t.write(w))),
|
|
w.token(this.tokens.close),
|
|
w.token(this.tokens.argsOpen),
|
|
w.ts.wrap(this.arguments.map((arg) => arg.write(w))),
|
|
w.token(this.tokens.argsClose),
|
|
w.token(this.tokens.termination),
|
|
]),
|
|
{ data: this, parent: this.parent }
|
|
);
|
|
}
|
|
}
|