kjelsrud.dev/node_modules/@babel/parser/lib/plugins/flow/index.js
2023-07-19 21:31:30 +02:00

2474 lines
84 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _types = require("../../tokenizer/types");
var _context = require("../../tokenizer/context");
var _identifier = require("../../util/identifier");
var _scope = require("./scope");
var _scopeflags = require("../../util/scopeflags");
var _parseError = require("../../parse-error");
var _node = require("../../parser/node");
const reservedTypes = new Set(["_", "any", "bool", "boolean", "empty", "extends", "false", "interface", "mixed", "null", "number", "static", "string", "true", "typeof", "void"]);
const FlowErrors = (0, _parseError.ParseErrorEnum)`flow`({
AmbiguousConditionalArrow: "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate.",
AmbiguousDeclareModuleKind: "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module.",
AssignReservedType: ({
reservedType
}) => `Cannot overwrite reserved type ${reservedType}.`,
DeclareClassElement: "The `declare` modifier can only appear on class fields.",
DeclareClassFieldInitializer: "Initializers are not allowed in fields with the `declare` modifier.",
DuplicateDeclareModuleExports: "Duplicate `declare module.exports` statement.",
EnumBooleanMemberNotInitialized: ({
memberName,
enumName
}) => `Boolean enum members need to be initialized. Use either \`${memberName} = true,\` or \`${memberName} = false,\` in enum \`${enumName}\`.`,
EnumDuplicateMemberName: ({
memberName,
enumName
}) => `Enum member names need to be unique, but the name \`${memberName}\` has already been used before in enum \`${enumName}\`.`,
EnumInconsistentMemberValues: ({
enumName
}) => `Enum \`${enumName}\` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.`,
EnumInvalidExplicitType: ({
invalidEnumType,
enumName
}) => `Enum type \`${invalidEnumType}\` is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`,
EnumInvalidExplicitTypeUnknownSupplied: ({
enumName
}) => `Supplied enum type is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`,
EnumInvalidMemberInitializerPrimaryType: ({
enumName,
memberName,
explicitType
}) => `Enum \`${enumName}\` has type \`${explicitType}\`, so the initializer of \`${memberName}\` needs to be a ${explicitType} literal.`,
EnumInvalidMemberInitializerSymbolType: ({
enumName,
memberName
}) => `Symbol enum members cannot be initialized. Use \`${memberName},\` in enum \`${enumName}\`.`,
EnumInvalidMemberInitializerUnknownType: ({
enumName,
memberName
}) => `The enum member initializer for \`${memberName}\` needs to be a literal (either a boolean, number, or string) in enum \`${enumName}\`.`,
EnumInvalidMemberName: ({
enumName,
memberName,
suggestion
}) => `Enum member names cannot start with lowercase 'a' through 'z'. Instead of using \`${memberName}\`, consider using \`${suggestion}\`, in enum \`${enumName}\`.`,
EnumNumberMemberNotInitialized: ({
enumName,
memberName
}) => `Number enum members need to be initialized, e.g. \`${memberName} = 1\` in enum \`${enumName}\`.`,
EnumStringMemberInconsistentlyInitailized: ({
enumName
}) => `String enum members need to consistently either all use initializers, or use no initializers, in enum \`${enumName}\`.`,
GetterMayNotHaveThisParam: "A getter cannot have a `this` parameter.",
ImportReflectionHasImportType: "An `import module` declaration can not use `type` or `typeof` keyword.",
ImportTypeShorthandOnlyInPureImport: "The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements.",
InexactInsideExact: "Explicit inexact syntax cannot appear inside an explicit exact object type.",
InexactInsideNonObject: "Explicit inexact syntax cannot appear in class or interface definitions.",
InexactVariance: "Explicit inexact syntax cannot have variance.",
InvalidNonTypeImportInDeclareModule: "Imports within a `declare module` body must always be `import type` or `import typeof`.",
MissingTypeParamDefault: "Type parameter declaration needs a default, since a preceding type parameter declaration has a default.",
NestedDeclareModule: "`declare module` cannot be used inside another `declare module`.",
NestedFlowComment: "Cannot have a flow comment inside another flow comment.",
PatternIsOptional: Object.assign({
message: "A binding pattern parameter cannot be optional in an implementation signature."
}, {
reasonCode: "OptionalBindingPattern"
}),
SetterMayNotHaveThisParam: "A setter cannot have a `this` parameter.",
SpreadVariance: "Spread properties cannot have variance.",
ThisParamAnnotationRequired: "A type annotation is required for the `this` parameter.",
ThisParamBannedInConstructor: "Constructors cannot have a `this` parameter; constructors don't bind `this` like other functions.",
ThisParamMayNotBeOptional: "The `this` parameter cannot be optional.",
ThisParamMustBeFirst: "The `this` parameter must be the first function parameter.",
ThisParamNoDefault: "The `this` parameter may not have a default value.",
TypeBeforeInitializer: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.",
TypeCastInPattern: "The type cast expression is expected to be wrapped with parenthesis.",
UnexpectedExplicitInexactInObject: "Explicit inexact syntax must appear at the end of an inexact object.",
UnexpectedReservedType: ({
reservedType
}) => `Unexpected reserved type ${reservedType}.`,
UnexpectedReservedUnderscore: "`_` is only allowed as a type argument to call or new.",
UnexpectedSpaceBetweenModuloChecks: "Spaces between `%` and `checks` are not allowed here.",
UnexpectedSpreadType: "Spread operator cannot appear in class or interface definitions.",
UnexpectedSubtractionOperand: 'Unexpected token, expected "number" or "bigint".',
UnexpectedTokenAfterTypeParameter: "Expected an arrow function after this type parameter declaration.",
UnexpectedTypeParameterBeforeAsyncArrowFunction: "Type parameters must come after the async keyword, e.g. instead of `<T> async () => {}`, use `async <T>() => {}`.",
UnsupportedDeclareExportKind: ({
unsupportedExportKind,
suggestion
}) => `\`declare export ${unsupportedExportKind}\` is not supported. Use \`${suggestion}\` instead.`,
UnsupportedStatementInDeclareModule: "Only declares and type imports are allowed inside declare module.",
UnterminatedFlowComment: "Unterminated flow-comment."
});
function isEsModuleType(bodyElement) {
return bodyElement.type === "DeclareExportAllDeclaration" || bodyElement.type === "DeclareExportDeclaration" && (!bodyElement.declaration || bodyElement.declaration.type !== "TypeAlias" && bodyElement.declaration.type !== "InterfaceDeclaration");
}
function hasTypeImportKind(node) {
return node.importKind === "type" || node.importKind === "typeof";
}
const exportSuggestions = {
const: "declare export var",
let: "declare export var",
type: "export type",
interface: "export interface"
};
function partition(list, test) {
const list1 = [];
const list2 = [];
for (let i = 0; i < list.length; i++) {
(test(list[i], i, list) ? list1 : list2).push(list[i]);
}
return [list1, list2];
}
const FLOW_PRAGMA_REGEX = /\*?\s*@((?:no)?flow)\b/;
var _default = superClass => class FlowParserMixin extends superClass {
constructor(...args) {
super(...args);
this.flowPragma = undefined;
}
getScopeHandler() {
return _scope.default;
}
shouldParseTypes() {
return this.getPluginOption("flow", "all") || this.flowPragma === "flow";
}
shouldParseEnums() {
return !!this.getPluginOption("flow", "enums");
}
finishToken(type, val) {
if (type !== 131 && type !== 13 && type !== 28) {
if (this.flowPragma === undefined) {
this.flowPragma = null;
}
}
super.finishToken(type, val);
}
addComment(comment) {
if (this.flowPragma === undefined) {
const matches = FLOW_PRAGMA_REGEX.exec(comment.value);
if (!matches) {} else if (matches[1] === "flow") {
this.flowPragma = "flow";
} else if (matches[1] === "noflow") {
this.flowPragma = "noflow";
} else {
throw new Error("Unexpected flow pragma");
}
}
super.addComment(comment);
}
flowParseTypeInitialiser(tok) {
const oldInType = this.state.inType;
this.state.inType = true;
this.expect(tok || 14);
const type = this.flowParseType();
this.state.inType = oldInType;
return type;
}
flowParsePredicate() {
const node = this.startNode();
const moduloLoc = this.state.startLoc;
this.next();
this.expectContextual(108);
if (this.state.lastTokStart > moduloLoc.index + 1) {
this.raise(FlowErrors.UnexpectedSpaceBetweenModuloChecks, {
at: moduloLoc
});
}
if (this.eat(10)) {
node.value = super.parseExpression();
this.expect(11);
return this.finishNode(node, "DeclaredPredicate");
} else {
return this.finishNode(node, "InferredPredicate");
}
}
flowParseTypeAndPredicateInitialiser() {
const oldInType = this.state.inType;
this.state.inType = true;
this.expect(14);
let type = null;
let predicate = null;
if (this.match(54)) {
this.state.inType = oldInType;
predicate = this.flowParsePredicate();
} else {
type = this.flowParseType();
this.state.inType = oldInType;
if (this.match(54)) {
predicate = this.flowParsePredicate();
}
}
return [type, predicate];
}
flowParseDeclareClass(node) {
this.next();
this.flowParseInterfaceish(node, true);
return this.finishNode(node, "DeclareClass");
}
flowParseDeclareFunction(node) {
this.next();
const id = node.id = this.parseIdentifier();
const typeNode = this.startNode();
const typeContainer = this.startNode();
if (this.match(47)) {
typeNode.typeParameters = this.flowParseTypeParameterDeclaration();
} else {
typeNode.typeParameters = null;
}
this.expect(10);
const tmp = this.flowParseFunctionTypeParams();
typeNode.params = tmp.params;
typeNode.rest = tmp.rest;
typeNode.this = tmp._this;
this.expect(11);
[typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
this.resetEndLocation(id);
this.semicolon();
this.scope.declareName(node.id.name, _scopeflags.BIND_FLOW_DECLARE_FN, node.id.loc.start);
return this.finishNode(node, "DeclareFunction");
}
flowParseDeclare(node, insideModule) {
if (this.match(80)) {
return this.flowParseDeclareClass(node);
} else if (this.match(68)) {
return this.flowParseDeclareFunction(node);
} else if (this.match(74)) {
return this.flowParseDeclareVariable(node);
} else if (this.eatContextual(125)) {
if (this.match(16)) {
return this.flowParseDeclareModuleExports(node);
} else {
if (insideModule) {
this.raise(FlowErrors.NestedDeclareModule, {
at: this.state.lastTokStartLoc
});
}
return this.flowParseDeclareModule(node);
}
} else if (this.isContextual(128)) {
return this.flowParseDeclareTypeAlias(node);
} else if (this.isContextual(129)) {
return this.flowParseDeclareOpaqueType(node);
} else if (this.isContextual(127)) {
return this.flowParseDeclareInterface(node);
} else if (this.match(82)) {
return this.flowParseDeclareExportDeclaration(node, insideModule);
} else {
this.unexpected();
}
}
flowParseDeclareVariable(node) {
this.next();
node.id = this.flowParseTypeAnnotatableIdentifier(true);
this.scope.declareName(node.id.name, _scopeflags.BIND_VAR, node.id.loc.start);
this.semicolon();
return this.finishNode(node, "DeclareVariable");
}
flowParseDeclareModule(node) {
this.scope.enter(_scopeflags.SCOPE_OTHER);
if (this.match(131)) {
node.id = super.parseExprAtom();
} else {
node.id = this.parseIdentifier();
}
const bodyNode = node.body = this.startNode();
const body = bodyNode.body = [];
this.expect(5);
while (!this.match(8)) {
let bodyNode = this.startNode();
if (this.match(83)) {
this.next();
if (!this.isContextual(128) && !this.match(87)) {
this.raise(FlowErrors.InvalidNonTypeImportInDeclareModule, {
at: this.state.lastTokStartLoc
});
}
super.parseImport(bodyNode);
} else {
this.expectContextual(123, FlowErrors.UnsupportedStatementInDeclareModule);
bodyNode = this.flowParseDeclare(bodyNode, true);
}
body.push(bodyNode);
}
this.scope.exit();
this.expect(8);
this.finishNode(bodyNode, "BlockStatement");
let kind = null;
let hasModuleExport = false;
body.forEach(bodyElement => {
if (isEsModuleType(bodyElement)) {
if (kind === "CommonJS") {
this.raise(FlowErrors.AmbiguousDeclareModuleKind, {
at: bodyElement
});
}
kind = "ES";
} else if (bodyElement.type === "DeclareModuleExports") {
if (hasModuleExport) {
this.raise(FlowErrors.DuplicateDeclareModuleExports, {
at: bodyElement
});
}
if (kind === "ES") {
this.raise(FlowErrors.AmbiguousDeclareModuleKind, {
at: bodyElement
});
}
kind = "CommonJS";
hasModuleExport = true;
}
});
node.kind = kind || "CommonJS";
return this.finishNode(node, "DeclareModule");
}
flowParseDeclareExportDeclaration(node, insideModule) {
this.expect(82);
if (this.eat(65)) {
if (this.match(68) || this.match(80)) {
node.declaration = this.flowParseDeclare(this.startNode());
} else {
node.declaration = this.flowParseType();
this.semicolon();
}
node.default = true;
return this.finishNode(node, "DeclareExportDeclaration");
} else {
if (this.match(75) || this.isLet() || (this.isContextual(128) || this.isContextual(127)) && !insideModule) {
const label = this.state.value;
throw this.raise(FlowErrors.UnsupportedDeclareExportKind, {
at: this.state.startLoc,
unsupportedExportKind: label,
suggestion: exportSuggestions[label]
});
}
if (this.match(74) || this.match(68) || this.match(80) || this.isContextual(129)) {
node.declaration = this.flowParseDeclare(this.startNode());
node.default = false;
return this.finishNode(node, "DeclareExportDeclaration");
} else if (this.match(55) || this.match(5) || this.isContextual(127) || this.isContextual(128) || this.isContextual(129)) {
node = this.parseExport(node, null);
if (node.type === "ExportNamedDeclaration") {
node.type = "ExportDeclaration";
node.default = false;
delete node.exportKind;
}
node.type = "Declare" + node.type;
return node;
}
}
this.unexpected();
}
flowParseDeclareModuleExports(node) {
this.next();
this.expectContextual(109);
node.typeAnnotation = this.flowParseTypeAnnotation();
this.semicolon();
return this.finishNode(node, "DeclareModuleExports");
}
flowParseDeclareTypeAlias(node) {
this.next();
const finished = this.flowParseTypeAlias(node);
finished.type = "DeclareTypeAlias";
return finished;
}
flowParseDeclareOpaqueType(node) {
this.next();
const finished = this.flowParseOpaqueType(node, true);
finished.type = "DeclareOpaqueType";
return finished;
}
flowParseDeclareInterface(node) {
this.next();
this.flowParseInterfaceish(node, false);
return this.finishNode(node, "DeclareInterface");
}
flowParseInterfaceish(node, isClass) {
node.id = this.flowParseRestrictedIdentifier(!isClass, true);
this.scope.declareName(node.id.name, isClass ? _scopeflags.BIND_FUNCTION : _scopeflags.BIND_LEXICAL, node.id.loc.start);
if (this.match(47)) {
node.typeParameters = this.flowParseTypeParameterDeclaration();
} else {
node.typeParameters = null;
}
node.extends = [];
if (this.eat(81)) {
do {
node.extends.push(this.flowParseInterfaceExtends());
} while (!isClass && this.eat(12));
}
if (isClass) {
node.implements = [];
node.mixins = [];
if (this.eatContextual(115)) {
do {
node.mixins.push(this.flowParseInterfaceExtends());
} while (this.eat(12));
}
if (this.eatContextual(111)) {
do {
node.implements.push(this.flowParseInterfaceExtends());
} while (this.eat(12));
}
}
node.body = this.flowParseObjectType({
allowStatic: isClass,
allowExact: false,
allowSpread: false,
allowProto: isClass,
allowInexact: false
});
}
flowParseInterfaceExtends() {
const node = this.startNode();
node.id = this.flowParseQualifiedTypeIdentifier();
if (this.match(47)) {
node.typeParameters = this.flowParseTypeParameterInstantiation();
} else {
node.typeParameters = null;
}
return this.finishNode(node, "InterfaceExtends");
}
flowParseInterface(node) {
this.flowParseInterfaceish(node, false);
return this.finishNode(node, "InterfaceDeclaration");
}
checkNotUnderscore(word) {
if (word === "_") {
this.raise(FlowErrors.UnexpectedReservedUnderscore, {
at: this.state.startLoc
});
}
}
checkReservedType(word, startLoc, declaration) {
if (!reservedTypes.has(word)) return;
this.raise(declaration ? FlowErrors.AssignReservedType : FlowErrors.UnexpectedReservedType, {
at: startLoc,
reservedType: word
});
}
flowParseRestrictedIdentifier(liberal, declaration) {
this.checkReservedType(this.state.value, this.state.startLoc, declaration);
return this.parseIdentifier(liberal);
}
flowParseTypeAlias(node) {
node.id = this.flowParseRestrictedIdentifier(false, true);
this.scope.declareName(node.id.name, _scopeflags.BIND_LEXICAL, node.id.loc.start);
if (this.match(47)) {
node.typeParameters = this.flowParseTypeParameterDeclaration();
} else {
node.typeParameters = null;
}
node.right = this.flowParseTypeInitialiser(29);
this.semicolon();
return this.finishNode(node, "TypeAlias");
}
flowParseOpaqueType(node, declare) {
this.expectContextual(128);
node.id = this.flowParseRestrictedIdentifier(true, true);
this.scope.declareName(node.id.name, _scopeflags.BIND_LEXICAL, node.id.loc.start);
if (this.match(47)) {
node.typeParameters = this.flowParseTypeParameterDeclaration();
} else {
node.typeParameters = null;
}
node.supertype = null;
if (this.match(14)) {
node.supertype = this.flowParseTypeInitialiser(14);
}
node.impltype = null;
if (!declare) {
node.impltype = this.flowParseTypeInitialiser(29);
}
this.semicolon();
return this.finishNode(node, "OpaqueType");
}
flowParseTypeParameter(requireDefault = false) {
const nodeStartLoc = this.state.startLoc;
const node = this.startNode();
const variance = this.flowParseVariance();
const ident = this.flowParseTypeAnnotatableIdentifier();
node.name = ident.name;
node.variance = variance;
node.bound = ident.typeAnnotation;
if (this.match(29)) {
this.eat(29);
node.default = this.flowParseType();
} else {
if (requireDefault) {
this.raise(FlowErrors.MissingTypeParamDefault, {
at: nodeStartLoc
});
}
}
return this.finishNode(node, "TypeParameter");
}
flowParseTypeParameterDeclaration() {
const oldInType = this.state.inType;
const node = this.startNode();
node.params = [];
this.state.inType = true;
if (this.match(47) || this.match(140)) {
this.next();
} else {
this.unexpected();
}
let defaultRequired = false;
do {
const typeParameter = this.flowParseTypeParameter(defaultRequired);
node.params.push(typeParameter);
if (typeParameter.default) {
defaultRequired = true;
}
if (!this.match(48)) {
this.expect(12);
}
} while (!this.match(48));
this.expect(48);
this.state.inType = oldInType;
return this.finishNode(node, "TypeParameterDeclaration");
}
flowParseTypeParameterInstantiation() {
const node = this.startNode();
const oldInType = this.state.inType;
node.params = [];
this.state.inType = true;
this.expect(47);
const oldNoAnonFunctionType = this.state.noAnonFunctionType;
this.state.noAnonFunctionType = false;
while (!this.match(48)) {
node.params.push(this.flowParseType());
if (!this.match(48)) {
this.expect(12);
}
}
this.state.noAnonFunctionType = oldNoAnonFunctionType;
this.expect(48);
this.state.inType = oldInType;
return this.finishNode(node, "TypeParameterInstantiation");
}
flowParseTypeParameterInstantiationCallOrNew() {
const node = this.startNode();
const oldInType = this.state.inType;
node.params = [];
this.state.inType = true;
this.expect(47);
while (!this.match(48)) {
node.params.push(this.flowParseTypeOrImplicitInstantiation());
if (!this.match(48)) {
this.expect(12);
}
}
this.expect(48);
this.state.inType = oldInType;
return this.finishNode(node, "TypeParameterInstantiation");
}
flowParseInterfaceType() {
const node = this.startNode();
this.expectContextual(127);
node.extends = [];
if (this.eat(81)) {
do {
node.extends.push(this.flowParseInterfaceExtends());
} while (this.eat(12));
}
node.body = this.flowParseObjectType({
allowStatic: false,
allowExact: false,
allowSpread: false,
allowProto: false,
allowInexact: false
});
return this.finishNode(node, "InterfaceTypeAnnotation");
}
flowParseObjectPropertyKey() {
return this.match(132) || this.match(131) ? super.parseExprAtom() : this.parseIdentifier(true);
}
flowParseObjectTypeIndexer(node, isStatic, variance) {
node.static = isStatic;
if (this.lookahead().type === 14) {
node.id = this.flowParseObjectPropertyKey();
node.key = this.flowParseTypeInitialiser();
} else {
node.id = null;
node.key = this.flowParseType();
}
this.expect(3);
node.value = this.flowParseTypeInitialiser();
node.variance = variance;
return this.finishNode(node, "ObjectTypeIndexer");
}
flowParseObjectTypeInternalSlot(node, isStatic) {
node.static = isStatic;
node.id = this.flowParseObjectPropertyKey();
this.expect(3);
this.expect(3);
if (this.match(47) || this.match(10)) {
node.method = true;
node.optional = false;
node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.loc.start));
} else {
node.method = false;
if (this.eat(17)) {
node.optional = true;
}
node.value = this.flowParseTypeInitialiser();
}
return this.finishNode(node, "ObjectTypeInternalSlot");
}
flowParseObjectTypeMethodish(node) {
node.params = [];
node.rest = null;
node.typeParameters = null;
node.this = null;
if (this.match(47)) {
node.typeParameters = this.flowParseTypeParameterDeclaration();
}
this.expect(10);
if (this.match(78)) {
node.this = this.flowParseFunctionTypeParam(true);
node.this.name = null;
if (!this.match(11)) {
this.expect(12);
}
}
while (!this.match(11) && !this.match(21)) {
node.params.push(this.flowParseFunctionTypeParam(false));
if (!this.match(11)) {
this.expect(12);
}
}
if (this.eat(21)) {
node.rest = this.flowParseFunctionTypeParam(false);
}
this.expect(11);
node.returnType = this.flowParseTypeInitialiser();
return this.finishNode(node, "FunctionTypeAnnotation");
}
flowParseObjectTypeCallProperty(node, isStatic) {
const valueNode = this.startNode();
node.static = isStatic;
node.value = this.flowParseObjectTypeMethodish(valueNode);
return this.finishNode(node, "ObjectTypeCallProperty");
}
flowParseObjectType({
allowStatic,
allowExact,
allowSpread,
allowProto,
allowInexact
}) {
const oldInType = this.state.inType;
this.state.inType = true;
const nodeStart = this.startNode();
nodeStart.callProperties = [];
nodeStart.properties = [];
nodeStart.indexers = [];
nodeStart.internalSlots = [];
let endDelim;
let exact;
let inexact = false;
if (allowExact && this.match(6)) {
this.expect(6);
endDelim = 9;
exact = true;
} else {
this.expect(5);
endDelim = 8;
exact = false;
}
nodeStart.exact = exact;
while (!this.match(endDelim)) {
let isStatic = false;
let protoStartLoc = null;
let inexactStartLoc = null;
const node = this.startNode();
if (allowProto && this.isContextual(116)) {
const lookahead = this.lookahead();
if (lookahead.type !== 14 && lookahead.type !== 17) {
this.next();
protoStartLoc = this.state.startLoc;
allowStatic = false;
}
}
if (allowStatic && this.isContextual(104)) {
const lookahead = this.lookahead();
if (lookahead.type !== 14 && lookahead.type !== 17) {
this.next();
isStatic = true;
}
}
const variance = this.flowParseVariance();
if (this.eat(0)) {
if (protoStartLoc != null) {
this.unexpected(protoStartLoc);
}
if (this.eat(0)) {
if (variance) {
this.unexpected(variance.loc.start);
}
nodeStart.internalSlots.push(this.flowParseObjectTypeInternalSlot(node, isStatic));
} else {
nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance));
}
} else if (this.match(10) || this.match(47)) {
if (protoStartLoc != null) {
this.unexpected(protoStartLoc);
}
if (variance) {
this.unexpected(variance.loc.start);
}
nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic));
} else {
let kind = "init";
if (this.isContextual(98) || this.isContextual(103)) {
const lookahead = this.lookahead();
if ((0, _types.tokenIsLiteralPropertyName)(lookahead.type)) {
kind = this.state.value;
this.next();
}
}
const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStartLoc, variance, kind, allowSpread, allowInexact != null ? allowInexact : !exact);
if (propOrInexact === null) {
inexact = true;
inexactStartLoc = this.state.lastTokStartLoc;
} else {
nodeStart.properties.push(propOrInexact);
}
}
this.flowObjectTypeSemicolon();
if (inexactStartLoc && !this.match(8) && !this.match(9)) {
this.raise(FlowErrors.UnexpectedExplicitInexactInObject, {
at: inexactStartLoc
});
}
}
this.expect(endDelim);
if (allowSpread) {
nodeStart.inexact = inexact;
}
const out = this.finishNode(nodeStart, "ObjectTypeAnnotation");
this.state.inType = oldInType;
return out;
}
flowParseObjectTypeProperty(node, isStatic, protoStartLoc, variance, kind, allowSpread, allowInexact) {
if (this.eat(21)) {
const isInexactToken = this.match(12) || this.match(13) || this.match(8) || this.match(9);
if (isInexactToken) {
if (!allowSpread) {
this.raise(FlowErrors.InexactInsideNonObject, {
at: this.state.lastTokStartLoc
});
} else if (!allowInexact) {
this.raise(FlowErrors.InexactInsideExact, {
at: this.state.lastTokStartLoc
});
}
if (variance) {
this.raise(FlowErrors.InexactVariance, {
at: variance
});
}
return null;
}
if (!allowSpread) {
this.raise(FlowErrors.UnexpectedSpreadType, {
at: this.state.lastTokStartLoc
});
}
if (protoStartLoc != null) {
this.unexpected(protoStartLoc);
}
if (variance) {
this.raise(FlowErrors.SpreadVariance, {
at: variance
});
}
node.argument = this.flowParseType();
return this.finishNode(node, "ObjectTypeSpreadProperty");
} else {
node.key = this.flowParseObjectPropertyKey();
node.static = isStatic;
node.proto = protoStartLoc != null;
node.kind = kind;
let optional = false;
if (this.match(47) || this.match(10)) {
node.method = true;
if (protoStartLoc != null) {
this.unexpected(protoStartLoc);
}
if (variance) {
this.unexpected(variance.loc.start);
}
node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.loc.start));
if (kind === "get" || kind === "set") {
this.flowCheckGetterSetterParams(node);
}
if (!allowSpread && node.key.name === "constructor" && node.value.this) {
this.raise(FlowErrors.ThisParamBannedInConstructor, {
at: node.value.this
});
}
} else {
if (kind !== "init") this.unexpected();
node.method = false;
if (this.eat(17)) {
optional = true;
}
node.value = this.flowParseTypeInitialiser();
node.variance = variance;
}
node.optional = optional;
return this.finishNode(node, "ObjectTypeProperty");
}
}
flowCheckGetterSetterParams(property) {
const paramCount = property.kind === "get" ? 0 : 1;
const length = property.value.params.length + (property.value.rest ? 1 : 0);
if (property.value.this) {
this.raise(property.kind === "get" ? FlowErrors.GetterMayNotHaveThisParam : FlowErrors.SetterMayNotHaveThisParam, {
at: property.value.this
});
}
if (length !== paramCount) {
this.raise(property.kind === "get" ? _parseError.Errors.BadGetterArity : _parseError.Errors.BadSetterArity, {
at: property
});
}
if (property.kind === "set" && property.value.rest) {
this.raise(_parseError.Errors.BadSetterRestParameter, {
at: property
});
}
}
flowObjectTypeSemicolon() {
if (!this.eat(13) && !this.eat(12) && !this.match(8) && !this.match(9)) {
this.unexpected();
}
}
flowParseQualifiedTypeIdentifier(startLoc, id) {
var _startLoc;
(_startLoc = startLoc) != null ? _startLoc : startLoc = this.state.startLoc;
let node = id || this.flowParseRestrictedIdentifier(true);
while (this.eat(16)) {
const node2 = this.startNodeAt(startLoc);
node2.qualification = node;
node2.id = this.flowParseRestrictedIdentifier(true);
node = this.finishNode(node2, "QualifiedTypeIdentifier");
}
return node;
}
flowParseGenericType(startLoc, id) {
const node = this.startNodeAt(startLoc);
node.typeParameters = null;
node.id = this.flowParseQualifiedTypeIdentifier(startLoc, id);
if (this.match(47)) {
node.typeParameters = this.flowParseTypeParameterInstantiation();
}
return this.finishNode(node, "GenericTypeAnnotation");
}
flowParseTypeofType() {
const node = this.startNode();
this.expect(87);
node.argument = this.flowParsePrimaryType();
return this.finishNode(node, "TypeofTypeAnnotation");
}
flowParseTupleType() {
const node = this.startNode();
node.types = [];
this.expect(0);
while (this.state.pos < this.length && !this.match(3)) {
node.types.push(this.flowParseType());
if (this.match(3)) break;
this.expect(12);
}
this.expect(3);
return this.finishNode(node, "TupleTypeAnnotation");
}
flowParseFunctionTypeParam(first) {
let name = null;
let optional = false;
let typeAnnotation = null;
const node = this.startNode();
const lh = this.lookahead();
const isThis = this.state.type === 78;
if (lh.type === 14 || lh.type === 17) {
if (isThis && !first) {
this.raise(FlowErrors.ThisParamMustBeFirst, {
at: node
});
}
name = this.parseIdentifier(isThis);
if (this.eat(17)) {
optional = true;
if (isThis) {
this.raise(FlowErrors.ThisParamMayNotBeOptional, {
at: node
});
}
}
typeAnnotation = this.flowParseTypeInitialiser();
} else {
typeAnnotation = this.flowParseType();
}
node.name = name;
node.optional = optional;
node.typeAnnotation = typeAnnotation;
return this.finishNode(node, "FunctionTypeParam");
}
reinterpretTypeAsFunctionTypeParam(type) {
const node = this.startNodeAt(type.loc.start);
node.name = null;
node.optional = false;
node.typeAnnotation = type;
return this.finishNode(node, "FunctionTypeParam");
}
flowParseFunctionTypeParams(params = []) {
let rest = null;
let _this = null;
if (this.match(78)) {
_this = this.flowParseFunctionTypeParam(true);
_this.name = null;
if (!this.match(11)) {
this.expect(12);
}
}
while (!this.match(11) && !this.match(21)) {
params.push(this.flowParseFunctionTypeParam(false));
if (!this.match(11)) {
this.expect(12);
}
}
if (this.eat(21)) {
rest = this.flowParseFunctionTypeParam(false);
}
return {
params,
rest,
_this
};
}
flowIdentToTypeAnnotation(startLoc, node, id) {
switch (id.name) {
case "any":
return this.finishNode(node, "AnyTypeAnnotation");
case "bool":
case "boolean":
return this.finishNode(node, "BooleanTypeAnnotation");
case "mixed":
return this.finishNode(node, "MixedTypeAnnotation");
case "empty":
return this.finishNode(node, "EmptyTypeAnnotation");
case "number":
return this.finishNode(node, "NumberTypeAnnotation");
case "string":
return this.finishNode(node, "StringTypeAnnotation");
case "symbol":
return this.finishNode(node, "SymbolTypeAnnotation");
default:
this.checkNotUnderscore(id.name);
return this.flowParseGenericType(startLoc, id);
}
}
flowParsePrimaryType() {
const startLoc = this.state.startLoc;
const node = this.startNode();
let tmp;
let type;
let isGroupedType = false;
const oldNoAnonFunctionType = this.state.noAnonFunctionType;
switch (this.state.type) {
case 5:
return this.flowParseObjectType({
allowStatic: false,
allowExact: false,
allowSpread: true,
allowProto: false,
allowInexact: true
});
case 6:
return this.flowParseObjectType({
allowStatic: false,
allowExact: true,
allowSpread: true,
allowProto: false,
allowInexact: false
});
case 0:
this.state.noAnonFunctionType = false;
type = this.flowParseTupleType();
this.state.noAnonFunctionType = oldNoAnonFunctionType;
return type;
case 47:
node.typeParameters = this.flowParseTypeParameterDeclaration();
this.expect(10);
tmp = this.flowParseFunctionTypeParams();
node.params = tmp.params;
node.rest = tmp.rest;
node.this = tmp._this;
this.expect(11);
this.expect(19);
node.returnType = this.flowParseType();
return this.finishNode(node, "FunctionTypeAnnotation");
case 10:
this.next();
if (!this.match(11) && !this.match(21)) {
if ((0, _types.tokenIsIdentifier)(this.state.type) || this.match(78)) {
const token = this.lookahead().type;
isGroupedType = token !== 17 && token !== 14;
} else {
isGroupedType = true;
}
}
if (isGroupedType) {
this.state.noAnonFunctionType = false;
type = this.flowParseType();
this.state.noAnonFunctionType = oldNoAnonFunctionType;
if (this.state.noAnonFunctionType || !(this.match(12) || this.match(11) && this.lookahead().type === 19)) {
this.expect(11);
return type;
} else {
this.eat(12);
}
}
if (type) {
tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]);
} else {
tmp = this.flowParseFunctionTypeParams();
}
node.params = tmp.params;
node.rest = tmp.rest;
node.this = tmp._this;
this.expect(11);
this.expect(19);
node.returnType = this.flowParseType();
node.typeParameters = null;
return this.finishNode(node, "FunctionTypeAnnotation");
case 131:
return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation");
case 85:
case 86:
node.value = this.match(85);
this.next();
return this.finishNode(node, "BooleanLiteralTypeAnnotation");
case 53:
if (this.state.value === "-") {
this.next();
if (this.match(132)) {
return this.parseLiteralAtNode(-this.state.value, "NumberLiteralTypeAnnotation", node);
}
if (this.match(133)) {
return this.parseLiteralAtNode(-this.state.value, "BigIntLiteralTypeAnnotation", node);
}
throw this.raise(FlowErrors.UnexpectedSubtractionOperand, {
at: this.state.startLoc
});
}
this.unexpected();
return;
case 132:
return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation");
case 133:
return this.parseLiteral(this.state.value, "BigIntLiteralTypeAnnotation");
case 88:
this.next();
return this.finishNode(node, "VoidTypeAnnotation");
case 84:
this.next();
return this.finishNode(node, "NullLiteralTypeAnnotation");
case 78:
this.next();
return this.finishNode(node, "ThisTypeAnnotation");
case 55:
this.next();
return this.finishNode(node, "ExistsTypeAnnotation");
case 87:
return this.flowParseTypeofType();
default:
if ((0, _types.tokenIsKeyword)(this.state.type)) {
const label = (0, _types.tokenLabelName)(this.state.type);
this.next();
return super.createIdentifier(node, label);
} else if ((0, _types.tokenIsIdentifier)(this.state.type)) {
if (this.isContextual(127)) {
return this.flowParseInterfaceType();
}
return this.flowIdentToTypeAnnotation(startLoc, node, this.parseIdentifier());
}
}
this.unexpected();
}
flowParsePostfixType() {
const startLoc = this.state.startLoc;
let type = this.flowParsePrimaryType();
let seenOptionalIndexedAccess = false;
while ((this.match(0) || this.match(18)) && !this.canInsertSemicolon()) {
const node = this.startNodeAt(startLoc);
const optional = this.eat(18);
seenOptionalIndexedAccess = seenOptionalIndexedAccess || optional;
this.expect(0);
if (!optional && this.match(3)) {
node.elementType = type;
this.next();
type = this.finishNode(node, "ArrayTypeAnnotation");
} else {
node.objectType = type;
node.indexType = this.flowParseType();
this.expect(3);
if (seenOptionalIndexedAccess) {
node.optional = optional;
type = this.finishNode(node, "OptionalIndexedAccessType");
} else {
type = this.finishNode(node, "IndexedAccessType");
}
}
}
return type;
}
flowParsePrefixType() {
const node = this.startNode();
if (this.eat(17)) {
node.typeAnnotation = this.flowParsePrefixType();
return this.finishNode(node, "NullableTypeAnnotation");
} else {
return this.flowParsePostfixType();
}
}
flowParseAnonFunctionWithoutParens() {
const param = this.flowParsePrefixType();
if (!this.state.noAnonFunctionType && this.eat(19)) {
const node = this.startNodeAt(param.loc.start);
node.params = [this.reinterpretTypeAsFunctionTypeParam(param)];
node.rest = null;
node.this = null;
node.returnType = this.flowParseType();
node.typeParameters = null;
return this.finishNode(node, "FunctionTypeAnnotation");
}
return param;
}
flowParseIntersectionType() {
const node = this.startNode();
this.eat(45);
const type = this.flowParseAnonFunctionWithoutParens();
node.types = [type];
while (this.eat(45)) {
node.types.push(this.flowParseAnonFunctionWithoutParens());
}
return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation");
}
flowParseUnionType() {
const node = this.startNode();
this.eat(43);
const type = this.flowParseIntersectionType();
node.types = [type];
while (this.eat(43)) {
node.types.push(this.flowParseIntersectionType());
}
return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation");
}
flowParseType() {
const oldInType = this.state.inType;
this.state.inType = true;
const type = this.flowParseUnionType();
this.state.inType = oldInType;
return type;
}
flowParseTypeOrImplicitInstantiation() {
if (this.state.type === 130 && this.state.value === "_") {
const startLoc = this.state.startLoc;
const node = this.parseIdentifier();
return this.flowParseGenericType(startLoc, node);
} else {
return this.flowParseType();
}
}
flowParseTypeAnnotation() {
const node = this.startNode();
node.typeAnnotation = this.flowParseTypeInitialiser();
return this.finishNode(node, "TypeAnnotation");
}
flowParseTypeAnnotatableIdentifier(allowPrimitiveOverride) {
const ident = allowPrimitiveOverride ? this.parseIdentifier() : this.flowParseRestrictedIdentifier();
if (this.match(14)) {
ident.typeAnnotation = this.flowParseTypeAnnotation();
this.resetEndLocation(ident);
}
return ident;
}
typeCastToParameter(node) {
node.expression.typeAnnotation = node.typeAnnotation;
this.resetEndLocation(node.expression, node.typeAnnotation.loc.end);
return node.expression;
}
flowParseVariance() {
let variance = null;
if (this.match(53)) {
variance = this.startNode();
if (this.state.value === "+") {
variance.kind = "plus";
} else {
variance.kind = "minus";
}
this.next();
return this.finishNode(variance, "Variance");
}
return variance;
}
parseFunctionBody(node, allowExpressionBody, isMethod = false) {
if (allowExpressionBody) {
this.forwardNoArrowParamsConversionAt(node, () => super.parseFunctionBody(node, true, isMethod));
return;
}
super.parseFunctionBody(node, false, isMethod);
}
parseFunctionBodyAndFinish(node, type, isMethod = false) {
if (this.match(14)) {
const typeNode = this.startNode();
[typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
node.returnType = typeNode.typeAnnotation ? this.finishNode(typeNode, "TypeAnnotation") : null;
}
return super.parseFunctionBodyAndFinish(node, type, isMethod);
}
parseStatementLike(flags) {
if (this.state.strict && this.isContextual(127)) {
const lookahead = this.lookahead();
if ((0, _types.tokenIsKeywordOrIdentifier)(lookahead.type)) {
const node = this.startNode();
this.next();
return this.flowParseInterface(node);
}
} else if (this.shouldParseEnums() && this.isContextual(124)) {
const node = this.startNode();
this.next();
return this.flowParseEnumDeclaration(node);
}
const stmt = super.parseStatementLike(flags);
if (this.flowPragma === undefined && !this.isValidDirective(stmt)) {
this.flowPragma = null;
}
return stmt;
}
parseExpressionStatement(node, expr, decorators) {
if (expr.type === "Identifier") {
if (expr.name === "declare") {
if (this.match(80) || (0, _types.tokenIsIdentifier)(this.state.type) || this.match(68) || this.match(74) || this.match(82)) {
return this.flowParseDeclare(node);
}
} else if ((0, _types.tokenIsIdentifier)(this.state.type)) {
if (expr.name === "interface") {
return this.flowParseInterface(node);
} else if (expr.name === "type") {
return this.flowParseTypeAlias(node);
} else if (expr.name === "opaque") {
return this.flowParseOpaqueType(node, false);
}
}
}
return super.parseExpressionStatement(node, expr, decorators);
}
shouldParseExportDeclaration() {
const {
type
} = this.state;
if ((0, _types.tokenIsFlowInterfaceOrTypeOrOpaque)(type) || this.shouldParseEnums() && type === 124) {
return !this.state.containsEsc;
}
return super.shouldParseExportDeclaration();
}
isExportDefaultSpecifier() {
const {
type
} = this.state;
if ((0, _types.tokenIsFlowInterfaceOrTypeOrOpaque)(type) || this.shouldParseEnums() && type === 124) {
return this.state.containsEsc;
}
return super.isExportDefaultSpecifier();
}
parseExportDefaultExpression() {
if (this.shouldParseEnums() && this.isContextual(124)) {
const node = this.startNode();
this.next();
return this.flowParseEnumDeclaration(node);
}
return super.parseExportDefaultExpression();
}
parseConditional(expr, startLoc, refExpressionErrors) {
if (!this.match(17)) return expr;
if (this.state.maybeInArrowParameters) {
const nextCh = this.lookaheadCharCode();
if (nextCh === 44 || nextCh === 61 || nextCh === 58 || nextCh === 41) {
this.setOptionalParametersError(refExpressionErrors);
return expr;
}
}
this.expect(17);
const state = this.state.clone();
const originalNoArrowAt = this.state.noArrowAt;
const node = this.startNodeAt(startLoc);
let {
consequent,
failed
} = this.tryParseConditionalConsequent();
let [valid, invalid] = this.getArrowLikeExpressions(consequent);
if (failed || invalid.length > 0) {
const noArrowAt = [...originalNoArrowAt];
if (invalid.length > 0) {
this.state = state;
this.state.noArrowAt = noArrowAt;
for (let i = 0; i < invalid.length; i++) {
noArrowAt.push(invalid[i].start);
}
({
consequent,
failed
} = this.tryParseConditionalConsequent());
[valid, invalid] = this.getArrowLikeExpressions(consequent);
}
if (failed && valid.length > 1) {
this.raise(FlowErrors.AmbiguousConditionalArrow, {
at: state.startLoc
});
}
if (failed && valid.length === 1) {
this.state = state;
noArrowAt.push(valid[0].start);
this.state.noArrowAt = noArrowAt;
({
consequent,
failed
} = this.tryParseConditionalConsequent());
}
}
this.getArrowLikeExpressions(consequent, true);
this.state.noArrowAt = originalNoArrowAt;
this.expect(14);
node.test = expr;
node.consequent = consequent;
node.alternate = this.forwardNoArrowParamsConversionAt(node, () => this.parseMaybeAssign(undefined, undefined));
return this.finishNode(node, "ConditionalExpression");
}
tryParseConditionalConsequent() {
this.state.noArrowParamsConversionAt.push(this.state.start);
const consequent = this.parseMaybeAssignAllowIn();
const failed = !this.match(14);
this.state.noArrowParamsConversionAt.pop();
return {
consequent,
failed
};
}
getArrowLikeExpressions(node, disallowInvalid) {
const stack = [node];
const arrows = [];
while (stack.length !== 0) {
const node = stack.pop();
if (node.type === "ArrowFunctionExpression") {
if (node.typeParameters || !node.returnType) {
this.finishArrowValidation(node);
} else {
arrows.push(node);
}
stack.push(node.body);
} else if (node.type === "ConditionalExpression") {
stack.push(node.consequent);
stack.push(node.alternate);
}
}
if (disallowInvalid) {
arrows.forEach(node => this.finishArrowValidation(node));
return [arrows, []];
}
return partition(arrows, node => node.params.every(param => this.isAssignable(param, true)));
}
finishArrowValidation(node) {
var _node$extra;
this.toAssignableList(node.params, (_node$extra = node.extra) == null ? void 0 : _node$extra.trailingCommaLoc, false);
this.scope.enter(_scopeflags.SCOPE_FUNCTION | _scopeflags.SCOPE_ARROW);
super.checkParams(node, false, true);
this.scope.exit();
}
forwardNoArrowParamsConversionAt(node, parse) {
let result;
if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) {
this.state.noArrowParamsConversionAt.push(this.state.start);
result = parse();
this.state.noArrowParamsConversionAt.pop();
} else {
result = parse();
}
return result;
}
parseParenItem(node, startLoc) {
node = super.parseParenItem(node, startLoc);
if (this.eat(17)) {
node.optional = true;
this.resetEndLocation(node);
}
if (this.match(14)) {
const typeCastNode = this.startNodeAt(startLoc);
typeCastNode.expression = node;
typeCastNode.typeAnnotation = this.flowParseTypeAnnotation();
return this.finishNode(typeCastNode, "TypeCastExpression");
}
return node;
}
assertModuleNodeAllowed(node) {
if (node.type === "ImportDeclaration" && (node.importKind === "type" || node.importKind === "typeof") || node.type === "ExportNamedDeclaration" && node.exportKind === "type" || node.type === "ExportAllDeclaration" && node.exportKind === "type") {
return;
}
super.assertModuleNodeAllowed(node);
}
parseExportDeclaration(node) {
if (this.isContextual(128)) {
node.exportKind = "type";
const declarationNode = this.startNode();
this.next();
if (this.match(5)) {
node.specifiers = this.parseExportSpecifiers(true);
super.parseExportFrom(node);
return null;
} else {
return this.flowParseTypeAlias(declarationNode);
}
} else if (this.isContextual(129)) {
node.exportKind = "type";
const declarationNode = this.startNode();
this.next();
return this.flowParseOpaqueType(declarationNode, false);
} else if (this.isContextual(127)) {
node.exportKind = "type";
const declarationNode = this.startNode();
this.next();
return this.flowParseInterface(declarationNode);
} else if (this.shouldParseEnums() && this.isContextual(124)) {
node.exportKind = "value";
const declarationNode = this.startNode();
this.next();
return this.flowParseEnumDeclaration(declarationNode);
} else {
return super.parseExportDeclaration(node);
}
}
eatExportStar(node) {
if (super.eatExportStar(node)) return true;
if (this.isContextual(128) && this.lookahead().type === 55) {
node.exportKind = "type";
this.next();
this.next();
return true;
}
return false;
}
maybeParseExportNamespaceSpecifier(node) {
const {
startLoc
} = this.state;
const hasNamespace = super.maybeParseExportNamespaceSpecifier(node);
if (hasNamespace && node.exportKind === "type") {
this.unexpected(startLoc);
}
return hasNamespace;
}
parseClassId(node, isStatement, optionalId) {
super.parseClassId(node, isStatement, optionalId);
if (this.match(47)) {
node.typeParameters = this.flowParseTypeParameterDeclaration();
}
}
parseClassMember(classBody, member, state) {
const {
startLoc
} = this.state;
if (this.isContextual(123)) {
if (super.parseClassMemberFromModifier(classBody, member)) {
return;
}
member.declare = true;
}
super.parseClassMember(classBody, member, state);
if (member.declare) {
if (member.type !== "ClassProperty" && member.type !== "ClassPrivateProperty" && member.type !== "PropertyDefinition") {
this.raise(FlowErrors.DeclareClassElement, {
at: startLoc
});
} else if (member.value) {
this.raise(FlowErrors.DeclareClassFieldInitializer, {
at: member.value
});
}
}
}
isIterator(word) {
return word === "iterator" || word === "asyncIterator";
}
readIterator() {
const word = super.readWord1();
const fullWord = "@@" + word;
if (!this.isIterator(word) || !this.state.inType) {
this.raise(_parseError.Errors.InvalidIdentifier, {
at: this.state.curPosition(),
identifierName: fullWord
});
}
this.finishToken(130, fullWord);
}
getTokenFromCode(code) {
const next = this.input.charCodeAt(this.state.pos + 1);
if (code === 123 && next === 124) {
this.finishOp(6, 2);
} else if (this.state.inType && (code === 62 || code === 60)) {
this.finishOp(code === 62 ? 48 : 47, 1);
} else if (this.state.inType && code === 63) {
if (next === 46) {
this.finishOp(18, 2);
} else {
this.finishOp(17, 1);
}
} else if ((0, _identifier.isIteratorStart)(code, next, this.input.charCodeAt(this.state.pos + 2))) {
this.state.pos += 2;
this.readIterator();
} else {
super.getTokenFromCode(code);
}
}
isAssignable(node, isBinding) {
if (node.type === "TypeCastExpression") {
return this.isAssignable(node.expression, isBinding);
} else {
return super.isAssignable(node, isBinding);
}
}
toAssignable(node, isLHS = false) {
if (!isLHS && node.type === "AssignmentExpression" && node.left.type === "TypeCastExpression") {
node.left = this.typeCastToParameter(node.left);
}
super.toAssignable(node, isLHS);
}
toAssignableList(exprList, trailingCommaLoc, isLHS) {
for (let i = 0; i < exprList.length; i++) {
const expr = exprList[i];
if ((expr == null ? void 0 : expr.type) === "TypeCastExpression") {
exprList[i] = this.typeCastToParameter(expr);
}
}
super.toAssignableList(exprList, trailingCommaLoc, isLHS);
}
toReferencedList(exprList, isParenthesizedExpr) {
for (let i = 0; i < exprList.length; i++) {
var _expr$extra;
const expr = exprList[i];
if (expr && expr.type === "TypeCastExpression" && !((_expr$extra = expr.extra) != null && _expr$extra.parenthesized) && (exprList.length > 1 || !isParenthesizedExpr)) {
this.raise(FlowErrors.TypeCastInPattern, {
at: expr.typeAnnotation
});
}
}
return exprList;
}
parseArrayLike(close, canBePattern, isTuple, refExpressionErrors) {
const node = super.parseArrayLike(close, canBePattern, isTuple, refExpressionErrors);
if (canBePattern && !this.state.maybeInArrowParameters) {
this.toReferencedList(node.elements);
}
return node;
}
isValidLVal(type, isParenthesized, binding) {
return type === "TypeCastExpression" || super.isValidLVal(type, isParenthesized, binding);
}
parseClassProperty(node) {
if (this.match(14)) {
node.typeAnnotation = this.flowParseTypeAnnotation();
}
return super.parseClassProperty(node);
}
parseClassPrivateProperty(node) {
if (this.match(14)) {
node.typeAnnotation = this.flowParseTypeAnnotation();
}
return super.parseClassPrivateProperty(node);
}
isClassMethod() {
return this.match(47) || super.isClassMethod();
}
isClassProperty() {
return this.match(14) || super.isClassProperty();
}
isNonstaticConstructor(method) {
return !this.match(14) && super.isNonstaticConstructor(method);
}
pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
if (method.variance) {
this.unexpected(method.variance.loc.start);
}
delete method.variance;
if (this.match(47)) {
method.typeParameters = this.flowParseTypeParameterDeclaration();
}
super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper);
if (method.params && isConstructor) {
const params = method.params;
if (params.length > 0 && this.isThisParam(params[0])) {
this.raise(FlowErrors.ThisParamBannedInConstructor, {
at: method
});
}
} else if (method.type === "MethodDefinition" && isConstructor && method.value.params) {
const params = method.value.params;
if (params.length > 0 && this.isThisParam(params[0])) {
this.raise(FlowErrors.ThisParamBannedInConstructor, {
at: method
});
}
}
}
pushClassPrivateMethod(classBody, method, isGenerator, isAsync) {
if (method.variance) {
this.unexpected(method.variance.loc.start);
}
delete method.variance;
if (this.match(47)) {
method.typeParameters = this.flowParseTypeParameterDeclaration();
}
super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync);
}
parseClassSuper(node) {
super.parseClassSuper(node);
if (node.superClass && this.match(47)) {
node.superTypeParameters = this.flowParseTypeParameterInstantiation();
}
if (this.isContextual(111)) {
this.next();
const implemented = node.implements = [];
do {
const node = this.startNode();
node.id = this.flowParseRestrictedIdentifier(true);
if (this.match(47)) {
node.typeParameters = this.flowParseTypeParameterInstantiation();
} else {
node.typeParameters = null;
}
implemented.push(this.finishNode(node, "ClassImplements"));
} while (this.eat(12));
}
}
checkGetterSetterParams(method) {
super.checkGetterSetterParams(method);
const params = this.getObjectOrClassMethodParams(method);
if (params.length > 0) {
const param = params[0];
if (this.isThisParam(param) && method.kind === "get") {
this.raise(FlowErrors.GetterMayNotHaveThisParam, {
at: param
});
} else if (this.isThisParam(param)) {
this.raise(FlowErrors.SetterMayNotHaveThisParam, {
at: param
});
}
}
}
parsePropertyNamePrefixOperator(node) {
node.variance = this.flowParseVariance();
}
parseObjPropValue(prop, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) {
if (prop.variance) {
this.unexpected(prop.variance.loc.start);
}
delete prop.variance;
let typeParameters;
if (this.match(47) && !isAccessor) {
typeParameters = this.flowParseTypeParameterDeclaration();
if (!this.match(10)) this.unexpected();
}
const result = super.parseObjPropValue(prop, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors);
if (typeParameters) {
(result.value || result).typeParameters = typeParameters;
}
return result;
}
parseAssignableListItemTypes(param) {
if (this.eat(17)) {
if (param.type !== "Identifier") {
this.raise(FlowErrors.PatternIsOptional, {
at: param
});
}
if (this.isThisParam(param)) {
this.raise(FlowErrors.ThisParamMayNotBeOptional, {
at: param
});
}
param.optional = true;
}
if (this.match(14)) {
param.typeAnnotation = this.flowParseTypeAnnotation();
} else if (this.isThisParam(param)) {
this.raise(FlowErrors.ThisParamAnnotationRequired, {
at: param
});
}
if (this.match(29) && this.isThisParam(param)) {
this.raise(FlowErrors.ThisParamNoDefault, {
at: param
});
}
this.resetEndLocation(param);
return param;
}
parseMaybeDefault(startLoc, left) {
const node = super.parseMaybeDefault(startLoc, left);
if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) {
this.raise(FlowErrors.TypeBeforeInitializer, {
at: node.typeAnnotation
});
}
return node;
}
checkImportReflection(node) {
super.checkImportReflection(node);
if (node.module && node.importKind !== "value") {
this.raise(FlowErrors.ImportReflectionHasImportType, {
at: node.specifiers[0].loc.start
});
}
}
parseImportSpecifierLocal(node, specifier, type) {
specifier.local = hasTypeImportKind(node) ? this.flowParseRestrictedIdentifier(true, true) : this.parseIdentifier();
node.specifiers.push(this.finishImportSpecifier(specifier, type));
}
isPotentialImportPhase(isExport) {
if (super.isPotentialImportPhase(isExport)) return true;
if (this.isContextual(128)) {
if (!isExport) return true;
const ch = this.lookaheadCharCode();
return ch === 123 || ch === 42;
}
return !isExport && this.isContextual(87);
}
applyImportPhase(node, isExport, phase, loc) {
super.applyImportPhase(node, isExport, phase, loc);
if (isExport) {
if (!phase && this.match(65)) {
return;
}
node.exportKind = phase === "type" ? phase : "value";
} else {
if (phase === "type" && this.match(55)) this.unexpected();
node.importKind = phase === "type" || phase === "typeof" ? phase : "value";
}
}
parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly, bindingType) {
const firstIdent = specifier.imported;
let specifierTypeKind = null;
if (firstIdent.type === "Identifier") {
if (firstIdent.name === "type") {
specifierTypeKind = "type";
} else if (firstIdent.name === "typeof") {
specifierTypeKind = "typeof";
}
}
let isBinding = false;
if (this.isContextual(93) && !this.isLookaheadContextual("as")) {
const as_ident = this.parseIdentifier(true);
if (specifierTypeKind !== null && !(0, _types.tokenIsKeywordOrIdentifier)(this.state.type)) {
specifier.imported = as_ident;
specifier.importKind = specifierTypeKind;
specifier.local = (0, _node.cloneIdentifier)(as_ident);
} else {
specifier.imported = firstIdent;
specifier.importKind = null;
specifier.local = this.parseIdentifier();
}
} else {
if (specifierTypeKind !== null && (0, _types.tokenIsKeywordOrIdentifier)(this.state.type)) {
specifier.imported = this.parseIdentifier(true);
specifier.importKind = specifierTypeKind;
} else {
if (importedIsString) {
throw this.raise(_parseError.Errors.ImportBindingIsString, {
at: specifier,
importName: firstIdent.value
});
}
specifier.imported = firstIdent;
specifier.importKind = null;
}
if (this.eatContextual(93)) {
specifier.local = this.parseIdentifier();
} else {
isBinding = true;
specifier.local = (0, _node.cloneIdentifier)(specifier.imported);
}
}
const specifierIsTypeImport = hasTypeImportKind(specifier);
if (isInTypeOnlyImport && specifierIsTypeImport) {
this.raise(FlowErrors.ImportTypeShorthandOnlyInPureImport, {
at: specifier
});
}
if (isInTypeOnlyImport || specifierIsTypeImport) {
this.checkReservedType(specifier.local.name, specifier.local.loc.start, true);
}
if (isBinding && !isInTypeOnlyImport && !specifierIsTypeImport) {
this.checkReservedWord(specifier.local.name, specifier.loc.start, true, true);
}
return this.finishImportSpecifier(specifier, "ImportSpecifier");
}
parseBindingAtom() {
switch (this.state.type) {
case 78:
return this.parseIdentifier(true);
default:
return super.parseBindingAtom();
}
}
parseFunctionParams(node, isConstructor) {
const kind = node.kind;
if (kind !== "get" && kind !== "set" && this.match(47)) {
node.typeParameters = this.flowParseTypeParameterDeclaration();
}
super.parseFunctionParams(node, isConstructor);
}
parseVarId(decl, kind) {
super.parseVarId(decl, kind);
if (this.match(14)) {
decl.id.typeAnnotation = this.flowParseTypeAnnotation();
this.resetEndLocation(decl.id);
}
}
parseAsyncArrowFromCallExpression(node, call) {
if (this.match(14)) {
const oldNoAnonFunctionType = this.state.noAnonFunctionType;
this.state.noAnonFunctionType = true;
node.returnType = this.flowParseTypeAnnotation();
this.state.noAnonFunctionType = oldNoAnonFunctionType;
}
return super.parseAsyncArrowFromCallExpression(node, call);
}
shouldParseAsyncArrow() {
return this.match(14) || super.shouldParseAsyncArrow();
}
parseMaybeAssign(refExpressionErrors, afterLeftParse) {
var _jsx;
let state = null;
let jsx;
if (this.hasPlugin("jsx") && (this.match(140) || this.match(47))) {
state = this.state.clone();
jsx = this.tryParse(() => super.parseMaybeAssign(refExpressionErrors, afterLeftParse), state);
if (!jsx.error) return jsx.node;
const {
context
} = this.state;
const currentContext = context[context.length - 1];
if (currentContext === _context.types.j_oTag || currentContext === _context.types.j_expr) {
context.pop();
}
}
if ((_jsx = jsx) != null && _jsx.error || this.match(47)) {
var _jsx2, _jsx3;
state = state || this.state.clone();
let typeParameters;
const arrow = this.tryParse(abort => {
var _arrowExpression$extr;
typeParameters = this.flowParseTypeParameterDeclaration();
const arrowExpression = this.forwardNoArrowParamsConversionAt(typeParameters, () => {
const result = super.parseMaybeAssign(refExpressionErrors, afterLeftParse);
this.resetStartLocationFromNode(result, typeParameters);
return result;
});
if ((_arrowExpression$extr = arrowExpression.extra) != null && _arrowExpression$extr.parenthesized) abort();
const expr = this.maybeUnwrapTypeCastExpression(arrowExpression);
if (expr.type !== "ArrowFunctionExpression") abort();
expr.typeParameters = typeParameters;
this.resetStartLocationFromNode(expr, typeParameters);
return arrowExpression;
}, state);
let arrowExpression = null;
if (arrow.node && this.maybeUnwrapTypeCastExpression(arrow.node).type === "ArrowFunctionExpression") {
if (!arrow.error && !arrow.aborted) {
if (arrow.node.async) {
this.raise(FlowErrors.UnexpectedTypeParameterBeforeAsyncArrowFunction, {
at: typeParameters
});
}
return arrow.node;
}
arrowExpression = arrow.node;
}
if ((_jsx2 = jsx) != null && _jsx2.node) {
this.state = jsx.failState;
return jsx.node;
}
if (arrowExpression) {
this.state = arrow.failState;
return arrowExpression;
}
if ((_jsx3 = jsx) != null && _jsx3.thrown) throw jsx.error;
if (arrow.thrown) throw arrow.error;
throw this.raise(FlowErrors.UnexpectedTokenAfterTypeParameter, {
at: typeParameters
});
}
return super.parseMaybeAssign(refExpressionErrors, afterLeftParse);
}
parseArrow(node) {
if (this.match(14)) {
const result = this.tryParse(() => {
const oldNoAnonFunctionType = this.state.noAnonFunctionType;
this.state.noAnonFunctionType = true;
const typeNode = this.startNode();
[typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
this.state.noAnonFunctionType = oldNoAnonFunctionType;
if (this.canInsertSemicolon()) this.unexpected();
if (!this.match(19)) this.unexpected();
return typeNode;
});
if (result.thrown) return null;
if (result.error) this.state = result.failState;
node.returnType = result.node.typeAnnotation ? this.finishNode(result.node, "TypeAnnotation") : null;
}
return super.parseArrow(node);
}
shouldParseArrow(params) {
return this.match(14) || super.shouldParseArrow(params);
}
setArrowFunctionParameters(node, params) {
if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) {
node.params = params;
} else {
super.setArrowFunctionParameters(node, params);
}
}
checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged = true) {
if (isArrowFunction && this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) {
return;
}
for (let i = 0; i < node.params.length; i++) {
if (this.isThisParam(node.params[i]) && i > 0) {
this.raise(FlowErrors.ThisParamMustBeFirst, {
at: node.params[i]
});
}
}
super.checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged);
}
parseParenAndDistinguishExpression(canBeArrow) {
return super.parseParenAndDistinguishExpression(canBeArrow && this.state.noArrowAt.indexOf(this.state.start) === -1);
}
parseSubscripts(base, startLoc, noCalls) {
if (base.type === "Identifier" && base.name === "async" && this.state.noArrowAt.indexOf(startLoc.index) !== -1) {
this.next();
const node = this.startNodeAt(startLoc);
node.callee = base;
node.arguments = super.parseCallExpressionArguments(11, false);
base = this.finishNode(node, "CallExpression");
} else if (base.type === "Identifier" && base.name === "async" && this.match(47)) {
const state = this.state.clone();
const arrow = this.tryParse(abort => this.parseAsyncArrowWithTypeParameters(startLoc) || abort(), state);
if (!arrow.error && !arrow.aborted) return arrow.node;
const result = this.tryParse(() => super.parseSubscripts(base, startLoc, noCalls), state);
if (result.node && !result.error) return result.node;
if (arrow.node) {
this.state = arrow.failState;
return arrow.node;
}
if (result.node) {
this.state = result.failState;
return result.node;
}
throw arrow.error || result.error;
}
return super.parseSubscripts(base, startLoc, noCalls);
}
parseSubscript(base, startLoc, noCalls, subscriptState) {
if (this.match(18) && this.isLookaheadToken_lt()) {
subscriptState.optionalChainMember = true;
if (noCalls) {
subscriptState.stop = true;
return base;
}
this.next();
const node = this.startNodeAt(startLoc);
node.callee = base;
node.typeArguments = this.flowParseTypeParameterInstantiation();
this.expect(10);
node.arguments = this.parseCallExpressionArguments(11, false);
node.optional = true;
return this.finishCallExpression(node, true);
} else if (!noCalls && this.shouldParseTypes() && this.match(47)) {
const node = this.startNodeAt(startLoc);
node.callee = base;
const result = this.tryParse(() => {
node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew();
this.expect(10);
node.arguments = super.parseCallExpressionArguments(11, false);
if (subscriptState.optionalChainMember) {
node.optional = false;
}
return this.finishCallExpression(node, subscriptState.optionalChainMember);
});
if (result.node) {
if (result.error) this.state = result.failState;
return result.node;
}
}
return super.parseSubscript(base, startLoc, noCalls, subscriptState);
}
parseNewCallee(node) {
super.parseNewCallee(node);
let targs = null;
if (this.shouldParseTypes() && this.match(47)) {
targs = this.tryParse(() => this.flowParseTypeParameterInstantiationCallOrNew()).node;
}
node.typeArguments = targs;
}
parseAsyncArrowWithTypeParameters(startLoc) {
const node = this.startNodeAt(startLoc);
this.parseFunctionParams(node, false);
if (!this.parseArrow(node)) return;
return super.parseArrowExpression(node, undefined, true);
}
readToken_mult_modulo(code) {
const next = this.input.charCodeAt(this.state.pos + 1);
if (code === 42 && next === 47 && this.state.hasFlowComment) {
this.state.hasFlowComment = false;
this.state.pos += 2;
this.nextToken();
return;
}
super.readToken_mult_modulo(code);
}
readToken_pipe_amp(code) {
const next = this.input.charCodeAt(this.state.pos + 1);
if (code === 124 && next === 125) {
this.finishOp(9, 2);
return;
}
super.readToken_pipe_amp(code);
}
parseTopLevel(file, program) {
const fileNode = super.parseTopLevel(file, program);
if (this.state.hasFlowComment) {
this.raise(FlowErrors.UnterminatedFlowComment, {
at: this.state.curPosition()
});
}
return fileNode;
}
skipBlockComment() {
if (this.hasPlugin("flowComments") && this.skipFlowComment()) {
if (this.state.hasFlowComment) {
throw this.raise(FlowErrors.NestedFlowComment, {
at: this.state.startLoc
});
}
this.hasFlowCommentCompletion();
const commentSkip = this.skipFlowComment();
if (commentSkip) {
this.state.pos += commentSkip;
this.state.hasFlowComment = true;
}
return;
}
return super.skipBlockComment(this.state.hasFlowComment ? "*-/" : "*/");
}
skipFlowComment() {
const {
pos
} = this.state;
let shiftToFirstNonWhiteSpace = 2;
while ([32, 9].includes(this.input.charCodeAt(pos + shiftToFirstNonWhiteSpace))) {
shiftToFirstNonWhiteSpace++;
}
const ch2 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos);
const ch3 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos + 1);
if (ch2 === 58 && ch3 === 58) {
return shiftToFirstNonWhiteSpace + 2;
}
if (this.input.slice(shiftToFirstNonWhiteSpace + pos, shiftToFirstNonWhiteSpace + pos + 12) === "flow-include") {
return shiftToFirstNonWhiteSpace + 12;
}
if (ch2 === 58 && ch3 !== 58) {
return shiftToFirstNonWhiteSpace;
}
return false;
}
hasFlowCommentCompletion() {
const end = this.input.indexOf("*/", this.state.pos);
if (end === -1) {
throw this.raise(_parseError.Errors.UnterminatedComment, {
at: this.state.curPosition()
});
}
}
flowEnumErrorBooleanMemberNotInitialized(loc, {
enumName,
memberName
}) {
this.raise(FlowErrors.EnumBooleanMemberNotInitialized, {
at: loc,
memberName,
enumName
});
}
flowEnumErrorInvalidMemberInitializer(loc, enumContext) {
return this.raise(!enumContext.explicitType ? FlowErrors.EnumInvalidMemberInitializerUnknownType : enumContext.explicitType === "symbol" ? FlowErrors.EnumInvalidMemberInitializerSymbolType : FlowErrors.EnumInvalidMemberInitializerPrimaryType, Object.assign({
at: loc
}, enumContext));
}
flowEnumErrorNumberMemberNotInitialized(loc, {
enumName,
memberName
}) {
this.raise(FlowErrors.EnumNumberMemberNotInitialized, {
at: loc,
enumName,
memberName
});
}
flowEnumErrorStringMemberInconsistentlyInitailized(node, {
enumName
}) {
this.raise(FlowErrors.EnumStringMemberInconsistentlyInitailized, {
at: node,
enumName
});
}
flowEnumMemberInit() {
const startLoc = this.state.startLoc;
const endOfInit = () => this.match(12) || this.match(8);
switch (this.state.type) {
case 132:
{
const literal = this.parseNumericLiteral(this.state.value);
if (endOfInit()) {
return {
type: "number",
loc: literal.loc.start,
value: literal
};
}
return {
type: "invalid",
loc: startLoc
};
}
case 131:
{
const literal = this.parseStringLiteral(this.state.value);
if (endOfInit()) {
return {
type: "string",
loc: literal.loc.start,
value: literal
};
}
return {
type: "invalid",
loc: startLoc
};
}
case 85:
case 86:
{
const literal = this.parseBooleanLiteral(this.match(85));
if (endOfInit()) {
return {
type: "boolean",
loc: literal.loc.start,
value: literal
};
}
return {
type: "invalid",
loc: startLoc
};
}
default:
return {
type: "invalid",
loc: startLoc
};
}
}
flowEnumMemberRaw() {
const loc = this.state.startLoc;
const id = this.parseIdentifier(true);
const init = this.eat(29) ? this.flowEnumMemberInit() : {
type: "none",
loc
};
return {
id,
init
};
}
flowEnumCheckExplicitTypeMismatch(loc, context, expectedType) {
const {
explicitType
} = context;
if (explicitType === null) {
return;
}
if (explicitType !== expectedType) {
this.flowEnumErrorInvalidMemberInitializer(loc, context);
}
}
flowEnumMembers({
enumName,
explicitType
}) {
const seenNames = new Set();
const members = {
booleanMembers: [],
numberMembers: [],
stringMembers: [],
defaultedMembers: []
};
let hasUnknownMembers = false;
while (!this.match(8)) {
if (this.eat(21)) {
hasUnknownMembers = true;
break;
}
const memberNode = this.startNode();
const {
id,
init
} = this.flowEnumMemberRaw();
const memberName = id.name;
if (memberName === "") {
continue;
}
if (/^[a-z]/.test(memberName)) {
this.raise(FlowErrors.EnumInvalidMemberName, {
at: id,
memberName,
suggestion: memberName[0].toUpperCase() + memberName.slice(1),
enumName
});
}
if (seenNames.has(memberName)) {
this.raise(FlowErrors.EnumDuplicateMemberName, {
at: id,
memberName,
enumName
});
}
seenNames.add(memberName);
const context = {
enumName,
explicitType,
memberName
};
memberNode.id = id;
switch (init.type) {
case "boolean":
{
this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "boolean");
memberNode.init = init.value;
members.booleanMembers.push(this.finishNode(memberNode, "EnumBooleanMember"));
break;
}
case "number":
{
this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "number");
memberNode.init = init.value;
members.numberMembers.push(this.finishNode(memberNode, "EnumNumberMember"));
break;
}
case "string":
{
this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "string");
memberNode.init = init.value;
members.stringMembers.push(this.finishNode(memberNode, "EnumStringMember"));
break;
}
case "invalid":
{
throw this.flowEnumErrorInvalidMemberInitializer(init.loc, context);
}
case "none":
{
switch (explicitType) {
case "boolean":
this.flowEnumErrorBooleanMemberNotInitialized(init.loc, context);
break;
case "number":
this.flowEnumErrorNumberMemberNotInitialized(init.loc, context);
break;
default:
members.defaultedMembers.push(this.finishNode(memberNode, "EnumDefaultedMember"));
}
}
}
if (!this.match(8)) {
this.expect(12);
}
}
return {
members,
hasUnknownMembers
};
}
flowEnumStringMembers(initializedMembers, defaultedMembers, {
enumName
}) {
if (initializedMembers.length === 0) {
return defaultedMembers;
} else if (defaultedMembers.length === 0) {
return initializedMembers;
} else if (defaultedMembers.length > initializedMembers.length) {
for (const member of initializedMembers) {
this.flowEnumErrorStringMemberInconsistentlyInitailized(member, {
enumName
});
}
return defaultedMembers;
} else {
for (const member of defaultedMembers) {
this.flowEnumErrorStringMemberInconsistentlyInitailized(member, {
enumName
});
}
return initializedMembers;
}
}
flowEnumParseExplicitType({
enumName
}) {
if (!this.eatContextual(101)) return null;
if (!(0, _types.tokenIsIdentifier)(this.state.type)) {
throw this.raise(FlowErrors.EnumInvalidExplicitTypeUnknownSupplied, {
at: this.state.startLoc,
enumName
});
}
const {
value
} = this.state;
this.next();
if (value !== "boolean" && value !== "number" && value !== "string" && value !== "symbol") {
this.raise(FlowErrors.EnumInvalidExplicitType, {
at: this.state.startLoc,
enumName,
invalidEnumType: value
});
}
return value;
}
flowEnumBody(node, id) {
const enumName = id.name;
const nameLoc = id.loc.start;
const explicitType = this.flowEnumParseExplicitType({
enumName
});
this.expect(5);
const {
members,
hasUnknownMembers
} = this.flowEnumMembers({
enumName,
explicitType
});
node.hasUnknownMembers = hasUnknownMembers;
switch (explicitType) {
case "boolean":
node.explicitType = true;
node.members = members.booleanMembers;
this.expect(8);
return this.finishNode(node, "EnumBooleanBody");
case "number":
node.explicitType = true;
node.members = members.numberMembers;
this.expect(8);
return this.finishNode(node, "EnumNumberBody");
case "string":
node.explicitType = true;
node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, {
enumName
});
this.expect(8);
return this.finishNode(node, "EnumStringBody");
case "symbol":
node.members = members.defaultedMembers;
this.expect(8);
return this.finishNode(node, "EnumSymbolBody");
default:
{
const empty = () => {
node.members = [];
this.expect(8);
return this.finishNode(node, "EnumStringBody");
};
node.explicitType = false;
const boolsLen = members.booleanMembers.length;
const numsLen = members.numberMembers.length;
const strsLen = members.stringMembers.length;
const defaultedLen = members.defaultedMembers.length;
if (!boolsLen && !numsLen && !strsLen && !defaultedLen) {
return empty();
} else if (!boolsLen && !numsLen) {
node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, {
enumName
});
this.expect(8);
return this.finishNode(node, "EnumStringBody");
} else if (!numsLen && !strsLen && boolsLen >= defaultedLen) {
for (const member of members.defaultedMembers) {
this.flowEnumErrorBooleanMemberNotInitialized(member.loc.start, {
enumName,
memberName: member.id.name
});
}
node.members = members.booleanMembers;
this.expect(8);
return this.finishNode(node, "EnumBooleanBody");
} else if (!boolsLen && !strsLen && numsLen >= defaultedLen) {
for (const member of members.defaultedMembers) {
this.flowEnumErrorNumberMemberNotInitialized(member.loc.start, {
enumName,
memberName: member.id.name
});
}
node.members = members.numberMembers;
this.expect(8);
return this.finishNode(node, "EnumNumberBody");
} else {
this.raise(FlowErrors.EnumInconsistentMemberValues, {
at: nameLoc,
enumName
});
return empty();
}
}
}
}
flowParseEnumDeclaration(node) {
const id = this.parseIdentifier();
node.id = id;
node.body = this.flowEnumBody(this.startNode(), id);
return this.finishNode(node, "EnumDeclaration");
}
isLookaheadToken_lt() {
const next = this.nextTokenStart();
if (this.input.charCodeAt(next) === 60) {
const afterNext = this.input.charCodeAt(next + 1);
return afterNext !== 60 && afterNext !== 61;
}
return false;
}
maybeUnwrapTypeCastExpression(node) {
return node.type === "TypeCastExpression" ? node.expression : node;
}
};
exports.default = _default;
//# sourceMappingURL=index.js.map