1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = void 0;
- var _types = require("../tokenizer/types");
- var N = _interopRequireWildcard(require("../types"));
- var _context = require("../tokenizer/context");
- var _identifier = require("../util/identifier");
- var _scopeflags = require("../util/scopeflags");
- var _error = require("../parser/error");
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- const reservedTypes = new Set(["_", "any", "bool", "boolean", "empty", "extends", "false", "interface", "mixed", "null", "number", "static", "string", "true", "typeof", "void"]);
- const FlowErrors = Object.freeze({
- 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: "Cannot overwrite reserved type %0",
- 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: "Boolean enum members need to be initialized. Use either `%0 = true,` or `%0 = false,` in enum `%1`.",
- EnumDuplicateMemberName: "Enum member names need to be unique, but the name `%0` has already been used before in enum `%1`.",
- EnumInconsistentMemberValues: "Enum `%0` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.",
- EnumInvalidExplicitType: "Enum type `%1` is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.",
- EnumInvalidExplicitTypeUnknownSupplied: "Supplied enum type is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.",
- EnumInvalidMemberInitializerPrimaryType: "Enum `%0` has type `%2`, so the initializer of `%1` needs to be a %2 literal.",
- EnumInvalidMemberInitializerSymbolType: "Symbol enum members cannot be initialized. Use `%1,` in enum `%0`.",
- EnumInvalidMemberInitializerUnknownType: "The enum member initializer for `%1` needs to be a literal (either a boolean, number, or string) in enum `%0`.",
- EnumInvalidMemberName: "Enum member names cannot start with lowercase 'a' through 'z'. Instead of using `%0`, consider using `%1`, in enum `%2`.",
- EnumNumberMemberNotInitialized: "Number enum members need to be initialized, e.g. `%1 = 1` in enum `%0`.",
- EnumStringMemberInconsistentlyInitailized: "String enum members need to consistently either all use initializers, or use no initializers, in enum `%0`.",
- 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",
- OptionalBindingPattern: "A binding pattern parameter cannot be optional in an implementation signature.",
- SpreadVariance: "Spread properties cannot have variance",
- 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: "Unexpected reserved type %0",
- 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: "`declare export %0` is not supported. Use `%1` 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";
- }
- function isMaybeDefaultImport(state) {
- return (state.type === _types.types.name || !!state.type.keyword) && state.value !== "from";
- }
- 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 => {
- var _temp;
- return _temp = class extends superClass {
- constructor(options, input) {
- super(options, input);
- this.flowPragma = void 0;
- this.flowPragma = undefined;
- }
- shouldParseTypes() {
- return this.getPluginOption("flow", "all") || this.flowPragma === "flow";
- }
- shouldParseEnums() {
- return !!this.getPluginOption("flow", "enums");
- }
- finishToken(type, val) {
- if (type !== _types.types.string && type !== _types.types.semi && type !== _types.types.interpreterDirective) {
- if (this.flowPragma === undefined) {
- this.flowPragma = null;
- }
- }
- return 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");
- }
- }
- return super.addComment(comment);
- }
- flowParseTypeInitialiser(tok) {
- const oldInType = this.state.inType;
- this.state.inType = true;
- this.expect(tok || _types.types.colon);
- const type = this.flowParseType();
- this.state.inType = oldInType;
- return type;
- }
- flowParsePredicate() {
- const node = this.startNode();
- const moduloLoc = this.state.startLoc;
- const moduloPos = this.state.start;
- this.expect(_types.types.modulo);
- const checksLoc = this.state.startLoc;
- this.expectContextual("checks");
- if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) {
- this.raise(moduloPos, FlowErrors.UnexpectedSpaceBetweenModuloChecks);
- }
- if (this.eat(_types.types.parenL)) {
- node.value = this.parseExpression();
- this.expect(_types.types.parenR);
- return this.finishNode(node, "DeclaredPredicate");
- } else {
- return this.finishNode(node, "InferredPredicate");
- }
- }
- flowParseTypeAndPredicateInitialiser() {
- const oldInType = this.state.inType;
- this.state.inType = true;
- this.expect(_types.types.colon);
- let type = null;
- let predicate = null;
- if (this.match(_types.types.modulo)) {
- this.state.inType = oldInType;
- predicate = this.flowParsePredicate();
- } else {
- type = this.flowParseType();
- this.state.inType = oldInType;
- if (this.match(_types.types.modulo)) {
- 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.isRelational("<")) {
- typeNode.typeParameters = this.flowParseTypeParameterDeclaration();
- } else {
- typeNode.typeParameters = null;
- }
- this.expect(_types.types.parenL);
- const tmp = this.flowParseFunctionTypeParams();
- typeNode.params = tmp.params;
- typeNode.rest = tmp.rest;
- this.expect(_types.types.parenR);
- [typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
- typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
- id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
- this.resetEndLocation(id);
- this.semicolon();
- return this.finishNode(node, "DeclareFunction");
- }
- flowParseDeclare(node, insideModule) {
- if (this.match(_types.types._class)) {
- return this.flowParseDeclareClass(node);
- } else if (this.match(_types.types._function)) {
- return this.flowParseDeclareFunction(node);
- } else if (this.match(_types.types._var)) {
- return this.flowParseDeclareVariable(node);
- } else if (this.eatContextual("module")) {
- if (this.match(_types.types.dot)) {
- return this.flowParseDeclareModuleExports(node);
- } else {
- if (insideModule) {
- this.raise(this.state.lastTokStart, FlowErrors.NestedDeclareModule);
- }
- return this.flowParseDeclareModule(node);
- }
- } else if (this.isContextual("type")) {
- return this.flowParseDeclareTypeAlias(node);
- } else if (this.isContextual("opaque")) {
- return this.flowParseDeclareOpaqueType(node);
- } else if (this.isContextual("interface")) {
- return this.flowParseDeclareInterface(node);
- } else if (this.match(_types.types._export)) {
- return this.flowParseDeclareExportDeclaration(node, insideModule);
- } else {
- throw this.unexpected();
- }
- }
- flowParseDeclareVariable(node) {
- this.next();
- node.id = this.flowParseTypeAnnotatableIdentifier(true);
- this.scope.declareName(node.id.name, _scopeflags.BIND_VAR, node.id.start);
- this.semicolon();
- return this.finishNode(node, "DeclareVariable");
- }
- flowParseDeclareModule(node) {
- this.scope.enter(_scopeflags.SCOPE_OTHER);
- if (this.match(_types.types.string)) {
- node.id = this.parseExprAtom();
- } else {
- node.id = this.parseIdentifier();
- }
- const bodyNode = node.body = this.startNode();
- const body = bodyNode.body = [];
- this.expect(_types.types.braceL);
- while (!this.match(_types.types.braceR)) {
- let bodyNode = this.startNode();
- if (this.match(_types.types._import)) {
- this.next();
- if (!this.isContextual("type") && !this.match(_types.types._typeof)) {
- this.raise(this.state.lastTokStart, FlowErrors.InvalidNonTypeImportInDeclareModule);
- }
- this.parseImport(bodyNode);
- } else {
- this.expectContextual("declare", FlowErrors.UnsupportedStatementInDeclareModule);
- bodyNode = this.flowParseDeclare(bodyNode, true);
- }
- body.push(bodyNode);
- }
- this.scope.exit();
- this.expect(_types.types.braceR);
- this.finishNode(bodyNode, "BlockStatement");
- let kind = null;
- let hasModuleExport = false;
- body.forEach(bodyElement => {
- if (isEsModuleType(bodyElement)) {
- if (kind === "CommonJS") {
- this.raise(bodyElement.start, FlowErrors.AmbiguousDeclareModuleKind);
- }
- kind = "ES";
- } else if (bodyElement.type === "DeclareModuleExports") {
- if (hasModuleExport) {
- this.raise(bodyElement.start, FlowErrors.DuplicateDeclareModuleExports);
- }
- if (kind === "ES") {
- this.raise(bodyElement.start, FlowErrors.AmbiguousDeclareModuleKind);
- }
- kind = "CommonJS";
- hasModuleExport = true;
- }
- });
- node.kind = kind || "CommonJS";
- return this.finishNode(node, "DeclareModule");
- }
- flowParseDeclareExportDeclaration(node, insideModule) {
- this.expect(_types.types._export);
- if (this.eat(_types.types._default)) {
- if (this.match(_types.types._function) || this.match(_types.types._class)) {
- 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(_types.types._const) || this.isLet() || (this.isContextual("type") || this.isContextual("interface")) && !insideModule) {
- const label = this.state.value;
- const suggestion = exportSuggestions[label];
- throw this.raise(this.state.start, FlowErrors.UnsupportedDeclareExportKind, label, suggestion);
- }
- if (this.match(_types.types._var) || this.match(_types.types._function) || this.match(_types.types._class) || this.isContextual("opaque")) {
- node.declaration = this.flowParseDeclare(this.startNode());
- node.default = false;
- return this.finishNode(node, "DeclareExportDeclaration");
- } else if (this.match(_types.types.star) || this.match(_types.types.braceL) || this.isContextual("interface") || this.isContextual("type") || this.isContextual("opaque")) {
- node = this.parseExport(node);
- if (node.type === "ExportNamedDeclaration") {
- node.type = "ExportDeclaration";
- node.default = false;
- delete node.exportKind;
- }
- node.type = "Declare" + node.type;
- return node;
- }
- }
- throw this.unexpected();
- }
- flowParseDeclareModuleExports(node) {
- this.next();
- this.expectContextual("exports");
- node.typeAnnotation = this.flowParseTypeAnnotation();
- this.semicolon();
- return this.finishNode(node, "DeclareModuleExports");
- }
- flowParseDeclareTypeAlias(node) {
- this.next();
- this.flowParseTypeAlias(node);
- node.type = "DeclareTypeAlias";
- return node;
- }
- flowParseDeclareOpaqueType(node) {
- this.next();
- this.flowParseOpaqueType(node, true);
- node.type = "DeclareOpaqueType";
- return node;
- }
- flowParseDeclareInterface(node) {
- this.next();
- this.flowParseInterfaceish(node);
- return this.finishNode(node, "DeclareInterface");
- }
- flowParseInterfaceish(node, isClass = false) {
- node.id = this.flowParseRestrictedIdentifier(!isClass, true);
- this.scope.declareName(node.id.name, isClass ? _scopeflags.BIND_FUNCTION : _scopeflags.BIND_LEXICAL, node.id.start);
- if (this.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterDeclaration();
- } else {
- node.typeParameters = null;
- }
- node.extends = [];
- node.implements = [];
- node.mixins = [];
- if (this.eat(_types.types._extends)) {
- do {
- node.extends.push(this.flowParseInterfaceExtends());
- } while (!isClass && this.eat(_types.types.comma));
- }
- if (this.isContextual("mixins")) {
- this.next();
- do {
- node.mixins.push(this.flowParseInterfaceExtends());
- } while (this.eat(_types.types.comma));
- }
- if (this.isContextual("implements")) {
- this.next();
- do {
- node.implements.push(this.flowParseInterfaceExtends());
- } while (this.eat(_types.types.comma));
- }
- 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.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterInstantiation();
- } else {
- node.typeParameters = null;
- }
- return this.finishNode(node, "InterfaceExtends");
- }
- flowParseInterface(node) {
- this.flowParseInterfaceish(node);
- return this.finishNode(node, "InterfaceDeclaration");
- }
- checkNotUnderscore(word) {
- if (word === "_") {
- this.raise(this.state.start, FlowErrors.UnexpectedReservedUnderscore);
- }
- }
- checkReservedType(word, startLoc, declaration) {
- if (!reservedTypes.has(word)) return;
- this.raise(startLoc, declaration ? FlowErrors.AssignReservedType : FlowErrors.UnexpectedReservedType, word);
- }
- flowParseRestrictedIdentifier(liberal, declaration) {
- this.checkReservedType(this.state.value, this.state.start, declaration);
- return this.parseIdentifier(liberal);
- }
- flowParseTypeAlias(node) {
- node.id = this.flowParseRestrictedIdentifier(false, true);
- this.scope.declareName(node.id.name, _scopeflags.BIND_LEXICAL, node.id.start);
- if (this.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterDeclaration();
- } else {
- node.typeParameters = null;
- }
- node.right = this.flowParseTypeInitialiser(_types.types.eq);
- this.semicolon();
- return this.finishNode(node, "TypeAlias");
- }
- flowParseOpaqueType(node, declare) {
- this.expectContextual("type");
- node.id = this.flowParseRestrictedIdentifier(true, true);
- this.scope.declareName(node.id.name, _scopeflags.BIND_LEXICAL, node.id.start);
- if (this.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterDeclaration();
- } else {
- node.typeParameters = null;
- }
- node.supertype = null;
- if (this.match(_types.types.colon)) {
- node.supertype = this.flowParseTypeInitialiser(_types.types.colon);
- }
- node.impltype = null;
- if (!declare) {
- node.impltype = this.flowParseTypeInitialiser(_types.types.eq);
- }
- this.semicolon();
- return this.finishNode(node, "OpaqueType");
- }
- flowParseTypeParameter(requireDefault = false) {
- const nodeStart = this.state.start;
- 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(_types.types.eq)) {
- this.eat(_types.types.eq);
- node.default = this.flowParseType();
- } else {
- if (requireDefault) {
- this.raise(nodeStart, FlowErrors.MissingTypeParamDefault);
- }
- }
- return this.finishNode(node, "TypeParameter");
- }
- flowParseTypeParameterDeclaration() {
- const oldInType = this.state.inType;
- const node = this.startNode();
- node.params = [];
- this.state.inType = true;
- if (this.isRelational("<") || this.match(_types.types.jsxTagStart)) {
- 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.isRelational(">")) {
- this.expect(_types.types.comma);
- }
- } while (!this.isRelational(">"));
- this.expectRelational(">");
- 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.expectRelational("<");
- const oldNoAnonFunctionType = this.state.noAnonFunctionType;
- this.state.noAnonFunctionType = false;
- while (!this.isRelational(">")) {
- node.params.push(this.flowParseType());
- if (!this.isRelational(">")) {
- this.expect(_types.types.comma);
- }
- }
- this.state.noAnonFunctionType = oldNoAnonFunctionType;
- this.expectRelational(">");
- 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.expectRelational("<");
- while (!this.isRelational(">")) {
- node.params.push(this.flowParseTypeOrImplicitInstantiation());
- if (!this.isRelational(">")) {
- this.expect(_types.types.comma);
- }
- }
- this.expectRelational(">");
- this.state.inType = oldInType;
- return this.finishNode(node, "TypeParameterInstantiation");
- }
- flowParseInterfaceType() {
- const node = this.startNode();
- this.expectContextual("interface");
- node.extends = [];
- if (this.eat(_types.types._extends)) {
- do {
- node.extends.push(this.flowParseInterfaceExtends());
- } while (this.eat(_types.types.comma));
- }
- node.body = this.flowParseObjectType({
- allowStatic: false,
- allowExact: false,
- allowSpread: false,
- allowProto: false,
- allowInexact: false
- });
- return this.finishNode(node, "InterfaceTypeAnnotation");
- }
- flowParseObjectPropertyKey() {
- return this.match(_types.types.num) || this.match(_types.types.string) ? this.parseExprAtom() : this.parseIdentifier(true);
- }
- flowParseObjectTypeIndexer(node, isStatic, variance) {
- node.static = isStatic;
- if (this.lookahead().type === _types.types.colon) {
- node.id = this.flowParseObjectPropertyKey();
- node.key = this.flowParseTypeInitialiser();
- } else {
- node.id = null;
- node.key = this.flowParseType();
- }
- this.expect(_types.types.bracketR);
- node.value = this.flowParseTypeInitialiser();
- node.variance = variance;
- return this.finishNode(node, "ObjectTypeIndexer");
- }
- flowParseObjectTypeInternalSlot(node, isStatic) {
- node.static = isStatic;
- node.id = this.flowParseObjectPropertyKey();
- this.expect(_types.types.bracketR);
- this.expect(_types.types.bracketR);
- if (this.isRelational("<") || this.match(_types.types.parenL)) {
- node.method = true;
- node.optional = false;
- node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start));
- } else {
- node.method = false;
- if (this.eat(_types.types.question)) {
- node.optional = true;
- }
- node.value = this.flowParseTypeInitialiser();
- }
- return this.finishNode(node, "ObjectTypeInternalSlot");
- }
- flowParseObjectTypeMethodish(node) {
- node.params = [];
- node.rest = null;
- node.typeParameters = null;
- if (this.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterDeclaration();
- }
- this.expect(_types.types.parenL);
- while (!this.match(_types.types.parenR) && !this.match(_types.types.ellipsis)) {
- node.params.push(this.flowParseFunctionTypeParam());
- if (!this.match(_types.types.parenR)) {
- this.expect(_types.types.comma);
- }
- }
- if (this.eat(_types.types.ellipsis)) {
- node.rest = this.flowParseFunctionTypeParam();
- }
- this.expect(_types.types.parenR);
- 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(_types.types.braceBarL)) {
- this.expect(_types.types.braceBarL);
- endDelim = _types.types.braceBarR;
- exact = true;
- } else {
- this.expect(_types.types.braceL);
- endDelim = _types.types.braceR;
- exact = false;
- }
- nodeStart.exact = exact;
- while (!this.match(endDelim)) {
- let isStatic = false;
- let protoStart = null;
- let inexactStart = null;
- const node = this.startNode();
- if (allowProto && this.isContextual("proto")) {
- const lookahead = this.lookahead();
- if (lookahead.type !== _types.types.colon && lookahead.type !== _types.types.question) {
- this.next();
- protoStart = this.state.start;
- allowStatic = false;
- }
- }
- if (allowStatic && this.isContextual("static")) {
- const lookahead = this.lookahead();
- if (lookahead.type !== _types.types.colon && lookahead.type !== _types.types.question) {
- this.next();
- isStatic = true;
- }
- }
- const variance = this.flowParseVariance();
- if (this.eat(_types.types.bracketL)) {
- if (protoStart != null) {
- this.unexpected(protoStart);
- }
- if (this.eat(_types.types.bracketL)) {
- if (variance) {
- this.unexpected(variance.start);
- }
- nodeStart.internalSlots.push(this.flowParseObjectTypeInternalSlot(node, isStatic));
- } else {
- nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance));
- }
- } else if (this.match(_types.types.parenL) || this.isRelational("<")) {
- if (protoStart != null) {
- this.unexpected(protoStart);
- }
- if (variance) {
- this.unexpected(variance.start);
- }
- nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic));
- } else {
- let kind = "init";
- if (this.isContextual("get") || this.isContextual("set")) {
- const lookahead = this.lookahead();
- if (lookahead.type === _types.types.name || lookahead.type === _types.types.string || lookahead.type === _types.types.num) {
- kind = this.state.value;
- this.next();
- }
- }
- const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact ?? !exact);
- if (propOrInexact === null) {
- inexact = true;
- inexactStart = this.state.lastTokStart;
- } else {
- nodeStart.properties.push(propOrInexact);
- }
- }
- this.flowObjectTypeSemicolon();
- if (inexactStart && !this.match(_types.types.braceR) && !this.match(_types.types.braceBarR)) {
- this.raise(inexactStart, FlowErrors.UnexpectedExplicitInexactInObject);
- }
- }
- this.expect(endDelim);
- if (allowSpread) {
- nodeStart.inexact = inexact;
- }
- const out = this.finishNode(nodeStart, "ObjectTypeAnnotation");
- this.state.inType = oldInType;
- return out;
- }
- flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact) {
- if (this.eat(_types.types.ellipsis)) {
- const isInexactToken = this.match(_types.types.comma) || this.match(_types.types.semi) || this.match(_types.types.braceR) || this.match(_types.types.braceBarR);
- if (isInexactToken) {
- if (!allowSpread) {
- this.raise(this.state.lastTokStart, FlowErrors.InexactInsideNonObject);
- } else if (!allowInexact) {
- this.raise(this.state.lastTokStart, FlowErrors.InexactInsideExact);
- }
- if (variance) {
- this.raise(variance.start, FlowErrors.InexactVariance);
- }
- return null;
- }
- if (!allowSpread) {
- this.raise(this.state.lastTokStart, FlowErrors.UnexpectedSpreadType);
- }
- if (protoStart != null) {
- this.unexpected(protoStart);
- }
- if (variance) {
- this.raise(variance.start, FlowErrors.SpreadVariance);
- }
- node.argument = this.flowParseType();
- return this.finishNode(node, "ObjectTypeSpreadProperty");
- } else {
- node.key = this.flowParseObjectPropertyKey();
- node.static = isStatic;
- node.proto = protoStart != null;
- node.kind = kind;
- let optional = false;
- if (this.isRelational("<") || this.match(_types.types.parenL)) {
- node.method = true;
- if (protoStart != null) {
- this.unexpected(protoStart);
- }
- if (variance) {
- this.unexpected(variance.start);
- }
- node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start));
- if (kind === "get" || kind === "set") {
- this.flowCheckGetterSetterParams(node);
- }
- } else {
- if (kind !== "init") this.unexpected();
- node.method = false;
- if (this.eat(_types.types.question)) {
- 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 start = property.start;
- const length = property.value.params.length + (property.value.rest ? 1 : 0);
- if (length !== paramCount) {
- if (property.kind === "get") {
- this.raise(start, _error.Errors.BadGetterArity);
- } else {
- this.raise(start, _error.Errors.BadSetterArity);
- }
- }
- if (property.kind === "set" && property.value.rest) {
- this.raise(start, _error.Errors.BadSetterRestParameter);
- }
- }
- flowObjectTypeSemicolon() {
- if (!this.eat(_types.types.semi) && !this.eat(_types.types.comma) && !this.match(_types.types.braceR) && !this.match(_types.types.braceBarR)) {
- this.unexpected();
- }
- }
- flowParseQualifiedTypeIdentifier(startPos, startLoc, id) {
- startPos = startPos || this.state.start;
- startLoc = startLoc || this.state.startLoc;
- let node = id || this.flowParseRestrictedIdentifier(true);
- while (this.eat(_types.types.dot)) {
- const node2 = this.startNodeAt(startPos, startLoc);
- node2.qualification = node;
- node2.id = this.flowParseRestrictedIdentifier(true);
- node = this.finishNode(node2, "QualifiedTypeIdentifier");
- }
- return node;
- }
- flowParseGenericType(startPos, startLoc, id) {
- const node = this.startNodeAt(startPos, startLoc);
- node.typeParameters = null;
- node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id);
- if (this.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterInstantiation();
- }
- return this.finishNode(node, "GenericTypeAnnotation");
- }
- flowParseTypeofType() {
- const node = this.startNode();
- this.expect(_types.types._typeof);
- node.argument = this.flowParsePrimaryType();
- return this.finishNode(node, "TypeofTypeAnnotation");
- }
- flowParseTupleType() {
- const node = this.startNode();
- node.types = [];
- this.expect(_types.types.bracketL);
- while (this.state.pos < this.length && !this.match(_types.types.bracketR)) {
- node.types.push(this.flowParseType());
- if (this.match(_types.types.bracketR)) break;
- this.expect(_types.types.comma);
- }
- this.expect(_types.types.bracketR);
- return this.finishNode(node, "TupleTypeAnnotation");
- }
- flowParseFunctionTypeParam() {
- let name = null;
- let optional = false;
- let typeAnnotation = null;
- const node = this.startNode();
- const lh = this.lookahead();
- if (lh.type === _types.types.colon || lh.type === _types.types.question) {
- name = this.parseIdentifier();
- if (this.eat(_types.types.question)) {
- optional = true;
- }
- 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.start, type.loc.start);
- node.name = null;
- node.optional = false;
- node.typeAnnotation = type;
- return this.finishNode(node, "FunctionTypeParam");
- }
- flowParseFunctionTypeParams(params = []) {
- let rest = null;
- while (!this.match(_types.types.parenR) && !this.match(_types.types.ellipsis)) {
- params.push(this.flowParseFunctionTypeParam());
- if (!this.match(_types.types.parenR)) {
- this.expect(_types.types.comma);
- }
- }
- if (this.eat(_types.types.ellipsis)) {
- rest = this.flowParseFunctionTypeParam();
- }
- return {
- params,
- rest
- };
- }
- flowIdentToTypeAnnotation(startPos, 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(startPos, startLoc, id);
- }
- }
- flowParsePrimaryType() {
- const startPos = this.state.start;
- 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 _types.types.name:
- if (this.isContextual("interface")) {
- return this.flowParseInterfaceType();
- }
- return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier());
- case _types.types.braceL:
- return this.flowParseObjectType({
- allowStatic: false,
- allowExact: false,
- allowSpread: true,
- allowProto: false,
- allowInexact: true
- });
- case _types.types.braceBarL:
- return this.flowParseObjectType({
- allowStatic: false,
- allowExact: true,
- allowSpread: true,
- allowProto: false,
- allowInexact: false
- });
- case _types.types.bracketL:
- this.state.noAnonFunctionType = false;
- type = this.flowParseTupleType();
- this.state.noAnonFunctionType = oldNoAnonFunctionType;
- return type;
- case _types.types.relational:
- if (this.state.value === "<") {
- node.typeParameters = this.flowParseTypeParameterDeclaration();
- this.expect(_types.types.parenL);
- tmp = this.flowParseFunctionTypeParams();
- node.params = tmp.params;
- node.rest = tmp.rest;
- this.expect(_types.types.parenR);
- this.expect(_types.types.arrow);
- node.returnType = this.flowParseType();
- return this.finishNode(node, "FunctionTypeAnnotation");
- }
- break;
- case _types.types.parenL:
- this.next();
- if (!this.match(_types.types.parenR) && !this.match(_types.types.ellipsis)) {
- if (this.match(_types.types.name)) {
- const token = this.lookahead().type;
- isGroupedType = token !== _types.types.question && token !== _types.types.colon;
- } else {
- isGroupedType = true;
- }
- }
- if (isGroupedType) {
- this.state.noAnonFunctionType = false;
- type = this.flowParseType();
- this.state.noAnonFunctionType = oldNoAnonFunctionType;
- if (this.state.noAnonFunctionType || !(this.match(_types.types.comma) || this.match(_types.types.parenR) && this.lookahead().type === _types.types.arrow)) {
- this.expect(_types.types.parenR);
- return type;
- } else {
- this.eat(_types.types.comma);
- }
- }
- if (type) {
- tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]);
- } else {
- tmp = this.flowParseFunctionTypeParams();
- }
- node.params = tmp.params;
- node.rest = tmp.rest;
- this.expect(_types.types.parenR);
- this.expect(_types.types.arrow);
- node.returnType = this.flowParseType();
- node.typeParameters = null;
- return this.finishNode(node, "FunctionTypeAnnotation");
- case _types.types.string:
- return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation");
- case _types.types._true:
- case _types.types._false:
- node.value = this.match(_types.types._true);
- this.next();
- return this.finishNode(node, "BooleanLiteralTypeAnnotation");
- case _types.types.plusMin:
- if (this.state.value === "-") {
- this.next();
- if (this.match(_types.types.num)) {
- return this.parseLiteral(-this.state.value, "NumberLiteralTypeAnnotation", node.start, node.loc.start);
- }
- if (this.match(_types.types.bigint)) {
- return this.parseLiteral(-this.state.value, "BigIntLiteralTypeAnnotation", node.start, node.loc.start);
- }
- throw this.raise(this.state.start, FlowErrors.UnexpectedSubtractionOperand);
- }
- throw this.unexpected();
- case _types.types.num:
- return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation");
- case _types.types.bigint:
- return this.parseLiteral(this.state.value, "BigIntLiteralTypeAnnotation");
- case _types.types._void:
- this.next();
- return this.finishNode(node, "VoidTypeAnnotation");
- case _types.types._null:
- this.next();
- return this.finishNode(node, "NullLiteralTypeAnnotation");
- case _types.types._this:
- this.next();
- return this.finishNode(node, "ThisTypeAnnotation");
- case _types.types.star:
- this.next();
- return this.finishNode(node, "ExistsTypeAnnotation");
- default:
- if (this.state.type.keyword === "typeof") {
- return this.flowParseTypeofType();
- } else if (this.state.type.keyword) {
- const label = this.state.type.label;
- this.next();
- return super.createIdentifier(node, label);
- }
- }
- throw this.unexpected();
- }
- flowParsePostfixType() {
- const startPos = this.state.start,
- startLoc = this.state.startLoc;
- let type = this.flowParsePrimaryType();
- while (this.match(_types.types.bracketL) && !this.canInsertSemicolon()) {
- const node = this.startNodeAt(startPos, startLoc);
- node.elementType = type;
- this.expect(_types.types.bracketL);
- this.expect(_types.types.bracketR);
- type = this.finishNode(node, "ArrayTypeAnnotation");
- }
- return type;
- }
- flowParsePrefixType() {
- const node = this.startNode();
- if (this.eat(_types.types.question)) {
- node.typeAnnotation = this.flowParsePrefixType();
- return this.finishNode(node, "NullableTypeAnnotation");
- } else {
- return this.flowParsePostfixType();
- }
- }
- flowParseAnonFunctionWithoutParens() {
- const param = this.flowParsePrefixType();
- if (!this.state.noAnonFunctionType && this.eat(_types.types.arrow)) {
- const node = this.startNodeAt(param.start, param.loc.start);
- node.params = [this.reinterpretTypeAsFunctionTypeParam(param)];
- node.rest = null;
- node.returnType = this.flowParseType();
- node.typeParameters = null;
- return this.finishNode(node, "FunctionTypeAnnotation");
- }
- return param;
- }
- flowParseIntersectionType() {
- const node = this.startNode();
- this.eat(_types.types.bitwiseAND);
- const type = this.flowParseAnonFunctionWithoutParens();
- node.types = [type];
- while (this.eat(_types.types.bitwiseAND)) {
- node.types.push(this.flowParseAnonFunctionWithoutParens());
- }
- return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation");
- }
- flowParseUnionType() {
- const node = this.startNode();
- this.eat(_types.types.bitwiseOR);
- const type = this.flowParseIntersectionType();
- node.types = [type];
- while (this.eat(_types.types.bitwiseOR)) {
- 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;
- this.state.exprAllowed = this.state.exprAllowed || this.state.noAnonFunctionType;
- return type;
- }
- flowParseTypeOrImplicitInstantiation() {
- if (this.state.type === _types.types.name && this.state.value === "_") {
- const startPos = this.state.start;
- const startLoc = this.state.startLoc;
- const node = this.parseIdentifier();
- return this.flowParseGenericType(startPos, 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(_types.types.colon)) {
- ident.typeAnnotation = this.flowParseTypeAnnotation();
- this.resetEndLocation(ident);
- }
- return ident;
- }
- typeCastToParameter(node) {
- node.expression.typeAnnotation = node.typeAnnotation;
- this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end);
- return node.expression;
- }
- flowParseVariance() {
- let variance = null;
- if (this.match(_types.types.plusMin)) {
- variance = this.startNode();
- if (this.state.value === "+") {
- variance.kind = "plus";
- } else {
- variance.kind = "minus";
- }
- this.next();
- this.finishNode(variance, "Variance");
- }
- return variance;
- }
- parseFunctionBody(node, allowExpressionBody, isMethod = false) {
- if (allowExpressionBody) {
- return this.forwardNoArrowParamsConversionAt(node, () => super.parseFunctionBody(node, true, isMethod));
- }
- return super.parseFunctionBody(node, false, isMethod);
- }
- parseFunctionBodyAndFinish(node, type, isMethod = false) {
- if (this.match(_types.types.colon)) {
- const typeNode = this.startNode();
- [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
- node.returnType = typeNode.typeAnnotation ? this.finishNode(typeNode, "TypeAnnotation") : null;
- }
- super.parseFunctionBodyAndFinish(node, type, isMethod);
- }
- parseStatement(context, topLevel) {
- if (this.state.strict && this.match(_types.types.name) && this.state.value === "interface") {
- const lookahead = this.lookahead();
- if (lookahead.type === _types.types.name || (0, _identifier.isKeyword)(lookahead.value)) {
- const node = this.startNode();
- this.next();
- return this.flowParseInterface(node);
- }
- } else if (this.shouldParseEnums() && this.isContextual("enum")) {
- const node = this.startNode();
- this.next();
- return this.flowParseEnumDeclaration(node);
- }
- const stmt = super.parseStatement(context, topLevel);
- if (this.flowPragma === undefined && !this.isValidDirective(stmt)) {
- this.flowPragma = null;
- }
- return stmt;
- }
- parseExpressionStatement(node, expr) {
- if (expr.type === "Identifier") {
- if (expr.name === "declare") {
- if (this.match(_types.types._class) || this.match(_types.types.name) || this.match(_types.types._function) || this.match(_types.types._var) || this.match(_types.types._export)) {
- return this.flowParseDeclare(node);
- }
- } else if (this.match(_types.types.name)) {
- 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);
- }
- shouldParseExportDeclaration() {
- return this.isContextual("type") || this.isContextual("interface") || this.isContextual("opaque") || this.shouldParseEnums() && this.isContextual("enum") || super.shouldParseExportDeclaration();
- }
- isExportDefaultSpecifier() {
- if (this.match(_types.types.name) && (this.state.value === "type" || this.state.value === "interface" || this.state.value === "opaque" || this.shouldParseEnums() && this.state.value === "enum")) {
- return false;
- }
- return super.isExportDefaultSpecifier();
- }
- parseExportDefaultExpression() {
- if (this.shouldParseEnums() && this.isContextual("enum")) {
- const node = this.startNode();
- this.next();
- return this.flowParseEnumDeclaration(node);
- }
- return super.parseExportDefaultExpression();
- }
- parseConditional(expr, startPos, startLoc, refNeedsArrowPos) {
- if (!this.match(_types.types.question)) return expr;
- if (refNeedsArrowPos) {
- const result = this.tryParse(() => super.parseConditional(expr, startPos, startLoc));
- if (!result.node) {
- refNeedsArrowPos.start = result.error.pos || this.state.start;
- return expr;
- }
- if (result.error) this.state = result.failState;
- return result.node;
- }
- this.expect(_types.types.question);
- const state = this.state.clone();
- const originalNoArrowAt = this.state.noArrowAt;
- const node = this.startNodeAt(startPos, 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(state.start, FlowErrors.AmbiguousConditionalArrow);
- }
- if (failed && valid.length === 1) {
- this.state = state;
- this.state.noArrowAt = noArrowAt.concat(valid[0].start);
- ({
- consequent,
- failed
- } = this.tryParseConditionalConsequent());
- }
- }
- this.getArrowLikeExpressions(consequent, true);
- this.state.noArrowAt = originalNoArrowAt;
- this.expect(_types.types.colon);
- node.test = expr;
- node.consequent = consequent;
- node.alternate = this.forwardNoArrowParamsConversionAt(node, () => this.parseMaybeAssign(undefined, undefined, undefined));
- return this.finishNode(node, "ConditionalExpression");
- }
- tryParseConditionalConsequent() {
- this.state.noArrowParamsConversionAt.push(this.state.start);
- const consequent = this.parseMaybeAssignAllowIn();
- const failed = !this.match(_types.types.colon);
- 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) {
- this.toAssignableList(node.params, node.extra?.trailingComma);
- 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, startPos, startLoc) {
- node = super.parseParenItem(node, startPos, startLoc);
- if (this.eat(_types.types.question)) {
- node.optional = true;
- this.resetEndLocation(node);
- }
- if (this.match(_types.types.colon)) {
- const typeCastNode = this.startNodeAt(startPos, 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);
- }
- parseExport(node) {
- const decl = super.parseExport(node);
- if (decl.type === "ExportNamedDeclaration" || decl.type === "ExportAllDeclaration") {
- decl.exportKind = decl.exportKind || "value";
- }
- return decl;
- }
- parseExportDeclaration(node) {
- if (this.isContextual("type")) {
- node.exportKind = "type";
- const declarationNode = this.startNode();
- this.next();
- if (this.match(_types.types.braceL)) {
- node.specifiers = this.parseExportSpecifiers();
- this.parseExportFrom(node);
- return null;
- } else {
- return this.flowParseTypeAlias(declarationNode);
- }
- } else if (this.isContextual("opaque")) {
- node.exportKind = "type";
- const declarationNode = this.startNode();
- this.next();
- return this.flowParseOpaqueType(declarationNode, false);
- } else if (this.isContextual("interface")) {
- node.exportKind = "type";
- const declarationNode = this.startNode();
- this.next();
- return this.flowParseInterface(declarationNode);
- } else if (this.shouldParseEnums() && this.isContextual("enum")) {
- node.exportKind = "value";
- const declarationNode = this.startNode();
- this.next();
- return this.flowParseEnumDeclaration(declarationNode);
- } else {
- return super.parseExportDeclaration(node);
- }
- }
- eatExportStar(node) {
- if (super.eatExportStar(...arguments)) return true;
- if (this.isContextual("type") && this.lookahead().type === _types.types.star) {
- node.exportKind = "type";
- this.next();
- this.next();
- return true;
- }
- return false;
- }
- maybeParseExportNamespaceSpecifier(node) {
- const pos = this.state.start;
- const hasNamespace = super.maybeParseExportNamespaceSpecifier(node);
- if (hasNamespace && node.exportKind === "type") {
- this.unexpected(pos);
- }
- return hasNamespace;
- }
- parseClassId(node, isStatement, optionalId) {
- super.parseClassId(node, isStatement, optionalId);
- if (this.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterDeclaration();
- }
- }
- parseClassMember(classBody, member, state) {
- const pos = this.state.start;
- if (this.isContextual("declare")) {
- if (this.parseClassMemberFromModifier(classBody, member)) {
- return;
- }
- member.declare = true;
- }
- super.parseClassMember(classBody, member, state);
- if (member.declare) {
- if (member.type !== "ClassProperty" && member.type !== "ClassPrivateProperty") {
- this.raise(pos, FlowErrors.DeclareClassElement);
- } else if (member.value) {
- this.raise(member.value.start, FlowErrors.DeclareClassFieldInitializer);
- }
- }
- }
- getTokenFromCode(code) {
- const next = this.input.charCodeAt(this.state.pos + 1);
- if (code === 123 && next === 124) {
- return this.finishOp(_types.types.braceBarL, 2);
- } else if (this.state.inType && (code === 62 || code === 60)) {
- return this.finishOp(_types.types.relational, 1);
- } else if (this.state.inType && code === 63) {
- return this.finishOp(_types.types.question, 1);
- } else if ((0, _identifier.isIteratorStart)(code, next)) {
- this.state.isIterator = true;
- return super.readWord();
- } else {
- return super.getTokenFromCode(code);
- }
- }
- isAssignable(node, isBinding) {
- switch (node.type) {
- case "Identifier":
- case "ObjectPattern":
- case "ArrayPattern":
- case "AssignmentPattern":
- return true;
- case "ObjectExpression":
- {
- const last = node.properties.length - 1;
- return node.properties.every((prop, i) => {
- return prop.type !== "ObjectMethod" && (i === last || prop.type === "SpreadElement") && this.isAssignable(prop);
- });
- }
- case "ObjectProperty":
- return this.isAssignable(node.value);
- case "SpreadElement":
- return this.isAssignable(node.argument);
- case "ArrayExpression":
- return node.elements.every(element => this.isAssignable(element));
- case "AssignmentExpression":
- return node.operator === "=";
- case "ParenthesizedExpression":
- case "TypeCastExpression":
- return this.isAssignable(node.expression);
- case "MemberExpression":
- case "OptionalMemberExpression":
- return !isBinding;
- default:
- return false;
- }
- }
- toAssignable(node) {
- if (node.type === "TypeCastExpression") {
- return super.toAssignable(this.typeCastToParameter(node));
- } else {
- return super.toAssignable(node);
- }
- }
- toAssignableList(exprList, trailingCommaPos) {
- for (let i = 0; i < exprList.length; i++) {
- const expr = exprList[i];
- if (expr?.type === "TypeCastExpression") {
- exprList[i] = this.typeCastToParameter(expr);
- }
- }
- return super.toAssignableList(exprList, trailingCommaPos);
- }
- toReferencedList(exprList, isParenthesizedExpr) {
- for (let i = 0; i < exprList.length; i++) {
- const expr = exprList[i];
- if (expr && expr.type === "TypeCastExpression" && !expr.extra?.parenthesized && (exprList.length > 1 || !isParenthesizedExpr)) {
- this.raise(expr.typeAnnotation.start, FlowErrors.TypeCastInPattern);
- }
- }
- 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;
- }
- checkLVal(expr, bindingType = _scopeflags.BIND_NONE, checkClashes, contextDescription) {
- if (expr.type !== "TypeCastExpression") {
- return super.checkLVal(expr, bindingType, checkClashes, contextDescription);
- }
- }
- parseClassProperty(node) {
- if (this.match(_types.types.colon)) {
- node.typeAnnotation = this.flowParseTypeAnnotation();
- }
- return super.parseClassProperty(node);
- }
- parseClassPrivateProperty(node) {
- if (this.match(_types.types.colon)) {
- node.typeAnnotation = this.flowParseTypeAnnotation();
- }
- return super.parseClassPrivateProperty(node);
- }
- isClassMethod() {
- return this.isRelational("<") || super.isClassMethod();
- }
- isClassProperty() {
- return this.match(_types.types.colon) || super.isClassProperty();
- }
- isNonstaticConstructor(method) {
- return !this.match(_types.types.colon) && super.isNonstaticConstructor(method);
- }
- pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
- if (method.variance) {
- this.unexpected(method.variance.start);
- }
- delete method.variance;
- if (this.isRelational("<")) {
- method.typeParameters = this.flowParseTypeParameterDeclaration();
- }
- super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper);
- }
- pushClassPrivateMethod(classBody, method, isGenerator, isAsync) {
- if (method.variance) {
- this.unexpected(method.variance.start);
- }
- delete method.variance;
- if (this.isRelational("<")) {
- method.typeParameters = this.flowParseTypeParameterDeclaration();
- }
- super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync);
- }
- parseClassSuper(node) {
- super.parseClassSuper(node);
- if (node.superClass && this.isRelational("<")) {
- node.superTypeParameters = this.flowParseTypeParameterInstantiation();
- }
- if (this.isContextual("implements")) {
- this.next();
- const implemented = node.implements = [];
- do {
- const node = this.startNode();
- node.id = this.flowParseRestrictedIdentifier(true);
- if (this.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterInstantiation();
- } else {
- node.typeParameters = null;
- }
- implemented.push(this.finishNode(node, "ClassImplements"));
- } while (this.eat(_types.types.comma));
- }
- }
- parsePropertyName(node, isPrivateNameAllowed) {
- const variance = this.flowParseVariance();
- const key = super.parsePropertyName(node, isPrivateNameAllowed);
- node.variance = variance;
- return key;
- }
- parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) {
- if (prop.variance) {
- this.unexpected(prop.variance.start);
- }
- delete prop.variance;
- let typeParameters;
- if (this.isRelational("<") && !isAccessor) {
- typeParameters = this.flowParseTypeParameterDeclaration();
- if (!this.match(_types.types.parenL)) this.unexpected();
- }
- super.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors);
- if (typeParameters) {
- (prop.value || prop).typeParameters = typeParameters;
- }
- }
- parseAssignableListItemTypes(param) {
- if (this.eat(_types.types.question)) {
- if (param.type !== "Identifier") {
- this.raise(param.start, FlowErrors.OptionalBindingPattern);
- }
- param.optional = true;
- }
- if (this.match(_types.types.colon)) {
- param.typeAnnotation = this.flowParseTypeAnnotation();
- }
- this.resetEndLocation(param);
- return param;
- }
- parseMaybeDefault(startPos, startLoc, left) {
- const node = super.parseMaybeDefault(startPos, startLoc, left);
- if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) {
- this.raise(node.typeAnnotation.start, FlowErrors.TypeBeforeInitializer);
- }
- return node;
- }
- shouldParseDefaultImport(node) {
- if (!hasTypeImportKind(node)) {
- return super.shouldParseDefaultImport(node);
- }
- return isMaybeDefaultImport(this.state);
- }
- parseImportSpecifierLocal(node, specifier, type, contextDescription) {
- specifier.local = hasTypeImportKind(node) ? this.flowParseRestrictedIdentifier(true, true) : this.parseIdentifier();
- this.checkLVal(specifier.local, _scopeflags.BIND_LEXICAL, undefined, contextDescription);
- node.specifiers.push(this.finishNode(specifier, type));
- }
- maybeParseDefaultImportSpecifier(node) {
- node.importKind = "value";
- let kind = null;
- if (this.match(_types.types._typeof)) {
- kind = "typeof";
- } else if (this.isContextual("type")) {
- kind = "type";
- }
- if (kind) {
- const lh = this.lookahead();
- if (kind === "type" && lh.type === _types.types.star) {
- this.unexpected(lh.start);
- }
- if (isMaybeDefaultImport(lh) || lh.type === _types.types.braceL || lh.type === _types.types.star) {
- this.next();
- node.importKind = kind;
- }
- }
- return super.maybeParseDefaultImportSpecifier(node);
- }
- parseImportSpecifier(node) {
- const specifier = this.startNode();
- const firstIdentLoc = this.state.start;
- const firstIdent = this.parseModuleExportName();
- 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("as") && !this.isLookaheadContextual("as")) {
- const as_ident = this.parseIdentifier(true);
- if (specifierTypeKind !== null && !this.match(_types.types.name) && !this.state.type.keyword) {
- specifier.imported = as_ident;
- specifier.importKind = specifierTypeKind;
- specifier.local = as_ident.__clone();
- } else {
- specifier.imported = firstIdent;
- specifier.importKind = null;
- specifier.local = this.parseIdentifier();
- }
- } else if (specifierTypeKind !== null && (this.match(_types.types.name) || this.state.type.keyword)) {
- specifier.imported = this.parseIdentifier(true);
- specifier.importKind = specifierTypeKind;
- if (this.eatContextual("as")) {
- specifier.local = this.parseIdentifier();
- } else {
- isBinding = true;
- specifier.local = specifier.imported.__clone();
- }
- } else {
- if (firstIdent.type === "StringLiteral") {
- throw this.raise(specifier.start, _error.Errors.ImportBindingIsString, firstIdent.value);
- }
- isBinding = true;
- specifier.imported = firstIdent;
- specifier.importKind = null;
- specifier.local = specifier.imported.__clone();
- }
- const nodeIsTypeImport = hasTypeImportKind(node);
- const specifierIsTypeImport = hasTypeImportKind(specifier);
- if (nodeIsTypeImport && specifierIsTypeImport) {
- this.raise(firstIdentLoc, FlowErrors.ImportTypeShorthandOnlyInPureImport);
- }
- if (nodeIsTypeImport || specifierIsTypeImport) {
- this.checkReservedType(specifier.local.name, specifier.local.start, true);
- }
- if (isBinding && !nodeIsTypeImport && !specifierIsTypeImport) {
- this.checkReservedWord(specifier.local.name, specifier.start, true, true);
- }
- this.checkLVal(specifier.local, _scopeflags.BIND_LEXICAL, undefined, "import specifier");
- node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
- }
- parseFunctionParams(node, allowModifiers) {
- const kind = node.kind;
- if (kind !== "get" && kind !== "set" && this.isRelational("<")) {
- node.typeParameters = this.flowParseTypeParameterDeclaration();
- }
- super.parseFunctionParams(node, allowModifiers);
- }
- parseVarId(decl, kind) {
- super.parseVarId(decl, kind);
- if (this.match(_types.types.colon)) {
- decl.id.typeAnnotation = this.flowParseTypeAnnotation();
- this.resetEndLocation(decl.id);
- }
- }
- parseAsyncArrowFromCallExpression(node, call) {
- if (this.match(_types.types.colon)) {
- 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(_types.types.colon) || super.shouldParseAsyncArrow();
- }
- parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos) {
- let state = null;
- let jsx;
- if (this.hasPlugin("jsx") && (this.match(_types.types.jsxTagStart) || this.isRelational("<"))) {
- state = this.state.clone();
- jsx = this.tryParse(() => super.parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos), state);
- if (!jsx.error) return jsx.node;
- const {
- context
- } = this.state;
- if (context[context.length - 1] === _context.types.j_oTag) {
- context.length -= 2;
- } else if (context[context.length - 1] === _context.types.j_expr) {
- context.length -= 1;
- }
- }
- if (jsx?.error || this.isRelational("<")) {
- state = state || this.state.clone();
- let typeParameters;
- const arrow = this.tryParse(abort => {
- typeParameters = this.flowParseTypeParameterDeclaration();
- const arrowExpression = this.forwardNoArrowParamsConversionAt(typeParameters, () => {
- const result = super.parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos);
- this.resetStartLocationFromNode(result, typeParameters);
- return result;
- });
- if (arrowExpression.type !== "ArrowFunctionExpression" && arrowExpression.extra?.parenthesized) {
- abort();
- }
- const expr = this.maybeUnwrapTypeCastExpression(arrowExpression);
- 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(typeParameters.start, FlowErrors.UnexpectedTypeParameterBeforeAsyncArrowFunction);
- }
- return arrow.node;
- }
- arrowExpression = arrow.node;
- }
- if (jsx?.node) {
- this.state = jsx.failState;
- return jsx.node;
- }
- if (arrowExpression) {
- this.state = arrow.failState;
- return arrowExpression;
- }
- if (jsx?.thrown) throw jsx.error;
- if (arrow.thrown) throw arrow.error;
- throw this.raise(typeParameters.start, FlowErrors.UnexpectedTokenAfterTypeParameter);
- }
- return super.parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos);
- }
- parseArrow(node) {
- if (this.match(_types.types.colon)) {
- 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(_types.types.arrow)) 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() {
- return this.match(_types.types.colon) || super.shouldParseArrow();
- }
- setArrowFunctionParameters(node, params) {
- if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) {
- node.params = params;
- } else {
- super.setArrowFunctionParameters(node, params);
- }
- }
- checkParams(node, allowDuplicates, isArrowFunction) {
- if (isArrowFunction && this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) {
- return;
- }
- return super.checkParams(...arguments);
- }
- parseParenAndDistinguishExpression(canBeArrow) {
- return super.parseParenAndDistinguishExpression(canBeArrow && this.state.noArrowAt.indexOf(this.state.start) === -1);
- }
- parseSubscripts(base, startPos, startLoc, noCalls) {
- if (base.type === "Identifier" && base.name === "async" && this.state.noArrowAt.indexOf(startPos) !== -1) {
- this.next();
- const node = this.startNodeAt(startPos, startLoc);
- node.callee = base;
- node.arguments = this.parseCallExpressionArguments(_types.types.parenR, false);
- base = this.finishNode(node, "CallExpression");
- } else if (base.type === "Identifier" && base.name === "async" && this.isRelational("<")) {
- const state = this.state.clone();
- const arrow = this.tryParse(abort => this.parseAsyncArrowWithTypeParameters(startPos, startLoc) || abort(), state);
- if (!arrow.error && !arrow.aborted) return arrow.node;
- const result = this.tryParse(() => super.parseSubscripts(base, startPos, 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, startPos, startLoc, noCalls);
- }
- parseSubscript(base, startPos, startLoc, noCalls, subscriptState) {
- if (this.match(_types.types.questionDot) && this.isLookaheadToken_lt()) {
- subscriptState.optionalChainMember = true;
- if (noCalls) {
- subscriptState.stop = true;
- return base;
- }
- this.next();
- const node = this.startNodeAt(startPos, startLoc);
- node.callee = base;
- node.typeArguments = this.flowParseTypeParameterInstantiation();
- this.expect(_types.types.parenL);
- node.arguments = this.parseCallExpressionArguments(_types.types.parenR, false);
- node.optional = true;
- return this.finishCallExpression(node, true);
- } else if (!noCalls && this.shouldParseTypes() && this.isRelational("<")) {
- const node = this.startNodeAt(startPos, startLoc);
- node.callee = base;
- const result = this.tryParse(() => {
- node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew();
- this.expect(_types.types.parenL);
- node.arguments = this.parseCallExpressionArguments(_types.types.parenR, 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, startPos, startLoc, noCalls, subscriptState);
- }
- parseNewArguments(node) {
- let targs = null;
- if (this.shouldParseTypes() && this.isRelational("<")) {
- targs = this.tryParse(() => this.flowParseTypeParameterInstantiationCallOrNew()).node;
- }
- node.typeArguments = targs;
- super.parseNewArguments(node);
- }
- parseAsyncArrowWithTypeParameters(startPos, startLoc) {
- const node = this.startNodeAt(startPos, startLoc);
- this.parseFunctionParams(node);
- if (!this.parseArrow(node)) return;
- return this.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(_types.types.braceBarR, 2);
- return;
- }
- super.readToken_pipe_amp(code);
- }
- parseTopLevel(file, program) {
- const fileNode = super.parseTopLevel(file, program);
- if (this.state.hasFlowComment) {
- this.raise(this.state.pos, FlowErrors.UnterminatedFlowComment);
- }
- return fileNode;
- }
- skipBlockComment() {
- if (this.hasPlugin("flowComments") && this.skipFlowComment()) {
- if (this.state.hasFlowComment) {
- this.unexpected(null, FlowErrors.NestedFlowComment);
- }
- this.hasFlowCommentCompletion();
- this.state.pos += this.skipFlowComment();
- this.state.hasFlowComment = true;
- return;
- }
- if (this.state.hasFlowComment) {
- const end = this.input.indexOf("*-/", this.state.pos += 2);
- if (end === -1) {
- throw this.raise(this.state.pos - 2, _error.Errors.UnterminatedComment);
- }
- this.state.pos = end + 3;
- return;
- }
- super.skipBlockComment();
- }
- 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(this.state.pos, _error.Errors.UnterminatedComment);
- }
- }
- flowEnumErrorBooleanMemberNotInitialized(pos, {
- enumName,
- memberName
- }) {
- this.raise(pos, FlowErrors.EnumBooleanMemberNotInitialized, memberName, enumName);
- }
- flowEnumErrorInvalidMemberName(pos, {
- enumName,
- memberName
- }) {
- const suggestion = memberName[0].toUpperCase() + memberName.slice(1);
- this.raise(pos, FlowErrors.EnumInvalidMemberName, memberName, suggestion, enumName);
- }
- flowEnumErrorDuplicateMemberName(pos, {
- enumName,
- memberName
- }) {
- this.raise(pos, FlowErrors.EnumDuplicateMemberName, memberName, enumName);
- }
- flowEnumErrorInconsistentMemberValues(pos, {
- enumName
- }) {
- this.raise(pos, FlowErrors.EnumInconsistentMemberValues, enumName);
- }
- flowEnumErrorInvalidExplicitType(pos, {
- enumName,
- suppliedType
- }) {
- return this.raise(pos, suppliedType === null ? FlowErrors.EnumInvalidExplicitTypeUnknownSupplied : FlowErrors.EnumInvalidExplicitType, enumName, suppliedType);
- }
- flowEnumErrorInvalidMemberInitializer(pos, {
- enumName,
- explicitType,
- memberName
- }) {
- let message = null;
- switch (explicitType) {
- case "boolean":
- case "number":
- case "string":
- message = FlowErrors.EnumInvalidMemberInitializerPrimaryType;
- break;
- case "symbol":
- message = FlowErrors.EnumInvalidMemberInitializerSymbolType;
- break;
- default:
- message = FlowErrors.EnumInvalidMemberInitializerUnknownType;
- }
- return this.raise(pos, message, enumName, memberName, explicitType);
- }
- flowEnumErrorNumberMemberNotInitialized(pos, {
- enumName,
- memberName
- }) {
- this.raise(pos, FlowErrors.EnumNumberMemberNotInitialized, enumName, memberName);
- }
- flowEnumErrorStringMemberInconsistentlyInitailized(pos, {
- enumName
- }) {
- this.raise(pos, FlowErrors.EnumStringMemberInconsistentlyInitailized, enumName);
- }
- flowEnumMemberInit() {
- const startPos = this.state.start;
- const endOfInit = () => this.match(_types.types.comma) || this.match(_types.types.braceR);
- switch (this.state.type) {
- case _types.types.num:
- {
- const literal = this.parseLiteral(this.state.value, "NumericLiteral");
- if (endOfInit()) {
- return {
- type: "number",
- pos: literal.start,
- value: literal
- };
- }
- return {
- type: "invalid",
- pos: startPos
- };
- }
- case _types.types.string:
- {
- const literal = this.parseLiteral(this.state.value, "StringLiteral");
- if (endOfInit()) {
- return {
- type: "string",
- pos: literal.start,
- value: literal
- };
- }
- return {
- type: "invalid",
- pos: startPos
- };
- }
- case _types.types._true:
- case _types.types._false:
- {
- const literal = this.parseBooleanLiteral();
- if (endOfInit()) {
- return {
- type: "boolean",
- pos: literal.start,
- value: literal
- };
- }
- return {
- type: "invalid",
- pos: startPos
- };
- }
- default:
- return {
- type: "invalid",
- pos: startPos
- };
- }
- }
- flowEnumMemberRaw() {
- const pos = this.state.start;
- const id = this.parseIdentifier(true);
- const init = this.eat(_types.types.eq) ? this.flowEnumMemberInit() : {
- type: "none",
- pos
- };
- return {
- id,
- init
- };
- }
- flowEnumCheckExplicitTypeMismatch(pos, context, expectedType) {
- const {
- explicitType
- } = context;
- if (explicitType === null) {
- return;
- }
- if (explicitType !== expectedType) {
- this.flowEnumErrorInvalidMemberInitializer(pos, context);
- }
- }
- flowEnumMembers({
- enumName,
- explicitType
- }) {
- const seenNames = new Set();
- const members = {
- booleanMembers: [],
- numberMembers: [],
- stringMembers: [],
- defaultedMembers: []
- };
- while (!this.match(_types.types.braceR)) {
- const memberNode = this.startNode();
- const {
- id,
- init
- } = this.flowEnumMemberRaw();
- const memberName = id.name;
- if (memberName === "") {
- continue;
- }
- if (/^[a-z]/.test(memberName)) {
- this.flowEnumErrorInvalidMemberName(id.start, {
- enumName,
- memberName
- });
- }
- if (seenNames.has(memberName)) {
- this.flowEnumErrorDuplicateMemberName(id.start, {
- enumName,
- memberName
- });
- }
- seenNames.add(memberName);
- const context = {
- enumName,
- explicitType,
- memberName
- };
- memberNode.id = id;
- switch (init.type) {
- case "boolean":
- {
- this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "boolean");
- memberNode.init = init.value;
- members.booleanMembers.push(this.finishNode(memberNode, "EnumBooleanMember"));
- break;
- }
- case "number":
- {
- this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "number");
- memberNode.init = init.value;
- members.numberMembers.push(this.finishNode(memberNode, "EnumNumberMember"));
- break;
- }
- case "string":
- {
- this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "string");
- memberNode.init = init.value;
- members.stringMembers.push(this.finishNode(memberNode, "EnumStringMember"));
- break;
- }
- case "invalid":
- {
- throw this.flowEnumErrorInvalidMemberInitializer(init.pos, context);
- }
- case "none":
- {
- switch (explicitType) {
- case "boolean":
- this.flowEnumErrorBooleanMemberNotInitialized(init.pos, context);
- break;
- case "number":
- this.flowEnumErrorNumberMemberNotInitialized(init.pos, context);
- break;
- default:
- members.defaultedMembers.push(this.finishNode(memberNode, "EnumDefaultedMember"));
- }
- }
- }
- if (!this.match(_types.types.braceR)) {
- this.expect(_types.types.comma);
- }
- }
- return members;
- }
- flowEnumStringMembers(initializedMembers, defaultedMembers, {
- enumName
- }) {
- if (initializedMembers.length === 0) {
- return defaultedMembers;
- } else if (defaultedMembers.length === 0) {
- return initializedMembers;
- } else if (defaultedMembers.length > initializedMembers.length) {
- for (let _i = 0; _i < initializedMembers.length; _i++) {
- const member = initializedMembers[_i];
- this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, {
- enumName
- });
- }
- return defaultedMembers;
- } else {
- for (let _i2 = 0; _i2 < defaultedMembers.length; _i2++) {
- const member = defaultedMembers[_i2];
- this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, {
- enumName
- });
- }
- return initializedMembers;
- }
- }
- flowEnumParseExplicitType({
- enumName
- }) {
- if (this.eatContextual("of")) {
- if (!this.match(_types.types.name)) {
- throw this.flowEnumErrorInvalidExplicitType(this.state.start, {
- enumName,
- suppliedType: null
- });
- }
- const {
- value
- } = this.state;
- this.next();
- if (value !== "boolean" && value !== "number" && value !== "string" && value !== "symbol") {
- this.flowEnumErrorInvalidExplicitType(this.state.start, {
- enumName,
- suppliedType: value
- });
- }
- return value;
- }
- return null;
- }
- flowEnumBody(node, {
- enumName,
- nameLoc
- }) {
- const explicitType = this.flowEnumParseExplicitType({
- enumName
- });
- this.expect(_types.types.braceL);
- const members = this.flowEnumMembers({
- enumName,
- explicitType
- });
- switch (explicitType) {
- case "boolean":
- node.explicitType = true;
- node.members = members.booleanMembers;
- this.expect(_types.types.braceR);
- return this.finishNode(node, "EnumBooleanBody");
- case "number":
- node.explicitType = true;
- node.members = members.numberMembers;
- this.expect(_types.types.braceR);
- return this.finishNode(node, "EnumNumberBody");
- case "string":
- node.explicitType = true;
- node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, {
- enumName
- });
- this.expect(_types.types.braceR);
- return this.finishNode(node, "EnumStringBody");
- case "symbol":
- node.members = members.defaultedMembers;
- this.expect(_types.types.braceR);
- return this.finishNode(node, "EnumSymbolBody");
- default:
- {
- const empty = () => {
- node.members = [];
- this.expect(_types.types.braceR);
- 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(_types.types.braceR);
- return this.finishNode(node, "EnumStringBody");
- } else if (!numsLen && !strsLen && boolsLen >= defaultedLen) {
- for (let _i3 = 0, _members$defaultedMem = members.defaultedMembers; _i3 < _members$defaultedMem.length; _i3++) {
- const member = _members$defaultedMem[_i3];
- this.flowEnumErrorBooleanMemberNotInitialized(member.start, {
- enumName,
- memberName: member.id.name
- });
- }
- node.members = members.booleanMembers;
- this.expect(_types.types.braceR);
- return this.finishNode(node, "EnumBooleanBody");
- } else if (!boolsLen && !strsLen && numsLen >= defaultedLen) {
- for (let _i4 = 0, _members$defaultedMem2 = members.defaultedMembers; _i4 < _members$defaultedMem2.length; _i4++) {
- const member = _members$defaultedMem2[_i4];
- this.flowEnumErrorNumberMemberNotInitialized(member.start, {
- enumName,
- memberName: member.id.name
- });
- }
- node.members = members.numberMembers;
- this.expect(_types.types.braceR);
- return this.finishNode(node, "EnumNumberBody");
- } else {
- this.flowEnumErrorInconsistentMemberValues(nameLoc, {
- enumName
- });
- return empty();
- }
- }
- }
- }
- flowParseEnumDeclaration(node) {
- const id = this.parseIdentifier();
- node.id = id;
- node.body = this.flowEnumBody(this.startNode(), {
- enumName: id.name,
- nameLoc: id.start
- });
- return this.finishNode(node, "EnumDeclaration");
- }
- updateContext(prevType) {
- if (this.match(_types.types.name) && this.state.value === "of" && prevType === _types.types.name && this.input.slice(this.state.lastTokStart, this.state.lastTokEnd) === "interface") {
- this.state.exprAllowed = false;
- } else {
- super.updateContext(prevType);
- }
- }
- 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;
- }
- }, _temp;
- };
- exports.default = _default;
|