From 1b9a1ededd84d37fcda1bcb126b5760ee62644d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 20 Jul 2022 15:29:50 -0400 Subject: [PATCH 1/9] flowts convert yarn dlx flowts --no-allow-js --interactive-rename -i "./src/**/*.js" "./packages/babel-parser/" && yarn eslint packages/babel-parser '**/*.ts' --fix --- .../babel-parser/src/{index.js => index.ts} | 14 +- .../src/{options.js => options.ts} | 36 +- .../src/{parse-error.js => parse-error.ts} | 76 +- .../{credentials.js => credentials.ts} | 20 +- .../{module-errors.js => module-errors.ts} | 2 - ...-errors.js => pipeline-operator-errors.ts} | 10 +- ...{standard-errors.js => standard-errors.ts} | 154 ++- ...t-mode-errors.js => strict-mode-errors.ts} | 14 +- ...-description.js => to-node-description.ts} | 15 +- .../src/parser/{base.js => base.ts} | 15 +- .../src/parser/{comments.js => comments.ts} | 14 +- .../parser/{expression.js => expression.ts} | 133 +- .../src/parser/{index.js => index.ts} | 15 +- .../src/parser/{lval.js => lval.ts} | 45 +- .../src/parser/{node.js => node.ts} | 18 +- .../src/parser/{statement.js => statement.ts} | 59 +- .../src/parser/{util.js => util.ts} | 35 +- .../src/{plugin-utils.js => plugin-utils.ts} | 14 +- .../src/plugins/{estree.js => estree.ts} | 91 +- .../src/plugins/flow/{index.js => index.ts} | 344 +++-- .../src/plugins/flow/{scope.js => scope.ts} | 2 - .../src/plugins/jsx/{index.js => index.ts} | 21 +- .../src/plugins/jsx/{xhtml.js => xhtml.ts} | 7 +- .../{placeholders.js => placeholders.ts} | 43 +- .../plugins/typescript/{index.js => index.ts} | 323 +++-- .../plugins/typescript/{scope.js => scope.ts} | 2 - .../{v8intrinsic.js => v8intrinsic.ts} | 6 +- .../src/tokenizer/{context.js => context.ts} | 4 +- .../src/tokenizer/{index.js => index.ts} | 10 +- .../src/tokenizer/{state.js => state.ts} | 25 +- .../src/tokenizer/{types.js => types.ts} | 34 +- .../babel-parser/src/{types.js => types.ts} | 1229 ++++++++--------- .../util/{class-scope.js => class-scope.ts} | 2 - ...xpression-scope.js => expression-scope.ts} | 29 +- .../src/util/{identifier.js => identifier.ts} | 2 - .../src/util/{location.js => location.ts} | 6 +- ...n-parameter.js => production-parameter.ts} | 13 +- .../src/util/{scope.js => scope.ts} | 3 +- .../src/util/{scopeflags.js => scopeflags.ts} | 14 +- .../src/util/{whitespace.js => whitespace.ts} | 2 - tsconfig.json | 4 + 41 files changed, 1569 insertions(+), 1336 deletions(-) rename packages/babel-parser/src/{index.js => index.ts} (91%) rename packages/babel-parser/src/{options.js => options.ts} (83%) rename packages/babel-parser/src/{parse-error.js => parse-error.ts} (82%) rename packages/babel-parser/src/parse-error/{credentials.js => credentials.ts} (81%) rename packages/babel-parser/src/parse-error/{module-errors.js => module-errors.ts} (97%) rename packages/babel-parser/src/parse-error/{pipeline-operator-errors.js => pipeline-operator-errors.ts} (95%) rename packages/babel-parser/src/parse-error/{standard-errors.js => standard-errors.ts} (83%) rename packages/babel-parser/src/parse-error/{strict-mode-errors.js => strict-mode-errors.ts} (81%) rename packages/babel-parser/src/parse-error/{to-node-description.js => to-node-description.ts} (83%) rename packages/babel-parser/src/parser/{base.js => base.ts} (91%) rename packages/babel-parser/src/parser/{comments.js => comments.ts} (98%) rename packages/babel-parser/src/parser/{expression.js => expression.ts} (96%) rename packages/babel-parser/src/parser/{index.js => index.ts} (86%) rename packages/babel-parser/src/parser/{lval.js => lval.ts} (95%) rename packages/babel-parser/src/parser/{node.js => node.ts} (91%) rename packages/babel-parser/src/parser/{statement.js => statement.ts} (98%) rename packages/babel-parser/src/parser/{util.js => util.ts} (93%) rename packages/babel-parser/src/{plugin-utils.js => plugin-utils.ts} (96%) rename packages/babel-parser/src/plugins/{estree.js => estree.ts} (85%) rename packages/babel-parser/src/plugins/flow/{index.js => index.ts} (94%) rename packages/babel-parser/src/plugins/flow/{scope.js => scope.ts} (99%) rename packages/babel-parser/src/plugins/jsx/{index.js => index.ts} (98%) rename packages/babel-parser/src/plugins/jsx/{xhtml.js => xhtml.ts} (98%) rename packages/babel-parser/src/plugins/{placeholders.js => placeholders.ts} (92%) rename packages/babel-parser/src/plugins/typescript/{index.js => index.ts} (94%) rename packages/babel-parser/src/plugins/typescript/{scope.js => scope.ts} (99%) rename packages/babel-parser/src/plugins/{v8intrinsic.js => v8intrinsic.ts} (91%) rename packages/babel-parser/src/tokenizer/{context.js => context.ts} (94%) rename packages/babel-parser/src/tokenizer/{index.js => index.ts} (99%) rename packages/babel-parser/src/tokenizer/{state.js => state.ts} (95%) rename packages/babel-parser/src/tokenizer/{types.js => types.ts} (97%) rename packages/babel-parser/src/{types.js => types.ts} (54%) rename packages/babel-parser/src/util/{class-scope.js => class-scope.ts} (99%) rename packages/babel-parser/src/util/{expression-scope.js => expression-scope.ts} (95%) rename packages/babel-parser/src/util/{identifier.js => identifier.ts} (99%) rename packages/babel-parser/src/util/{location.js => location.ts} (95%) rename packages/babel-parser/src/util/{production-parameter.js => production-parameter.ts} (87%) rename packages/babel-parser/src/util/{scope.js => scope.ts} (98%) rename packages/babel-parser/src/util/{scopeflags.js => scopeflags.ts} (88%) rename packages/babel-parser/src/util/{whitespace.js => whitespace.ts} (99%) diff --git a/packages/babel-parser/src/index.js b/packages/babel-parser/src/index.ts similarity index 91% rename from packages/babel-parser/src/index.js rename to packages/babel-parser/src/index.ts index aa93080a2d32..2121db1bbc37 100644 --- a/packages/babel-parser/src/index.js +++ b/packages/babel-parser/src/index.ts @@ -1,5 +1,3 @@ -// @flow - import { type Options } from "./options"; import { hasPlugin, @@ -77,7 +75,7 @@ function generateExportedTokenTypes(internalTokenTypes) { export const tokTypes = generateExportedTokenTypes(internalTokenTypes); -function getParser(options: ?Options, input: string): Parser { +function getParser(options: Options | undefined | null, input: string): Parser { let cls = Parser; if (options?.plugins) { validatePlugins(options.plugins); @@ -87,10 +85,16 @@ function getParser(options: ?Options, input: string): Parser { return new cls(options, input); } -const parserClassCache: { [key: string]: Class } = {}; +const parserClassCache: { + [key: string]: { + new (...args: any): Parser; + }; +} = {}; /** Get a Parser class with plugins applied. */ -function getParserClass(pluginsFromOptions: PluginList): Class { +function getParserClass(pluginsFromOptions: PluginList): { + new (...args: any): Parser; +} { const pluginList = mixinPluginNames.filter(name => hasPlugin(pluginsFromOptions, name), ); diff --git a/packages/babel-parser/src/options.js b/packages/babel-parser/src/options.ts similarity index 83% rename from packages/babel-parser/src/options.js rename to packages/babel-parser/src/options.ts index e181d3da38f9..b31c14174338 100644 --- a/packages/babel-parser/src/options.js +++ b/packages/babel-parser/src/options.ts @@ -1,5 +1,3 @@ -// @flow - import type { PluginList } from "./plugin-utils"; // A second optional argument can be given to further configure @@ -8,22 +6,22 @@ import type { PluginList } from "./plugin-utils"; export type SourceType = "script" | "module" | "unambiguous"; export type Options = { - sourceType: SourceType, - sourceFilename?: string, - startColumn: number, - startLine: number, - allowAwaitOutsideFunction: boolean, - allowReturnOutsideFunction: boolean, - allowImportExportEverywhere: boolean, - allowSuperOutsideMethod: boolean, - allowUndeclaredExports: boolean, - plugins: PluginList, - strictMode: ?boolean, - ranges: boolean, - tokens: boolean, - createParenthesizedExpressions: boolean, - errorRecovery: boolean, - attachComment: boolean, + sourceType: SourceType; + sourceFilename?: string; + startColumn: number; + startLine: number; + allowAwaitOutsideFunction: boolean; + allowReturnOutsideFunction: boolean; + allowImportExportEverywhere: boolean; + allowSuperOutsideMethod: boolean; + allowUndeclaredExports: boolean; + plugins: PluginList; + strictMode: boolean | undefined | null; + ranges: boolean; + tokens: boolean; + createParenthesizedExpressions: boolean; + errorRecovery: boolean; + attachComment: boolean; }; export const defaultOptions: Options = { @@ -80,7 +78,7 @@ export const defaultOptions: Options = { // Interpret and default an options object -export function getOptions(opts: ?Options): Options { +export function getOptions(opts?: Options | null): Options { const options: any = {}; for (const key of Object.keys(defaultOptions)) { options[key] = opts && opts[key] != null ? opts[key] : defaultOptions[key]; diff --git a/packages/babel-parser/src/parse-error.js b/packages/babel-parser/src/parse-error.ts similarity index 82% rename from packages/babel-parser/src/parse-error.js rename to packages/babel-parser/src/parse-error.ts index 0cd9cbfc12d8..4a55588a7171 100644 --- a/packages/babel-parser/src/parse-error.js +++ b/packages/babel-parser/src/parse-error.ts @@ -1,5 +1,3 @@ -// @flow - import { Position } from "./util/location"; import type { NodeBase } from "./types"; import { @@ -25,9 +23,7 @@ interface ParseErrorSpecification { code: ParseErrorCode; reasonCode: string; syntaxPlugin?: string; - missingPlugin?: string | string[]; - loc: Position; details: ErrorDetails; @@ -44,22 +40,31 @@ export type ParseError = SyntaxError & // separate classes from `SyntaxError`'s. // // 1. https://github.com/microsoft/TypeScript/blob/v4.5.5/lib/lib.es5.d.ts#L1027 -export type ParseErrorConstructor = ({ - loc: Position, - details: ErrorDetails, +export type ParseErrorConstructor = (a: { + loc: Position; + details: ErrorDetails; }) => ParseError; -function toParseErrorConstructor({ +function toParseErrorConstructor({ toMessage, ...properties }: ParseErrorCredentials): ParseErrorConstructor { - type ConstructorArgument = { loc: Position, details: ErrorDetails }; + type ConstructorArgument = { + loc: Position; + details: ErrorDetails; + }; + return function constructor({ loc, details }: ConstructorArgument) { return instantiate>( SyntaxError, { ...properties, loc }, { - clone(overrides: { loc?: Position, details?: ErrorDetails } = {}) { + clone( + overrides: { + loc?: Position; + details?: ErrorDetails; + } = {}, + ) { const loc = overrides.loc || {}; return constructor({ loc: new Position( @@ -91,7 +96,7 @@ function toParseErrorConstructor({ }; } -// This part is tricky. You'll probably notice from the name of this function +export // This part is tricky. You'll probably notice from the name of this function // that it is supposed to return `ParseErrorCredentials`, but instead these. // declarations seem to instead imply that they return // `ParseErrorConstructor` instead. This is because in Flow we @@ -103,18 +108,32 @@ function toParseErrorConstructor({ // to the type system, avoiding the need to do so with $ObjMap (which doesn't // work) in `ParseErrorEnum`. This hack won't be necessary when we switch to // Typescript. -declare function toParseErrorCredentials( - T, - ?{ code?: ParseErrorCode, reasonCode?: string } | boolean, -): ParseErrorConstructor<{||}>; - -// ESLint seems to erroneously think that Flow's overloading syntax is an +function toParseErrorCredentials( + b: T, + a: + | { + code?: ParseErrorCode; + reasonCode?: string; + } + | undefined + | null + | boolean, +): ParseErrorConstructor<{}>; + +export // ESLint seems to erroneously think that Flow's overloading syntax is an // accidental redeclaration of the function: // https://github.com/babel/eslint-plugin-babel/issues/162 // eslint-disable-next-line no-redeclare -declare function toParseErrorCredentials( - (ErrorDetails) => string, - ?{ code?: ParseErrorCode, reasonCode?: string } | boolean, +function toParseErrorCredentials( + b: (a: ErrorDetails) => string, + a: + | { + code?: ParseErrorCode; + reasonCode?: string; + } + | undefined + | null + | boolean, ): ParseErrorConstructor; // See comment about eslint and Flow overloading above. @@ -129,13 +148,13 @@ export function toParseErrorCredentials(toMessageOrMessage, credentials) { }; } -// This is the templated form. -declare function ParseErrorEnum(string[]): typeof ParseErrorEnum; +export // This is the templated form. +function ParseErrorEnum(a: string[]): typeof ParseErrorEnum; -// See comment about eslint and Flow overloading above. +export // See comment about eslint and Flow overloading above. // eslint-disable-next-line no-redeclare -declare function ParseErrorEnum( - toParseErrorCredentials: (typeof toParseErrorCredentials) => T, +function ParseErrorEnum( + toParseErrorCredentials: (a: typeof toParseErrorCredentials) => T, syntaxPlugin?: string, ): T; @@ -174,10 +193,9 @@ export function ParseErrorEnum(argument, syntaxPlugin) { return ParseErrorConstructors; } -export type RaiseProperties = {| - ...ErrorDetails, - at: Position | NodeBase, -|}; +export type RaiseProperties = { + at: Position | NodeBase; +} & ErrorDetails; import ModuleErrors from "./parse-error/module-errors"; import StandardErrors from "./parse-error/standard-errors"; diff --git a/packages/babel-parser/src/parse-error/credentials.js b/packages/babel-parser/src/parse-error/credentials.ts similarity index 81% rename from packages/babel-parser/src/parse-error/credentials.js rename to packages/babel-parser/src/parse-error/credentials.ts index 1e758abb8731..9ddca01f1699 100644 --- a/packages/babel-parser/src/parse-error/credentials.js +++ b/packages/babel-parser/src/parse-error/credentials.ts @@ -1,11 +1,10 @@ -// @flow - export const ParseErrorCodes = Object.freeze({ SyntaxError: "BABEL_PARSER_SYNTAX_ERROR", SourceTypeModuleError: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED", }); -export type ParseErrorCode = $Values; +export type ParseErrorCode = + typeof ParseErrorCodes[keyof typeof ParseErrorCodes]; export type SyntaxPlugin = | "flow" @@ -17,11 +16,10 @@ export type SyntaxPlugin = export type ToMessage = (self: ErrorDetails) => string; export type ParseErrorCredentials = { - code: ParseErrorCode, - reasonCode: string, - syntaxPlugin?: SyntaxPlugin, - - toMessage: ToMessage, + code: ParseErrorCode; + reasonCode: string; + syntaxPlugin?: SyntaxPlugin; + toMessage: ToMessage; }; const reflect = (keys: string[], last = keys.length - 1) => ({ @@ -38,8 +36,8 @@ const reflect = (keys: string[], last = keys.length - 1) => ({ const instantiate = ( constructor: () => any, - properties: Object, - descriptors: Object, + properties: any, + descriptors: any, ) => Object.keys(descriptors) .map(key => [key, descriptors[key]]) @@ -58,7 +56,7 @@ const instantiate = ( configurable: true, ...descriptor, }), - Object.assign((new constructor(): T), properties), + Object.assign(new constructor() as T, properties), ); export { instantiate }; diff --git a/packages/babel-parser/src/parse-error/module-errors.js b/packages/babel-parser/src/parse-error/module-errors.ts similarity index 97% rename from packages/babel-parser/src/parse-error/module-errors.js rename to packages/babel-parser/src/parse-error/module-errors.ts index 82f83c222731..465d8018b572 100644 --- a/packages/babel-parser/src/parse-error/module-errors.js +++ b/packages/babel-parser/src/parse-error/module-errors.ts @@ -1,5 +1,3 @@ -// @flow - import { ParseErrorCodes, toParseErrorCredentials } from "../parse-error"; export default (_: typeof toParseErrorCredentials) => ({ diff --git a/packages/babel-parser/src/parse-error/pipeline-operator-errors.js b/packages/babel-parser/src/parse-error/pipeline-operator-errors.ts similarity index 95% rename from packages/babel-parser/src/parse-error/pipeline-operator-errors.js rename to packages/babel-parser/src/parse-error/pipeline-operator-errors.ts index a5a66d6d5eb7..fd6a1c0e67a5 100644 --- a/packages/babel-parser/src/parse-error/pipeline-operator-errors.js +++ b/packages/babel-parser/src/parse-error/pipeline-operator-errors.ts @@ -1,5 +1,3 @@ -// @flow - import { toParseErrorCredentials } from "../parse-error"; import toNodeDescription from "./to-node-description"; @@ -21,14 +19,18 @@ export default (_: typeof toParseErrorCredentials) => ({ PipeTopicUnbound: _( "Topic reference is unbound; it must be inside a pipe body.", ), - PipeTopicUnconfiguredToken: _<{| token: string |}>( + PipeTopicUnconfiguredToken: _<{ + token: string; + }>( ({ token }) => `Invalid topic token ${token}. In order to use ${token} as a topic reference, the pipelineOperator plugin must be configured with { "proposal": "hack", "topicToken": "${token}" }.`, ), PipeTopicUnused: _( "Hack-style pipe body does not contain a topic reference; Hack-style pipes must use topic at least once.", ), - PipeUnparenthesizedBody: _<{| type: string |}>( + PipeUnparenthesizedBody: _<{ + type: string; + }>( ({ type }) => `Hack-style pipe body cannot be an unparenthesized ${toNodeDescription({ type, diff --git a/packages/babel-parser/src/parse-error/standard-errors.js b/packages/babel-parser/src/parse-error/standard-errors.ts similarity index 83% rename from packages/babel-parser/src/parse-error/standard-errors.js rename to packages/babel-parser/src/parse-error/standard-errors.ts index 3f9747ce1d38..e1954852500d 100644 --- a/packages/babel-parser/src/parse-error/standard-errors.js +++ b/packages/babel-parser/src/parse-error/standard-errors.ts @@ -1,10 +1,11 @@ -// @flow - import { toParseErrorCredentials } from "../parse-error"; import toNodeDescription from "./to-node-description"; export type LValAncestor = - | { type: "UpdateExpression", prefix: boolean } + | { + type: "UpdateExpression"; + prefix: boolean; + } | { type: | "ArrayPattern" @@ -17,13 +18,13 @@ export type LValAncestor = | "Identfier" | "ObjectPattern" | "RestElement" - | "VariableDeclarator", + | "VariableDeclarator"; }; export default (_: typeof toParseErrorCredentials) => ({ - AccessorIsGenerator: _<{| kind: "get" | "set" |}>( - ({ kind }) => `A ${kind}ter cannot be a generator.`, - ), + AccessorIsGenerator: _<{ + kind: "get" | "set"; + }>(({ kind }) => `A ${kind}ter cannot be a generator.`), ArgumentsInClass: _( "'arguments' is only allowed in functions and class methods.", @@ -56,9 +57,9 @@ export default (_: typeof toParseErrorCredentials) => ({ ConstructorIsAccessor: _("Class constructor may not be an accessor."), ConstructorIsAsync: _("Constructor can't be an async function."), ConstructorIsGenerator: _("Constructor can't be a generator."), - DeclarationMissingInitializer: _<{| kind: "const" | "destructuring" |}>( - ({ kind }) => `Missing initializer in ${kind} declaration.`, - ), + DeclarationMissingInitializer: _<{ + kind: "const" | "destructuring"; + }>(({ kind }) => `Missing initializer in ${kind} declaration.`), DecoratorBeforeExport: _( "Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax.", ), @@ -76,7 +77,9 @@ export default (_: typeof toParseErrorCredentials) => ({ ), DuplicateConstructor: _("Duplicate constructor in the same class."), DuplicateDefaultExport: _("Only one default export allowed per module."), - DuplicateExport: _<{| exportName: string |}>( + DuplicateExport: _<{ + exportName: string; + }>( ({ exportName }) => `\`${exportName}\` has already been exported. Exported identifiers must be unique.`, ), @@ -84,7 +87,10 @@ export default (_: typeof toParseErrorCredentials) => ({ DuplicateRegExpFlags: _("Duplicate regular expression flag."), ElementAfterRest: _("Rest element must be last element."), EscapedCharNotAnIdentifier: _("Invalid Unicode escape."), - ExportBindingIsString: _<{| localName: string, exportName: string |}>( + ExportBindingIsString: _<{ + localName: string; + exportName: string; + }>( ({ localName, exportName }) => `A string literal cannot be used as an exported binding without \`from\`.\n- Did you mean \`export { '${localName}' as '${exportName}' } from 'some-module'\`?`, ), @@ -92,7 +98,9 @@ export default (_: typeof toParseErrorCredentials) => ({ "'from' is not allowed as an identifier after 'export default'.", ), - ForInOfLoopInitializer: _<{| type: "ForInStatement" | "ForOfStatement" |}>( + ForInOfLoopInitializer: _<{ + type: "ForInStatement" | "ForOfStatement"; + }>( ({ type }) => `'${ type === "ForInStatement" ? "for-in" : "for-of" @@ -105,7 +113,9 @@ export default (_: typeof toParseErrorCredentials) => ({ "Generators can only be declared at the top level or inside a block.", ), - IllegalBreakContinue: _<{| type: "BreakStatement" | "ContinueStatement" |}>( + IllegalBreakContinue: _<{ + type: "BreakStatement" | "ContinueStatement"; + }>( ({ type }) => `Unsyntactic ${type === "BreakStatement" ? "break" : "continue"}.`, ), @@ -114,14 +124,18 @@ export default (_: typeof toParseErrorCredentials) => ({ "Illegal 'use strict' directive in function with non-simple parameter list.", ), IllegalReturn: _("'return' outside of function."), - ImportBindingIsString: _<{| importName: string |}>( + ImportBindingIsString: _<{ + importName: string; + }>( ({ importName }) => `A string literal cannot be used as an imported binding.\n- Did you mean \`import { "${importName}" as foo }\`?`, ), ImportCallArgumentTrailingComma: _( "Trailing comma is disallowed inside import(...) arguments.", ), - ImportCallArity: _<{| maxArgumentCount: 1 | 2 |}>( + ImportCallArity: _<{ + maxArgumentCount: 1 | 2; + }>( ({ maxArgumentCount }) => `\`import()\` requires exactly ${ maxArgumentCount === 1 ? "one argument" : "one or two arguments" @@ -139,22 +153,26 @@ export default (_: typeof toParseErrorCredentials) => ({ InvalidCodePoint: _("Code point out of bounds."), InvalidCoverInitializedName: _("Invalid shorthand property initializer."), InvalidDecimal: _("Invalid decimal."), - InvalidDigit: _<{| radix: number |}>( - ({ radix }) => `Expected number in radix ${radix}.`, - ), + InvalidDigit: _<{ + radix: number; + }>(({ radix }) => `Expected number in radix ${radix}.`), InvalidEscapeSequence: _("Bad character escape sequence."), InvalidEscapeSequenceTemplate: _("Invalid escape sequence in template."), - InvalidEscapedReservedWord: _<{| reservedWord: string |}>( - ({ reservedWord }) => `Escape sequence in keyword ${reservedWord}.`, - ), - InvalidIdentifier: _<{| identifierName: string |}>( - ({ identifierName }) => `Invalid identifier ${identifierName}.`, - ), - InvalidLhs: _<{| ancestor: LValAncestor |}>( + InvalidEscapedReservedWord: _<{ + reservedWord: string; + }>(({ reservedWord }) => `Escape sequence in keyword ${reservedWord}.`), + InvalidIdentifier: _<{ + identifierName: string; + }>(({ identifierName }) => `Invalid identifier ${identifierName}.`), + InvalidLhs: _<{ + ancestor: LValAncestor; + }>( ({ ancestor }) => `Invalid left-hand side in ${toNodeDescription(ancestor)}.`, ), - InvalidLhsBinding: _<{| ancestor: LValAncestor |}>( + InvalidLhsBinding: _<{ + ancestor: LValAncestor; + }>( ({ ancestor }) => `Binding invalid left-hand side in ${toNodeDescription(ancestor)}.`, ), @@ -162,23 +180,23 @@ export default (_: typeof toParseErrorCredentials) => ({ InvalidOrMissingExponent: _( "Floating-point numbers require a valid exponent after the 'e'.", ), - InvalidOrUnexpectedToken: _<{| unexpected: string |}>( - ({ unexpected }) => `Unexpected character '${unexpected}'.`, - ), + InvalidOrUnexpectedToken: _<{ + unexpected: string; + }>(({ unexpected }) => `Unexpected character '${unexpected}'.`), InvalidParenthesizedAssignment: _( "Invalid parenthesized assignment pattern.", ), - InvalidPrivateFieldResolution: _<{| identifierName: string |}>( - ({ identifierName }) => `Private name #${identifierName} is not defined.`, - ), + InvalidPrivateFieldResolution: _<{ + identifierName: string; + }>(({ identifierName }) => `Private name #${identifierName} is not defined.`), InvalidPropertyBindingPattern: _("Binding member expression."), InvalidRecordProperty: _( "Only properties and spread elements are allowed in record definitions.", ), InvalidRestAssignmentPattern: _("Invalid rest operator's argument."), - LabelRedeclaration: _<{| labelName: string |}>( - ({ labelName }) => `Label '${labelName}' is already declared.`, - ), + LabelRedeclaration: _<{ + labelName: string; + }>(({ labelName }) => `Label '${labelName}' is already declared.`), LetInLexicalBinding: _( "'let' is not allowed to be used as a name in 'let' or 'const' declarations.", ), @@ -189,7 +207,9 @@ export default (_: typeof toParseErrorCredentials) => ({ "Only '=' operator can be used for specifying default value.", ), MissingSemicolon: _("Missing semicolon."), - MissingPlugin: _<{| missingPlugin: [string] |}>( + MissingPlugin: _<{ + missingPlugin: [string]; + }>( ({ missingPlugin }) => `This experimental syntax requires enabling the parser plugin: ${missingPlugin .map(name => JSON.stringify(name)) @@ -197,7 +217,9 @@ export default (_: typeof toParseErrorCredentials) => ({ ), // FIXME: Would be nice to make this "missingPlugins" instead. // Also), seems like we can drop the "(s)" from the message and just make it "s". - MissingOneOfPlugins: _<{| missingPlugin: string[] |}>( + MissingOneOfPlugins: _<{ + missingPlugin: string[]; + }>( ({ missingPlugin }) => `This experimental syntax requires enabling one of the following parser plugin(s): ${missingPlugin .map(name => JSON.stringify(name)) @@ -213,18 +235,22 @@ export default (_: typeof toParseErrorCredentials) => ({ ModuleAttributeInvalidValue: _( "Only string literals are allowed as module attribute values.", ), - ModuleAttributesWithDuplicateKeys: _<{| key: string |}>( + ModuleAttributesWithDuplicateKeys: _<{ + key: string; + }>( ({ key }) => `Duplicate key "${key}" is not allowed in module attributes.`, ), - ModuleExportNameHasLoneSurrogate: _<{| surrogateCharCode: number |}>( + ModuleExportNameHasLoneSurrogate: _<{ + surrogateCharCode: number; + }>( ({ surrogateCharCode }) => `An export name cannot include a lone surrogate, found '\\u${surrogateCharCode.toString( 16, )}'.`, ), - ModuleExportUndefined: _<{| localName: string |}>( - ({ localName }) => `Export '${localName}' is not defined.`, - ), + ModuleExportUndefined: _<{ + localName: string; + }>(({ localName }) => `Export '${localName}' is not defined.`), MultipleDefaultsInSwitch: _("Multiple default clauses."), NewlineAfterThrow: _("Illegal newline after throw."), NoCatchOrFinally: _("Missing catch or finally clause."), @@ -247,13 +273,15 @@ export default (_: typeof toParseErrorCredentials) => ({ ParamDupe: _("Argument name clash."), PatternHasAccessor: _("Object pattern can't contain getter or setter."), PatternHasMethod: _("Object pattern can't contain methods."), - PrivateInExpectedIn: _<{| identifierName: string |}>( + PrivateInExpectedIn: _<{ + identifierName: string; + }>( ({ identifierName }) => `Private names are only allowed in property accesses (\`obj.#${identifierName}\`) or in \`in\` expressions (\`#${identifierName} in obj\`).`, ), - PrivateNameRedeclaration: _<{| identifierName: string |}>( - ({ identifierName }) => `Duplicate private name #${identifierName}.`, - ), + PrivateNameRedeclaration: _<{ + identifierName: string; + }>(({ identifierName }) => `Duplicate private name #${identifierName}.`), RecordExpressionBarIncorrectEndSyntaxType: _( "Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", ), @@ -291,9 +319,9 @@ export default (_: typeof toParseErrorCredentials) => ({ UnexpectedImportExport: _( "'import' and 'export' may only appear at the top level.", ), - UnexpectedKeyword: _<{| keyword: string |}>( - ({ keyword }) => `Unexpected keyword '${keyword}'.`, - ), + UnexpectedKeyword: _<{ + keyword: string; + }>(({ keyword }) => `Unexpected keyword '${keyword}'.`), UnexpectedLeadingDecorator: _( "Leading decorators must be attached to a class declaration.", ), @@ -307,14 +335,14 @@ export default (_: typeof toParseErrorCredentials) => ({ "A numeric separator is only allowed between two digits.", ), UnexpectedPrivateField: _("Unexpected private name."), - UnexpectedReservedWord: _<{| reservedWord: string |}>( - ({ reservedWord }) => `Unexpected reserved word '${reservedWord}'.`, - ), + UnexpectedReservedWord: _<{ + reservedWord: string; + }>(({ reservedWord }) => `Unexpected reserved word '${reservedWord}'.`), UnexpectedSuper: _("'super' is only allowed in object methods and classes."), - UnexpectedToken: _<{| - expected?: ?string, - unexpected?: ?string, - |}>( + UnexpectedToken: _<{ + expected?: string | null; + unexpected?: string | null; + }>( ({ expected, unexpected }) => `Unexpected token${unexpected ? ` '${unexpected}'.` : ""}${ expected ? `, expected "${expected}"` : "" @@ -333,10 +361,10 @@ export default (_: typeof toParseErrorCredentials) => ({ UnsupportedImport: _( "`import` can only be used in `import()` or `import.meta`.", ), - UnsupportedMetaProperty: _<{| - target: string, - onlyValidPropertyName: string, - |}>( + UnsupportedMetaProperty: _<{ + target: string; + onlyValidPropertyName: string; + }>( ({ target, onlyValidPropertyName }) => `The only valid meta property for ${target} is ${target}.${onlyValidPropertyName}.`, ), @@ -353,7 +381,9 @@ export default (_: typeof toParseErrorCredentials) => ({ UnterminatedRegExp: _("Unterminated regular expression."), UnterminatedString: _("Unterminated string constant."), UnterminatedTemplate: _("Unterminated template."), - VarRedeclaration: _<{| identifierName: string |}>( + VarRedeclaration: _<{ + identifierName: string; + }>( ({ identifierName }) => `Identifier '${identifierName}' has already been declared.`, ), diff --git a/packages/babel-parser/src/parse-error/strict-mode-errors.js b/packages/babel-parser/src/parse-error/strict-mode-errors.ts similarity index 81% rename from packages/babel-parser/src/parse-error/strict-mode-errors.js rename to packages/babel-parser/src/parse-error/strict-mode-errors.ts index 62d4fe9038f2..1a6da37ac225 100644 --- a/packages/babel-parser/src/parse-error/strict-mode-errors.js +++ b/packages/babel-parser/src/parse-error/strict-mode-errors.ts @@ -1,5 +1,3 @@ -// @flow - import { toParseErrorCredentials } from "../parse-error"; export default (_: typeof toParseErrorCredentials) => ({ @@ -10,17 +8,17 @@ export default (_: typeof toParseErrorCredentials) => ({ // 1. https://tc39.es/ecma262/#sec-static-semantics-stringvalue // 2. https://tc39.es/ecma262/#prod-IdentifierReference // 3. https://github.com/babel/babel/blob/main/packages/babel-parser/ast/spec.md#identifier - StrictEvalArguments: _<{| referenceName: string |}>( - ({ referenceName }) => `Assigning to '${referenceName}' in strict mode.`, - ), + StrictEvalArguments: _<{ + referenceName: string; + }>(({ referenceName }) => `Assigning to '${referenceName}' in strict mode.`), // `bindingName` is the StringValue[1] of a BindingIdentifier[2], which is // represented as just an `Identifier`[3] in the Babel AST. // 1. https://tc39.es/ecma262/#sec-static-semantics-stringvalue // 2. https://tc39.es/ecma262/#prod-BindingIdentifier // 3. https://github.com/babel/babel/blob/main/packages/babel-parser/ast/spec.md#identifier - StrictEvalArgumentsBinding: _<{| bindingName: string |}>( - ({ bindingName }) => `Binding '${bindingName}' in strict mode.`, - ), + StrictEvalArgumentsBinding: _<{ + bindingName: string; + }>(({ bindingName }) => `Binding '${bindingName}' in strict mode.`), StrictFunction: _( "In strict mode code, functions can only be declared at top level or inside a block.", diff --git a/packages/babel-parser/src/parse-error/to-node-description.js b/packages/babel-parser/src/parse-error/to-node-description.ts similarity index 83% rename from packages/babel-parser/src/parse-error/to-node-description.js rename to packages/babel-parser/src/parse-error/to-node-description.ts index c604e30454b1..41577e925e9e 100644 --- a/packages/babel-parser/src/parse-error/to-node-description.js +++ b/packages/babel-parser/src/parse-error/to-node-description.ts @@ -20,12 +20,19 @@ const NodeDescriptions = { YieldExpression: "yield expression", }; -type NodeTypesWithDescriptions = $Keys< - $Diff, +type NodeTypesWithDescriptions = keyof Omit< + typeof NodeDescriptions, + "UpdateExpression" >; + type NodeWithDescription = - | { type: "UpdateExpression", prefix: boolean } - | { type: NodeTypesWithDescriptions }; + | { + type: "UpdateExpression"; + prefix: boolean; + } + | { + type: NodeTypesWithDescriptions; + }; // eslint-disable-next-line no-confusing-arrow const toNodeDescription = ({ type, prefix }: NodeWithDescription) => diff --git a/packages/babel-parser/src/parser/base.js b/packages/babel-parser/src/parser/base.ts similarity index 91% rename from packages/babel-parser/src/parser/base.js rename to packages/babel-parser/src/parser/base.ts index 522534ea5fff..fcb2c6ece510 100644 --- a/packages/babel-parser/src/parser/base.js +++ b/packages/babel-parser/src/parser/base.ts @@ -1,5 +1,3 @@ -// @flow - import type { Options } from "../options"; import type State from "../tokenizer/state"; import type { PluginsMap } from "./index"; @@ -12,12 +10,12 @@ export default class BaseParser { // Properties set by constructor in index.js declare options: Options; declare inModule: boolean; - declare scope: ScopeHandler<*>; + declare scope: ScopeHandler; declare classScope: ClassScopeHandler; declare prodParam: ProductionParameterHandler; declare expressionScope: ExpressionScopeHandler; declare plugins: PluginsMap; - declare filename: ?string; + declare filename: string | undefined | null; // Names of exports store. `default` is stored as a name for both // `export default foo;` and `export { foo as default };`. declare exportedIdentifiers: Set; @@ -58,4 +56,11 @@ export default class BaseParser { } } -export type PluginConfig = string | [string, { [string]: any }]; +export type PluginConfig = + | string + | [ + string, + { + [x: string]: any; + }, + ]; diff --git a/packages/babel-parser/src/parser/comments.js b/packages/babel-parser/src/parser/comments.ts similarity index 98% rename from packages/babel-parser/src/parser/comments.js rename to packages/babel-parser/src/parser/comments.ts index 9b50e63356c3..9258aaeafc11 100644 --- a/packages/babel-parser/src/parser/comments.js +++ b/packages/babel-parser/src/parser/comments.ts @@ -1,5 +1,3 @@ -// @flow - /*:: declare var invariant; */ import BaseParser from "./base"; @@ -19,12 +17,12 @@ import * as charCodes from "charcodes"; * with minimal size (|end - start|) */ export type CommentWhitespace = { - start: number, - end: number, - comments: Array, - leadingNode: Node | null, - trailingNode: Node | null, - containingNode: Node | null, + start: number; + end: number; + comments: Array; + leadingNode: Node | null; + trailingNode: Node | null; + containingNode: Node | null; }; /** diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.ts similarity index 96% rename from packages/babel-parser/src/parser/expression.js rename to packages/babel-parser/src/parser/expression.ts index 3b968ffc90e0..f2ac4fc62551 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.ts @@ -1,5 +1,3 @@ -// @flow - // A recursive descent parser operates by defining functions for all // syntactic elements, and recursively calling those, each function // advancing the input stream and returning an AST node. Precedence @@ -119,9 +117,11 @@ export default class ExpressionParser extends LValParser { checkProto( prop: N.ObjectMember | N.SpreadElement, - isRecord: ?boolean, - protoRef: { used: boolean }, - refExpressionErrors: ?ExpressionErrors, + isRecord: boolean | undefined | null, + protoRef: { + used: boolean; + }, + refExpressionErrors?: ExpressionErrors | null, ): void { if ( prop.type === "SpreadElement" || @@ -233,7 +233,7 @@ export default class ExpressionParser extends LValParser { // Set [~In] parameter for assignment expression parseMaybeAssignDisallowIn( - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, afterLeftParse?: Function, ) { return this.disallowInAnd(() => @@ -243,7 +243,7 @@ export default class ExpressionParser extends LValParser { // Set [+In] parameter for assignment expression parseMaybeAssignAllowIn( - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, afterLeftParse?: Function, ) { return this.allowInAnd(() => @@ -265,7 +265,7 @@ export default class ExpressionParser extends LValParser { // operators like `+=`. // https://tc39.es/ecma262/#prod-AssignmentExpression parseMaybeAssign( - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, afterLeftParse?: Function, ): N.Expression { const startPos = this.state.start; @@ -363,7 +363,7 @@ export default class ExpressionParser extends LValParser { startPos: number, startLoc: Position, // eslint-disable-next-line no-unused-vars - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): N.Expression { if (this.eat(tt.question)) { const node = this.startNodeAt(startPos, startLoc); @@ -584,7 +584,7 @@ export default class ExpressionParser extends LValParser { // Parse unary operators, both prefix and postfix. // https://tc39.es/ecma262/#prod-UnaryExpression parseMaybeUnary( - refExpressionErrors: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, sawUnary?: boolean, ): N.Expression { const startPos = this.state.start; @@ -649,7 +649,7 @@ export default class ExpressionParser extends LValParser { parseUpdate( node: N.Expression, update: boolean, - refExpressionErrors: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): N.Expression { if (update) { this.checkLVal(node.argument, { @@ -677,7 +677,9 @@ export default class ExpressionParser extends LValParser { // Parse call, dot, and `[]`-subscript expressions. // https://tc39.es/ecma262/#prod-LeftHandSideExpression - parseExprSubscripts(refExpressionErrors: ?ExpressionErrors): N.Expression { + parseExprSubscripts( + refExpressionErrors?: ExpressionErrors | null, + ): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const potentialArrowAt = this.state.potentialArrowAt; @@ -694,7 +696,7 @@ export default class ExpressionParser extends LValParser { base: N.Expression, startPos: number, startLoc: Position, - noCalls?: ?boolean, + noCalls?: boolean | null, ): N.Expression { const state = { optionalChainMember: false, @@ -718,7 +720,7 @@ export default class ExpressionParser extends LValParser { base: N.Expression, startPos: number, startLoc: Position, - noCalls: ?boolean, + noCalls: boolean | undefined | null, state: N.ParseSubscriptState, ): N.Expression { const { type } = this.state; @@ -812,7 +814,7 @@ export default class ExpressionParser extends LValParser { base: N.Expression, startPos: number, startLoc: Position, - noCalls: ?boolean, + noCalls: boolean | undefined | null, state: N.ParseSubscriptState, ): N.Expression { const node = this.startNodeAt(startPos, startLoc); @@ -933,7 +935,7 @@ export default class ExpressionParser extends LValParser { ); } - finishCallExpression( + finishCallExpression( node: T, optional: boolean, ): N.Expression { @@ -974,9 +976,9 @@ export default class ExpressionParser extends LValParser { close: TokenType, dynamicImport?: boolean, allowPlaceholder?: boolean, - nodeForExtra?: ?N.Node, - refExpressionErrors?: ?ExpressionErrors, - ): $ReadOnlyArray { + nodeForExtra?: N.Node | null, + refExpressionErrors?: ExpressionErrors | null, + ): ReadonlyArray { const elts = []; let first = true; const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; @@ -1062,7 +1064,7 @@ export default class ExpressionParser extends LValParser { // Import // AsyncArrowFunction - parseExprAtom(refExpressionErrors?: ?ExpressionErrors): N.Expression { + parseExprAtom(refExpressionErrors?: ExpressionErrors | null): N.Expression { let node; const { type } = this.state; @@ -1614,9 +1616,9 @@ export default class ExpressionParser extends LValParser { return this.parseMetaProperty(node, id, "meta"); } - parseLiteralAtNode( + parseLiteralAtNode( value: any, - type: $ElementType, + type: T["type"], node: any, ): T { this.addExtra(node, "rawValue", value); @@ -1626,7 +1628,7 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, type); } - parseLiteral(value: any, type: $ElementType): T { + parseLiteral(value: any, type: T["type"]): T { const node = this.startNode(); return this.parseLiteralAtNode(value, type, node); } @@ -1647,7 +1649,7 @@ export default class ExpressionParser extends LValParser { return this.parseLiteral(value, "DecimalLiteral"); } - parseRegExpLiteral(value: { value: any, pattern: string, flags: string }) { + parseRegExpLiteral(value: { value: any; pattern: string; flags: string }) { const node = this.parseLiteral( value.value, "RegExpLiteral", @@ -1803,7 +1805,9 @@ export default class ExpressionParser extends LValParser { return !this.canInsertSemicolon(); } - parseArrow(node: N.ArrowFunctionExpression): ?N.ArrowFunctionExpression { + parseArrow( + node: N.ArrowFunctionExpression, + ): N.ArrowFunctionExpression | undefined | null { if (this.eat(tt.arrow)) { return node; } @@ -1811,8 +1815,10 @@ export default class ExpressionParser extends LValParser { parseParenItem( node: N.Expression, - startPos: number, // eslint-disable-line no-unused-vars - startLoc: Position, // eslint-disable-line no-unused-vars + // eslint-disable-line no-unused-vars + startPos: number, + // eslint-disable-line no-unused-vars + startLoc: Position, ): N.Expression { return node; } @@ -1928,11 +1934,11 @@ export default class ExpressionParser extends LValParser { // Parse an object literal, binding pattern, or record. - parseObjectLike( + parseObjectLike( close: TokenType, isPattern: boolean, - isRecord?: ?boolean, - refExpressionErrors?: ?ExpressionErrors, + isRecord?: boolean | null, + refExpressionErrors?: ExpressionErrors | null, ): T { if (isRecord) { this.expectPlugin("recordAndTuple"); @@ -2013,7 +2019,7 @@ export default class ExpressionParser extends LValParser { // https://tc39.es/ecma262/#prod-PropertyDefinition parsePropertyDefinition( - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): N.ObjectMember | N.SpreadElement { let decorators = []; if (this.match(tt.at)) { @@ -2139,7 +2145,7 @@ export default class ExpressionParser extends LValParser { isAsync: boolean, isPattern: boolean, isAccessor: boolean, - ): ?N.ObjectMethod { + ): N.ObjectMethod | undefined | null { if (isAccessor) { // isAccessor implies isAsync: false, isPattern: false, isGenerator: false this.parseMethod( @@ -2175,11 +2181,11 @@ export default class ExpressionParser extends LValParser { // else https://tc39.es/ecma262/#prod-PropertyDefinition parseObjectProperty( prop: N.ObjectProperty, - startPos: ?number, - startLoc: ?Position, + startPos: number | undefined | null, + startLoc: Position | undefined | null, isPattern: boolean, - refExpressionErrors: ?ExpressionErrors, - ): ?N.ObjectProperty { + refExpressionErrors?: ExpressionErrors | null, + ): N.ObjectProperty | undefined | null { prop.shorthand = false; if (this.eat(tt.colon)) { @@ -2230,13 +2236,13 @@ export default class ExpressionParser extends LValParser { parseObjPropValue( prop: any, - startPos: ?number, - startLoc: ?Position, + startPos: number | undefined | null, + startLoc: Position | undefined | null, isGenerator: boolean, isAsync: boolean, isPattern: boolean, isAccessor: boolean, - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): void { const node = this.parseObjectMethod( @@ -2265,10 +2271,10 @@ export default class ExpressionParser extends LValParser { // and record the position of the first private name parsePropertyName( prop: N.ObjectOrClassMember | N.ClassMember | N.TsNamedTypeElementBase, - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): N.Expression | N.Identifier { if (this.eat(tt.bracketL)) { - (prop: $FlowSubtype).computed = true; + (prop as $FlowSubtype).computed = true; prop.key = this.parseMaybeAssignAllowIn(); this.expect(tt.bracketR); } else { @@ -2311,7 +2317,7 @@ export default class ExpressionParser extends LValParser { throw this.unexpected(); } } - (prop: $FlowFixMe).key = key; + (prop as any).key = key; if (type !== tt.privateName) { // ClassPrivateProperty is never computed, so we don't assign in that case. prop.computed = false; @@ -2323,7 +2329,10 @@ export default class ExpressionParser extends LValParser { // Initialize empty function node. - initFunction(node: N.BodilessFunctionOrMethodBase, isAsync: ?boolean): void { + initFunction( + node: N.BodilessFunctionOrMethodBase, + isAsync?: boolean | null, + ): void { node.id = null; node.generator = false; node.async = !!isAsync; @@ -2331,7 +2340,7 @@ export default class ExpressionParser extends LValParser { // Parse object or class method. - parseMethod( + parseMethod( node: T, isGenerator: boolean, isAsync: boolean, @@ -2350,7 +2359,7 @@ export default class ExpressionParser extends LValParser { (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0), ); this.prodParam.enter(functionFlags(isAsync, node.generator)); - this.parseFunctionParams((node: any), allowModifiers); + this.parseFunctionParams(node as any, allowModifiers); this.parseFunctionBodyAndFinish(node, type, true); this.prodParam.exit(); this.scope.exit(); @@ -2365,7 +2374,7 @@ export default class ExpressionParser extends LValParser { close: TokenType, canBePattern: boolean, isTuple: boolean, - refExpressionErrors: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): N.ArrayExpression | N.TupleExpression { if (isTuple) { this.expectPlugin("recordAndTuple"); @@ -2392,9 +2401,9 @@ export default class ExpressionParser extends LValParser { // assignable list. parseArrowExpression( node: N.ArrowFunctionExpression, - params: ?(N.Expression[]), + params: N.Expression[] | undefined | null, isAsync: boolean, - trailingCommaLoc: ?Position, + trailingCommaLoc?: Position | null, ): N.ArrowFunctionExpression { this.scope.enter(SCOPE_FUNCTION | SCOPE_ARROW); let flags = functionFlags(isAsync, false); @@ -2425,7 +2434,7 @@ export default class ExpressionParser extends LValParser { setArrowFunctionParameters( node: N.ArrowFunctionExpression, params: N.Expression[], - trailingCommaLoc: ?Position, + trailingCommaLoc?: Position | null, ): void { this.toAssignableList(params, trailingCommaLoc, false); node.params = params; @@ -2434,7 +2443,7 @@ export default class ExpressionParser extends LValParser { parseFunctionBodyAndFinish( node: N.BodilessFunctionOrMethodBase, type: string, - isMethod?: boolean = false, + isMethod: boolean = false, ): void { // $FlowIgnore (node is not bodiless if we get here) this.parseFunctionBody(node, false, isMethod); @@ -2444,8 +2453,8 @@ export default class ExpressionParser extends LValParser { // Parse function body and check parameters. parseFunctionBody( node: N.Function, - allowExpression: ?boolean, - isMethod?: boolean = false, + allowExpression?: boolean | null, + isMethod: boolean = false, ): void { const isExpression = allowExpression && !this.match(tt.braceL); this.expressionScope.enter(newExpressionScope()); @@ -2512,7 +2521,7 @@ export default class ExpressionParser extends LValParser { } isSimpleParamList( - params: $ReadOnlyArray, + params: ReadonlyArray, ): boolean { for (let i = 0, len = params.length; i < len; i++) { if (!this.isSimpleParameter(params[i])) return false; @@ -2524,8 +2533,8 @@ export default class ExpressionParser extends LValParser { node: N.Function, allowDuplicates: boolean, // eslint-disable-next-line no-unused-vars - isArrowFunction: ?boolean, - strictModeChanged?: boolean = true, + isArrowFunction?: boolean | null, + strictModeChanged: boolean = true, ): void { const checkClashes = !allowDuplicates && new Set(); // We create a fake node with the "ephemeral" type `FormalParameters`[1] @@ -2554,9 +2563,9 @@ export default class ExpressionParser extends LValParser { parseExprList( close: TokenType, allowEmpty?: boolean, - refExpressionErrors?: ?ExpressionErrors, - nodeForExtra?: ?N.Node, - ): $ReadOnlyArray { + refExpressionErrors?: ExpressionErrors | null, + nodeForExtra?: N.Node | null, + ): ReadonlyArray { const elts = []; let first = true; @@ -2580,10 +2589,10 @@ export default class ExpressionParser extends LValParser { } parseExprListItem( - allowEmpty: ?boolean, - refExpressionErrors?: ?ExpressionErrors, - allowPlaceholder: ?boolean, - ): ?N.Expression { + allowEmpty?: boolean | null, + refExpressionErrors?: ExpressionErrors | null, + allowPlaceholder?: boolean | null, + ): N.Expression | undefined | null { let elt; if (this.match(tt.comma)) { if (!allowEmpty) { diff --git a/packages/babel-parser/src/parser/index.js b/packages/babel-parser/src/parser/index.ts similarity index 86% rename from packages/babel-parser/src/parser/index.js rename to packages/babel-parser/src/parser/index.ts index 2db11faf491c..c9bea68c3a3e 100644 --- a/packages/babel-parser/src/parser/index.js +++ b/packages/babel-parser/src/parser/index.ts @@ -1,5 +1,3 @@ -// @flow - import type { Options } from "../options"; import type { File /*::, JSXOpeningElement */ } from "../types"; import type { PluginList } from "../plugin-utils"; @@ -7,7 +5,12 @@ import { getOptions } from "../options"; import StatementParser from "./statement"; import ScopeHandler from "../util/scope"; -export type PluginsMap = Map; +export type PluginsMap = Map< + string, + { + [x: string]: any; + } +>; export default class Parser extends StatementParser { // Forward-declaration so typescript plugin can override jsx plugin @@ -17,7 +20,7 @@ export default class Parser extends StatementParser { ) => JSXOpeningElement; */ - constructor(options: ?Options, input: string) { + constructor(options: Options | undefined | null, input: string) { options = getOptions(options); super(options, input); @@ -28,7 +31,9 @@ export default class Parser extends StatementParser { } // This can be overwritten, for example, by the TypeScript plugin. - getScopeHandler(): Class> { + getScopeHandler(): { + new (...args: any): ScopeHandler; + } { return ScopeHandler; } diff --git a/packages/babel-parser/src/parser/lval.js b/packages/babel-parser/src/parser/lval.ts similarity index 95% rename from packages/babel-parser/src/parser/lval.js rename to packages/babel-parser/src/parser/lval.ts index 20f883246882..cb6207166934 100644 --- a/packages/babel-parser/src/parser/lval.js +++ b/packages/babel-parser/src/parser/lval.ts @@ -1,5 +1,3 @@ -// @flow - /*:: declare var invariant; */ import * as charCodes from "charcodes"; import { tt, type TokenType } from "../tokenizer/types"; @@ -230,7 +228,7 @@ export default class LValParser extends NodeUtils { toAssignableList( exprList: Expression[], - trailingCommaLoc?: ?Position, + trailingCommaLoc: Position | undefined | null, isLHS: boolean, ): void { const end = exprList.length - 1; @@ -307,14 +305,15 @@ export default class LValParser extends NodeUtils { // Convert list of expression atoms to a list of toReferencedList( - exprList: $ReadOnlyArray, - isParenthesizedExpr?: boolean, // eslint-disable-line no-unused-vars - ): $ReadOnlyArray { + exprList: ReadonlyArray, + // eslint-disable-line no-unused-vars + isParenthesizedExpr?: boolean, + ): ReadonlyArray { return exprList; } toReferencedListDeep( - exprList: $ReadOnlyArray, + exprList: ReadonlyArray, isParenthesizedExpr?: boolean, ): void { this.toReferencedList(exprList, isParenthesizedExpr); @@ -329,8 +328,8 @@ export default class LValParser extends NodeUtils { // Parses spread element. parseSpread( - refExpressionErrors: ?ExpressionErrors, - refNeedsArrowPos?: ?Pos, + refExpressionErrors?: ExpressionErrors | null, + refNeedsArrowPos?: Pos | null, ): SpreadElement { const node = this.startNode(); this.next(); @@ -377,10 +376,10 @@ export default class LValParser extends NodeUtils { // https://tc39.es/ecma262/#prod-BindingElementList parseBindingList( close: TokenType, - closeCharCode: $Values, + closeCharCode: typeof charCodes[keyof typeof charCodes], allowEmpty?: boolean, allowModifiers?: boolean, - ): $ReadOnlyArray { + ): ReadonlyArray { const elts: Array = []; let first = true; while (!this.eat(close)) { @@ -454,7 +453,7 @@ export default class LValParser extends NodeUtils { } parseAssignableListItem( - allowModifiers: ?boolean, + allowModifiers: boolean | undefined | null, decorators: Decorator[], ): Pattern | TSParameterProperty { const left = this.parseMaybeDefault(); @@ -474,9 +473,9 @@ export default class LValParser extends NodeUtils { // Parses assignment pattern around given atom if possible. // https://tc39.es/ecma262/#prod-BindingElement parseMaybeDefault( - startPos?: ?number, - startLoc?: ?Position, - left?: ?Pattern, + startPos?: number | null, + startLoc?: Position | null, + left?: Pattern | null, ): Pattern { startLoc = startLoc ?? this.state.startLoc; startPos = startPos ?? this.state.start; @@ -579,12 +578,12 @@ export default class LValParser extends NodeUtils { allowingSloppyLetBinding = !(binding & BIND_SCOPE_LEXICAL), hasParenthesizedAncestor = false, }: { - in: LValAncestor, - binding?: BindingTypes, - checkClashes?: Set | false, - strictModeChanged?: boolean, - allowingSloppyLetBinding?: boolean, - hasParenthesizedAncestor?: boolean, + in: LValAncestor; + binding?: BindingTypes; + checkClashes?: Set | false; + strictModeChanged?: boolean; + allowingSloppyLetBinding?: boolean; + hasParenthesizedAncestor?: boolean; }, ): void { const type = expression.type; @@ -724,7 +723,9 @@ export default class LValParser extends NodeUtils { } } - checkCommaAfterRest(close: $Values): boolean { + checkCommaAfterRest( + close: typeof charCodes[keyof typeof charCodes], + ): boolean { if (!this.match(tt.comma)) { return false; } diff --git a/packages/babel-parser/src/parser/node.js b/packages/babel-parser/src/parser/node.ts similarity index 91% rename from packages/babel-parser/src/parser/node.js rename to packages/babel-parser/src/parser/node.ts index b12c533ce96b..5639a4bb963e 100644 --- a/packages/babel-parser/src/parser/node.js +++ b/packages/babel-parser/src/parser/node.ts @@ -1,5 +1,3 @@ -// @flow - import type Parser from "./index"; import UtilParser from "./util"; import { SourceLocation, type Position } from "../util/location"; @@ -24,7 +22,9 @@ class Node implements NodeBase { declare leadingComments: Array; declare trailingComments: Array; declare innerComments: Array; - declare extra: { [key: string]: any }; + declare extra: { + [key: string]: any; + }; } const NodePrototype = Node.prototype; @@ -95,30 +95,30 @@ export function cloneStringLiteral(node: any): any { } export class NodeUtils extends UtilParser { - startNode(): T { + startNode(): T { // $FlowIgnore return new Node(this, this.state.start, this.state.startLoc); } - startNodeAt(pos: number, loc: Position): T { + startNodeAt(pos: number, loc: Position): T { // $FlowIgnore return new Node(this, pos, loc); } /** Start a new node with a previous node's location. */ - startNodeAtNode(type: NodeType): T { + startNodeAtNode(type: NodeType): T { return this.startNodeAt(type.start, type.loc.start); } // Finish an AST node, adding `type` and `end` properties. - finishNode(node: T, type: string): T { + finishNode(node: T, type: string): T { return this.finishNodeAt(node, type, this.state.lastTokEndLoc); } // Finish node at given position - finishNodeAt(node: T, type: string, endLoc: Position): T { + finishNodeAt(node: T, type: string, endLoc: Position): T { if (process.env.NODE_ENV !== "production" && node.end > 0) { throw new Error( "Do not call finishNode*() twice on the same node." + @@ -141,7 +141,7 @@ export class NodeUtils extends UtilParser { resetEndLocation( node: NodeBase, - endLoc?: Position = this.state.lastTokEndLoc, + endLoc: Position = this.state.lastTokEndLoc, ): void { node.end = endLoc.index; node.loc.end = endLoc; diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.ts similarity index 98% rename from packages/babel-parser/src/parser/statement.js rename to packages/babel-parser/src/parser/statement.ts index 5c9aa4b6838f..0158ba6e637a 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.ts @@ -1,5 +1,3 @@ -// @flow - import * as N from "../types"; import { tokenIsIdentifier, @@ -234,7 +232,7 @@ export default class StatementParser extends ExpressionParser { * @memberof StatementParser */ stmtToDirective(stmt: N.Statement): N.Directive { - const directive = (stmt: any); + const directive = stmt as any; directive.type = "Directive"; directive.value = directive.expression; delete directive.expression; @@ -264,7 +262,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "InterpreterDirective"); } - isLet(context: ?string): boolean { + isLet(context?: string | null): boolean { if (!this.isContextual(tt._let)) { return false; } @@ -280,7 +278,7 @@ export default class StatementParser extends ExpressionParser { * @returns {boolean} * @memberof StatementParser */ - isLetKeyword(context: ?string): boolean { + isLetKeyword(context?: string | null): boolean { const next = this.nextTokenStart(); const nextCh = this.codePointAtPos(next); // For ambiguous cases, determine if a LexicalDeclaration (or only a @@ -322,14 +320,17 @@ export default class StatementParser extends ExpressionParser { // https://tc39.es/ecma262/#prod-Statement // ImportDeclaration and ExportDeclaration are also handled here so we can throw recoverable errors // when they are not at the top level - parseStatement(context: ?string, topLevel?: boolean): N.Statement { + parseStatement(context?: string | null, topLevel?: boolean): N.Statement { if (this.match(tt.at)) { this.parseDecorators(true); } return this.parseStatementContent(context, topLevel); } - parseStatementContent(context: ?string, topLevel: ?boolean): N.Statement { + parseStatementContent( + context?: string | null, + topLevel?: boolean | null, + ): N.Statement { let starttype = this.state.type; const node = this.startNode(); let kind; @@ -955,7 +956,7 @@ export default class StatementParser extends ExpressionParser { node: N.LabeledStatement, maybeName: string, expr: N.Identifier, - context: ?string, + context?: string | null, ): N.LabeledStatement { for (const label of this.state.labels) { if (label.name === maybeName) { @@ -1013,8 +1014,8 @@ export default class StatementParser extends ExpressionParser { // function bodies). parseBlock( - allowDirectives?: boolean = false, - createNewLexicalScope?: boolean = true, + allowDirectives: boolean = false, + createNewLexicalScope: boolean = true, afterBlockParse?: (hasStrictModeDirective: boolean) => void, ): N.BlockStatement { const node = this.startNode(); @@ -1048,7 +1049,7 @@ export default class StatementParser extends ExpressionParser { parseBlockBody( node: N.BlockStatementLike, - allowDirectives: ?boolean, + allowDirectives: boolean | undefined | null, topLevel: boolean, end: TokenType, afterBlockParse?: (hasStrictModeDirective: boolean) => void, @@ -1069,7 +1070,7 @@ export default class StatementParser extends ExpressionParser { // https://tc39.es/ecma262/#prod-ModuleBody parseBlockOrModuleBlockBody( body: N.Statement[], - directives: ?(N.Directive[]), + directives: N.Directive[] | undefined | null, topLevel: boolean, end: TokenType, afterBlockParse?: (hasStrictModeDirective: boolean) => void, @@ -1120,7 +1121,7 @@ export default class StatementParser extends ExpressionParser { parseFor( node: N.ForStatement, - init: ?(N.VariableDeclaration | N.Expression), + init?: N.VariableDeclaration | N.Expression | null, ): N.ForStatement { node.init = init; this.semicolon(/* allowAsi */ false); @@ -1151,7 +1152,7 @@ export default class StatementParser extends ExpressionParser { parseForIn( node: N.ForInOf, init: N.VariableDeclaration | N.AssignmentPattern, - awaitAt: ?Position, + awaitAt?: Position | null, ): N.ForInOf { const isForIn = this.match(tt._in); this.next(); @@ -1260,10 +1261,10 @@ export default class StatementParser extends ExpressionParser { // Parse a function declaration or literal (depending on the // `isStatement` parameter). - parseFunction( + parseFunction( node: T, - statement?: number = FUNC_NO_FLAGS, - isAsync?: boolean = false, + statement: number = FUNC_NO_FLAGS, + isAsync: boolean = false, ): T { const isStatement = statement & FUNC_STATEMENT; const isHangingStatement = statement & FUNC_HANGING_STATEMENT; @@ -1318,7 +1319,7 @@ export default class StatementParser extends ExpressionParser { return node; } - parseFunctionId(requireId?: boolean): ?N.Identifier { + parseFunctionId(requireId?: boolean): N.Identifier | undefined | null { return requireId || tokenIsIdentifier(this.state.type) ? this.parseIdentifier() : null; @@ -1358,7 +1359,7 @@ export default class StatementParser extends ExpressionParser { // Parse a class declaration or literal (depending on the // `isStatement` parameter). - parseClass( + parseClass( node: T, isStatement: /* T === ClassDeclaration */ boolean, optionalId?: boolean, @@ -1474,7 +1475,7 @@ export default class StatementParser extends ExpressionParser { const key = this.parseIdentifier(true); // eats the modifier if (this.isClassMethod()) { - const method: N.ClassMethod = (member: any); + const method: N.ClassMethod = member as any; // a method named like the modifier method.kind = "method"; @@ -1491,7 +1492,7 @@ export default class StatementParser extends ExpressionParser { ); return true; } else if (this.isClassProperty()) { - const prop: N.ClassProperty = (member: any); + const prop: N.ClassProperty = member as any; // a property named like the modifier prop.computed = false; @@ -1517,7 +1518,7 @@ export default class StatementParser extends ExpressionParser { return; } if (this.eat(tt.braceL)) { - this.parseClassStaticBlock(classBody, ((member: any): N.StaticBlock)); + this.parseClassStaticBlock(classBody, member as any as N.StaticBlock); return; } } @@ -1743,7 +1744,9 @@ export default class StatementParser extends ExpressionParser { parseClassStaticBlock( classBody: N.ClassBody, - member: N.StaticBlock & { decorators?: Array }, + member: N.StaticBlock & { + decorators?: Array; + }, ) { // Start a new lexical scope this.scope.enter(SCOPE_CLASS | SCOPE_STATIC_BLOCK | SCOPE_SUPER); @@ -1798,7 +1801,7 @@ export default class StatementParser extends ExpressionParser { ) { if (!isPrivate && !prop.computed) { // Not private, so not node is not a PrivateName and we can safely cast - const key = (prop.key: N.Expression); + const key = prop.key as N.Expression; if (key.name === "constructor" || key.value === "constructor") { // Non-computed field, which is either an identifier named "constructor" @@ -1927,7 +1930,7 @@ export default class StatementParser extends ExpressionParser { parseClassId( node: N.Class, isStatement: boolean, - optionalId: ?boolean, + optionalId?: boolean | null, bindingType: BindingTypes = BIND_CLASS, ): void { if (tokenIsIdentifier(this.state.type)) { @@ -2123,7 +2126,9 @@ export default class StatementParser extends ExpressionParser { } // eslint-disable-next-line no-unused-vars - parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration { + parseExportDeclaration( + node: N.ExportNamedDeclaration, + ): N.Declaration | undefined | null { return this.parseStatement(null); } @@ -2228,7 +2233,7 @@ export default class StatementParser extends ExpressionParser { // Default exports this.checkDuplicateExports(node, "default"); if (this.hasPlugin("exportDefaultFrom")) { - const declaration = ((node: any): N.ExportDefaultDeclaration) + const declaration = (node as any as N.ExportDefaultDeclaration) .declaration; if ( declaration.type === "Identifier" && diff --git a/packages/babel-parser/src/parser/util.js b/packages/babel-parser/src/parser/util.ts similarity index 93% rename from packages/babel-parser/src/parser/util.js rename to packages/babel-parser/src/parser/util.ts index fbe51edefa16..6f53fc57b3c8 100644 --- a/packages/babel-parser/src/parser/util.js +++ b/packages/babel-parser/src/parser/util.ts @@ -1,5 +1,3 @@ -// @flow - import { type Position } from "../util/location"; import { tokenIsLiteralPropertyName, @@ -23,16 +21,17 @@ import { type ParseError, type ParseErrorConstructor, } from "../parse-error"; + /*:: import type ScopeHandler from "../util/scope"; */ type TryParse = { - node: Node, - error: Error, - thrown: Thrown, - aborted: Aborted, - failState: FailState, + node: Node; + error: Error; + thrown: Thrown; + aborted: Aborted; + failState: FailState; }; // ## Parser utilities @@ -149,20 +148,22 @@ export default class UtilParser extends Tokenizer { // Expect a token of a given type. If found, consume it, otherwise, // raise an unexpected token error at given pos. - expect(type: TokenType, loc?: ?Position): void { + expect(type: TokenType, loc?: Position | null): void { this.eat(type) || this.unexpected(loc, type); } // tryParse will clone parser state. // It is expensive and should be used with cautions - tryParse>( - fn: (abort: (node?: T) => empty) => T, + tryParse>( + fn: (abort: (node?: T) => never) => T, oldState: State = this.state.clone(), ): | TryParse | TryParse, boolean, false, State> | TryParse { - const abortSignal: { node: T | null } = { node: null }; + const abortSignal: { + node: T | null; + } = { node: null }; try { const node = fn((node = null) => { abortSignal.node = node; @@ -177,7 +178,7 @@ export default class UtilParser extends Tokenizer { this.state.tokensLength = failState.tokensLength; return { node, - error: (failState.errors[oldState.errors.length]: ParseError), + error: failState.errors[oldState.errors.length] as ParseError, thrown: false, aborted: false, failState, @@ -212,7 +213,7 @@ export default class UtilParser extends Tokenizer { } checkExpressionErrors( - refExpressionErrors: ?ExpressionErrors, + refExpressionErrors: ExpressionErrors | undefined | null, andThrow: boolean, ) { if (!refExpressionErrors) return false; @@ -382,8 +383,8 @@ export default class UtilParser extends Tokenizer { * It's only used by typescript and flow plugins */ export class ExpressionErrors { - shorthandAssignLoc: ?Position = null; - doubleProtoLoc: ?Position = null; - privateKeyLoc: ?Position = null; - optionalParametersLoc: ?Position = null; + shorthandAssignLoc: Position | undefined | null = null; + doubleProtoLoc: Position | undefined | null = null; + privateKeyLoc: Position | undefined | null = null; + optionalParametersLoc: Position | undefined | null = null; } diff --git a/packages/babel-parser/src/plugin-utils.js b/packages/babel-parser/src/plugin-utils.ts similarity index 96% rename from packages/babel-parser/src/plugin-utils.js rename to packages/babel-parser/src/plugin-utils.ts index f663d5552e2d..d36d691268ae 100644 --- a/packages/babel-parser/src/plugin-utils.js +++ b/packages/babel-parser/src/plugin-utils.ts @@ -1,13 +1,13 @@ -// @flow - import type Parser from "./parser"; import type { PluginConfig } from "./parser/base"; export type Plugin = PluginConfig; -export type PluginList = $ReadOnlyArray; +export type PluginList = ReadonlyArray; -export type MixinPlugin = (superClass: Class) => Class; +export type MixinPlugin = (superClass: { new (...args: any): Parser }) => { + new (...args: any): Parser; +}; // This function’s second parameter accepts either a string (plugin name) or an // array pair (plugin name and options object). If an options object is given, @@ -218,7 +218,9 @@ import placeholders from "./plugins/placeholders"; import v8intrinsic from "./plugins/v8intrinsic"; // NOTE: order is important. estree must come first; placeholders must come last. -export const mixinPlugins: { [name: string]: MixinPlugin } = { +export const mixinPlugins: { + [name: string]: MixinPlugin; +} = { estree, jsx, flow, @@ -227,5 +229,5 @@ export const mixinPlugins: { [name: string]: MixinPlugin } = { placeholders, }; -export const mixinPluginNames: $ReadOnlyArray = +export const mixinPluginNames: ReadonlyArray = Object.keys(mixinPlugins); diff --git a/packages/babel-parser/src/plugins/estree.js b/packages/babel-parser/src/plugins/estree.ts similarity index 85% rename from packages/babel-parser/src/plugins/estree.js rename to packages/babel-parser/src/plugins/estree.ts index 286218741487..9d614d114d86 100644 --- a/packages/babel-parser/src/plugins/estree.js +++ b/packages/babel-parser/src/plugins/estree.ts @@ -1,5 +1,3 @@ -// @flow - import { type TokenType } from "../tokenizer/types"; import type Parser from "../parser"; import type { ExpressionErrors } from "../parser/util"; @@ -19,7 +17,11 @@ function toESTreeLocation(node: any) { return node; } -export default (superClass: Class): Class => +export default (superClass: { + new (...args: any): Parser; +}): { + new (...args: any): Parser; +} => class extends superClass { parse(): File { const file = toESTreeLocation(super.parse()); @@ -70,7 +72,7 @@ export default (superClass: Class): Class => return node; } - estreeParseLiteral(value: any) { + estreeParseLiteral(value: any) { return this.parseLiteral(value, "Literal"); } @@ -118,7 +120,7 @@ export default (superClass: Class): Class => initFunction( node: N.BodilessFunctionOrMethodBase, - isAsync: ?boolean, + isAsync?: boolean | null, ): void { super.initFunction(node, isAsync); node.expression = false; @@ -126,15 +128,15 @@ export default (superClass: Class): Class => checkDeclaration(node: N.Pattern | N.ObjectProperty): void { if (node != null && this.isObjectProperty(node)) { - this.checkDeclaration(((node: any): N.EstreeProperty).value); + this.checkDeclaration((node as any as N.EstreeProperty).value); } else { super.checkDeclaration(node); } } getObjectOrClassMethodParams(method: N.ObjectMethod | N.ClassMethod) { - return ((method: any): N.EstreeProperty | N.EstreeMethodDefinition).value - .params; + return (method as any as N.EstreeProperty | N.EstreeMethodDefinition) + .value.params; } isValidDirective(stmt: N.Statement): boolean { @@ -148,7 +150,12 @@ export default (superClass: Class): Class => parseBlockBody( node: N.BlockStatementLike, - ...args: [?boolean, boolean, TokenType, void | (boolean => void)] + ...args: [ + boolean | undefined | null, + boolean, + TokenType, + void | ((a: boolean) => void), + ] ): void { super.parseBlockBody(node, ...args); @@ -199,7 +206,7 @@ export default (superClass: Class): Class => node: N.PrivateName, ): N.EstreePrivateIdentifier { const name = super.getPrivateNameSV(node); - node = (node: any); + node = node as any; delete node.id; node.name = name; node.type = "PrivateIdentifier"; @@ -224,7 +231,7 @@ export default (superClass: Class): Class => return node.name; } - parseLiteral(value: any, type: $ElementType): T { + parseLiteral(value: any, type: T["type"]): T { const node = super.parseLiteral(value, type); node.raw = node.extra.raw; delete node.extra; @@ -234,14 +241,14 @@ export default (superClass: Class): Class => parseFunctionBody( node: N.Function, - allowExpression: ?boolean, - isMethod?: boolean = false, + allowExpression?: boolean | null, + isMethod: boolean = false, ): void { super.parseFunctionBody(node, allowExpression, isMethod); node.expression = node.body.type !== "BlockStatement"; } - parseMethod( + parseMethod( node: T, isGenerator: boolean, isAsync: boolean, @@ -274,26 +281,26 @@ export default (superClass: Class): Class => } parseClassProperty(...args: [N.ClassProperty]): any { - const propertyNode = (super.parseClassProperty(...args): any); + const propertyNode = super.parseClassProperty(...args) as any; if (!process.env.BABEL_8_BREAKING) { if (!this.getPluginOption("estree", "classFeatures")) { - return (propertyNode: N.EstreePropertyDefinition); + return propertyNode as N.EstreePropertyDefinition; } } propertyNode.type = "PropertyDefinition"; - return (propertyNode: N.EstreePropertyDefinition); + return propertyNode as N.EstreePropertyDefinition; } parseClassPrivateProperty(...args: [N.ClassPrivateProperty]): any { - const propertyNode = (super.parseClassPrivateProperty(...args): any); + const propertyNode = super.parseClassPrivateProperty(...args) as any; if (!process.env.BABEL_8_BREAKING) { if (!this.getPluginOption("estree", "classFeatures")) { - return (propertyNode: N.EstreePropertyDefinition); + return propertyNode as N.EstreePropertyDefinition; } } propertyNode.type = "PropertyDefinition"; propertyNode.computed = false; - return (propertyNode: N.EstreePropertyDefinition); + return propertyNode as N.EstreePropertyDefinition; } parseObjectMethod( @@ -302,45 +309,47 @@ export default (superClass: Class): Class => isAsync: boolean, isPattern: boolean, isAccessor: boolean, - ): ?N.ObjectMethod { - const node: N.EstreeProperty = (super.parseObjectMethod( + ): N.ObjectMethod | undefined | null { + const node: N.EstreeProperty = super.parseObjectMethod( prop, isGenerator, isAsync, isPattern, isAccessor, - ): any); + ) as any; if (node) { node.type = "Property"; - if (((node: any): N.ClassMethod).kind === "method") node.kind = "init"; + if ((node as any as N.ClassMethod).kind === "method") { + node.kind = "init"; + } node.shorthand = false; } - return (node: any); + return node as any; } parseObjectProperty( prop: N.ObjectProperty, - startPos: ?number, - startLoc: ?Position, + startPos: number | undefined | null, + startLoc: Position | undefined | null, isPattern: boolean, - refExpressionErrors: ?ExpressionErrors, - ): ?N.ObjectProperty { - const node: N.EstreeProperty = (super.parseObjectProperty( + refExpressionErrors?: ExpressionErrors | null, + ): N.ObjectProperty | undefined | null { + const node: N.EstreeProperty = super.parseObjectProperty( prop, startPos, startLoc, isPattern, refExpressionErrors, - ): any); + ) as any; if (node) { node.kind = "init"; node.type = "Property"; } - return (node: any); + return node as any; } isValidLVal(type: string, ...rest) { @@ -379,17 +388,17 @@ export default (superClass: Class): Class => } } - finishCallExpression( + finishCallExpression( node: T, optional: boolean, ): N.Expression { super.finishCallExpression(node, optional); if (node.callee.type === "Import") { - ((node: N.Node): N.EstreeImportExpression).type = "ImportExpression"; - ((node: N.Node): N.EstreeImportExpression).source = node.arguments[0]; + (node as N.Node as N.EstreeImportExpression).type = "ImportExpression"; + (node as N.Node as N.EstreeImportExpression).source = node.arguments[0]; if (this.hasPlugin("importAssertions")) { - ((node: N.Node): N.EstreeImportExpression).attributes = + (node as N.Node as N.EstreeImportExpression).attributes = node.arguments[1] ?? null; } // $FlowIgnore - arguments isn't optional in the type definition @@ -444,7 +453,7 @@ export default (superClass: Class): Class => base: N.Expression, startPos: number, startLoc: Position, - noCalls: ?boolean, + noCalls: boolean | undefined | null, state: N.ParseSubscriptState, ) { const node = super.parseSubscript( @@ -497,7 +506,11 @@ export default (superClass: Class): Class => return node.method || node.kind === "get" || node.kind === "set"; } - finishNodeAt(node: T, type: string, endLoc: Position): T { + finishNodeAt( + node: T, + type: string, + endLoc: Position, + ): T { return toESTreeLocation(super.finishNodeAt(node, type, endLoc)); } @@ -508,7 +521,7 @@ export default (superClass: Class): Class => resetEndLocation( node: NodeBase, - endLoc?: Position = this.state.lastTokEndLoc, + endLoc: Position = this.state.lastTokEndLoc, ): void { super.resetEndLocation(node, endLoc); toESTreeLocation(node); diff --git a/packages/babel-parser/src/plugins/flow/index.js b/packages/babel-parser/src/plugins/flow/index.ts similarity index 94% rename from packages/babel-parser/src/plugins/flow/index.js rename to packages/babel-parser/src/plugins/flow/index.ts index 9cc648fe0fe9..b8cfc816d737 100644 --- a/packages/babel-parser/src/plugins/flow/index.js +++ b/packages/babel-parser/src/plugins/flow/index.ts @@ -1,5 +1,3 @@ -// @flow - /*:: declare var invariant; */ import type Parser from "../../parser"; @@ -62,9 +60,9 @@ const FlowErrors = ParseErrorEnum`flow`(_ => ({ ), // TODO: When we get proper string enums in typescript make this ReservedType. // Not really worth it to do the whole $Values dance with reservedTypes set. - AssignReservedType: _<{| reservedType: string |}>( - ({ reservedType }) => `Cannot overwrite reserved type ${reservedType}.`, - ), + AssignReservedType: _<{ + reservedType: string; + }>(({ reservedType }) => `Cannot overwrite reserved type ${reservedType}.`), DeclareClassElement: _( "The `declare` modifier can only appear on class fields.", ), @@ -74,26 +72,36 @@ const FlowErrors = ParseErrorEnum`flow`(_ => ({ DuplicateDeclareModuleExports: _( "Duplicate `declare module.exports` statement.", ), - EnumBooleanMemberNotInitialized: _<{| - memberName: string, - enumName: string, - |}>( + EnumBooleanMemberNotInitialized: _<{ + memberName: string; + enumName: string; + }>( ({ memberName, enumName }) => `Boolean enum members need to be initialized. Use either \`${memberName} = true,\` or \`${memberName} = false,\` in enum \`${enumName}\`.`, ), - EnumDuplicateMemberName: _<{| memberName: string, enumName: string |}>( + EnumDuplicateMemberName: _<{ + memberName: string; + enumName: string; + }>( ({ memberName, enumName }) => `Enum member names need to be unique, but the name \`${memberName}\` has already been used before in enum \`${enumName}\`.`, ), - EnumInconsistentMemberValues: _<{| enumName: string |}>( + EnumInconsistentMemberValues: _<{ + enumName: string; + }>( ({ 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: string, enumName: string |}>( + EnumInvalidExplicitType: _<{ + invalidEnumType: string; + enumName: string; + }>( ({ invalidEnumType, enumName }) => `Enum type \`${invalidEnumType}\` is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`, ), - EnumInvalidExplicitTypeUnknownSupplied: _<{| enumName: string |}>( + EnumInvalidExplicitTypeUnknownSupplied: _<{ + enumName: string; + }>( ({ enumName }) => `Supplied enum type is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`, ), @@ -109,47 +117,49 @@ const FlowErrors = ParseErrorEnum`flow`(_ => ({ // `EnumInvalidMemberInitializer` error that can accept `EnumExplicitType` // without alteration, and then just have its message change based on the // explicitType. - EnumInvalidMemberInitializerPrimaryType: _<{| - enumName: string, - memberName: string, - explicitType: EnumExplicitType, - |}>( + EnumInvalidMemberInitializerPrimaryType: _<{ + enumName: string; + memberName: string; + explicitType: EnumExplicitType; + }>( ({ enumName, memberName, explicitType }) => // $FlowIgnore (coercing null which never actually happens) `Enum \`${enumName}\` has type \`${explicitType}\`, so the initializer of \`${memberName}\` needs to be a ${explicitType} literal.`, ), - EnumInvalidMemberInitializerSymbolType: _<{| - enumName: string, - memberName: string, - explicitType: EnumExplicitType, - |}>( + EnumInvalidMemberInitializerSymbolType: _<{ + enumName: string; + memberName: string; + explicitType: EnumExplicitType; + }>( ({ enumName, memberName }) => `Symbol enum members cannot be initialized. Use \`${memberName},\` in enum \`${enumName}\`.`, ), - EnumInvalidMemberInitializerUnknownType: _<{| - enumName: string, - memberName: string, - explicitType: EnumExplicitType, - |}>( + EnumInvalidMemberInitializerUnknownType: _<{ + enumName: string; + memberName: string; + explicitType: EnumExplicitType; + }>( ({ enumName, memberName }) => `The enum member initializer for \`${memberName}\` needs to be a literal (either a boolean, number, or string) in enum \`${enumName}\`.`, ), - EnumInvalidMemberName: _<{| - enumName: string, - memberName: string, - suggestion: string, - |}>( + EnumInvalidMemberName: _<{ + enumName: string; + memberName: string; + suggestion: string; + }>( ({ 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: string, - memberName: string, - |}>( + EnumNumberMemberNotInitialized: _<{ + enumName: string; + memberName: string; + }>( ({ enumName, memberName }) => `Number enum members need to be initialized, e.g. \`${memberName} = 1\` in enum \`${enumName}\`.`, ), - EnumStringMemberInconsistentlyInitailized: _<{| enumName: string |}>( + EnumStringMemberInconsistentlyInitailized: _<{ + enumName: string; + }>( ({ enumName }) => `String enum members need to consistently either all use initializers, or use no initializers, in enum \`${enumName}\`.`, ), @@ -205,9 +215,9 @@ const FlowErrors = ParseErrorEnum`flow`(_ => ({ UnexpectedExplicitInexactInObject: _( "Explicit inexact syntax must appear at the end of an inexact object.", ), - UnexpectedReservedType: _<{| reservedType: string |}>( - ({ reservedType }) => `Unexpected reserved type ${reservedType}.`, - ), + UnexpectedReservedType: _<{ + reservedType: string; + }>(({ reservedType }) => `Unexpected reserved type ${reservedType}.`), UnexpectedReservedUnderscore: _( "`_` is only allowed as a type argument to call or new.", ), @@ -226,10 +236,10 @@ const FlowErrors = ParseErrorEnum`flow`(_ => ({ UnexpectedTypeParameterBeforeAsyncArrowFunction: _( "Type parameters must come after the async keyword, e.g. instead of ` async () => {}`, use `async () => {}`.", ), - UnsupportedDeclareExportKind: _<{| - unsupportedExportKind: string, - suggestion: string, - |}>( + UnsupportedDeclareExportKind: _<{ + unsupportedExportKind: string; + suggestion: string; + }>( ({ unsupportedExportKind, suggestion }) => `\`declare export ${unsupportedExportKind}\` is not supported. Use \`${suggestion}\` instead.`, ), @@ -268,7 +278,7 @@ const exportSuggestions = { // Like Array#filter, but returns a tuple [ acceptedElements, discardedElements ] function partition( list: T[], - test: (T, number, T[]) => ?boolean, + test: (c: T, b: number, a: T[]) => boolean | undefined | null, ): [T[], T[]] { const list1 = []; const list2 = []; @@ -282,26 +292,52 @@ const FLOW_PRAGMA_REGEX = /\*?\s*@((?:no)?flow)\b/; // Flow enums types type EnumExplicitType = null | "boolean" | "number" | "string" | "symbol"; -type EnumContext = {| - enumName: string, - explicitType: EnumExplicitType, - memberName: string, -|}; -type EnumMemberInit = - | {| type: "number", loc: Position, value: N.Node |} - | {| type: "string", loc: Position, value: N.Node |} - | {| type: "boolean", loc: Position, value: N.Node |} - | {| type: "invalid", loc: Position |} - | {| type: "none", loc: Position |}; -export default (superClass: Class): Class => +type EnumContext = { + enumName: string; + explicitType: EnumExplicitType; + memberName: string; +}; + +type EnumMemberInit = + | { + type: "number"; + loc: Position; + value: N.Node; + } + | { + type: "string"; + loc: Position; + value: N.Node; + } + | { + type: "boolean"; + loc: Position; + value: N.Node; + } + | { + type: "invalid"; + loc: Position; + } + | { + type: "none"; + loc: Position; + }; + +export default (superClass: { + new (...args: any): Parser; +}): { + new (...args: any): Parser; +} => class extends superClass { // The value of the @flow/@noflow pragma. Initially undefined, transitions // to "@flow" or "@noflow" if we see a pragma. Transitions to null if we are // past the initial comment. flowPragma: void | null | "flow" | "noflow" = undefined; - getScopeHandler(): Class { + getScopeHandler(): { + new (...args: any): FlowScopeHandler; + } { return FlowScopeHandler; } @@ -373,7 +409,10 @@ export default (superClass: Class): Class => } } - flowParseTypeAndPredicateInitialiser(): [?N.FlowType, ?N.FlowPredicate] { + flowParseTypeAndPredicateInitialiser(): [ + N.FlowType | undefined | null, + N.FlowPredicate | undefined | null, + ] { const oldInType = this.state.inType; this.state.inType = true; this.expect(tt.colon); @@ -566,7 +605,7 @@ export default (superClass: Class): Class => flowParseDeclareExportDeclaration( node: N.FlowDeclareExportDeclaration, - insideModule: ?boolean, + insideModule?: boolean | null, ): N.FlowDeclareExportDeclaration { this.expect(tt._export); @@ -676,10 +715,7 @@ export default (superClass: Class): Class => // Interfaces - flowParseInterfaceish( - node: N.FlowDeclare, - isClass?: boolean = false, - ): void { + flowParseInterfaceish(node: N.FlowDeclare, isClass: boolean = false): void { node.id = this.flowParseRestrictedIdentifier( /* liberal */ !isClass, /* declaration */ true, @@ -837,7 +873,7 @@ export default (superClass: Class): Class => // Type annotations - flowParseTypeParameter(requireDefault?: boolean = false): N.TypeParameter { + flowParseTypeParameter(requireDefault: boolean = false): N.TypeParameter { const nodeStartLoc = this.state.startLoc; const node = this.startNode(); @@ -973,7 +1009,7 @@ export default (superClass: Class): Class => flowParseObjectTypeIndexer( node: N.FlowObjectTypeIndexer, isStatic: boolean, - variance: ?N.FlowVariance, + variance?: N.FlowVariance | null, ): N.FlowObjectTypeIndexer { node.static = isStatic; @@ -1071,11 +1107,11 @@ export default (superClass: Class): Class => allowProto, allowInexact, }: { - allowStatic: boolean, - allowExact: boolean, - allowSpread: boolean, - allowProto: boolean, - allowInexact: boolean, + allowStatic: boolean; + allowExact: boolean; + allowSpread: boolean; + allowProto: boolean; + allowInexact: boolean; }): N.FlowObjectTypeAnnotation { const oldInType = this.state.inType; this.state.inType = true; @@ -1104,8 +1140,8 @@ export default (superClass: Class): Class => while (!this.match(endDelim)) { let isStatic = false; - let protoStartLoc: ?Position = null; - let inexactStartLoc: ?Position = null; + let protoStartLoc: Position | undefined | null = null; + let inexactStartLoc: Position | undefined | null = null; const node = this.startNode(); if (allowProto && this.isContextual(tt._proto)) { @@ -1219,12 +1255,12 @@ export default (superClass: Class): Class => flowParseObjectTypeProperty( node: N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty, isStatic: boolean, - protoStartLoc: ?Position, - variance: ?N.FlowVariance, + protoStartLoc: Position | undefined | null, + variance: N.FlowVariance | undefined | null, kind: string, allowSpread: boolean, allowInexact: boolean, - ): (N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty) | null { + ): N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty | null { if (this.eat(tt.ellipsis)) { const isInexactToken = this.match(tt.comma) || @@ -1455,12 +1491,12 @@ export default (superClass: Class): Class => } flowParseFunctionTypeParams(params: N.FlowFunctionTypeParam[] = []): { - params: N.FlowFunctionTypeParam[], - rest: ?N.FlowFunctionTypeParam, - _this: ?N.FlowFunctionTypeParam, + params: N.FlowFunctionTypeParam[]; + rest: N.FlowFunctionTypeParam | undefined | null; + _this: N.FlowFunctionTypeParam | undefined | null; } { - let rest: ?N.FlowFunctionTypeParam = null; - let _this: ?N.FlowFunctionTypeParam = null; + let rest: N.FlowFunctionTypeParam | undefined | null = null; + let _this: N.FlowFunctionTypeParam | undefined | null = null; if (this.match(tt._this)) { _this = this.flowParseFunctionTypeParam(/* first */ true); // match Flow parser behavior @@ -1852,7 +1888,7 @@ export default (superClass: Class): Class => return node.expression; } - flowParseVariance(): ?N.FlowVariance { + flowParseVariance(): N.FlowVariance | undefined | null { let variance = null; if (this.match(tt.plusMin)) { variance = this.startNode(); @@ -1873,8 +1909,8 @@ export default (superClass: Class): Class => parseFunctionBody( node: N.Function, - allowExpressionBody: ?boolean, - isMethod?: boolean = false, + allowExpressionBody?: boolean | null, + isMethod: boolean = false, ): void { if (allowExpressionBody) { return this.forwardNoArrowParamsConversionAt(node, () => @@ -1888,7 +1924,7 @@ export default (superClass: Class): Class => parseFunctionBodyAndFinish( node: N.BodilessFunctionOrMethodBase, type: string, - isMethod?: boolean = false, + isMethod: boolean = false, ): void { if (this.match(tt.colon)) { const typeNode = this.startNode(); @@ -1909,7 +1945,7 @@ export default (superClass: Class): Class => } // interfaces and enums - parseStatement(context: ?string, topLevel?: boolean): N.Statement { + parseStatement(context?: string | null, topLevel?: boolean): N.Statement { // strict mode handling of `interface` since it's a reserved word if (this.state.strict && this.isContextual(tt._interface)) { const lookahead = this.lookahead(); @@ -1998,7 +2034,7 @@ export default (superClass: Class): Class => expr: N.Expression, startPos: number, startLoc: Position, - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): N.Expression { if (!this.match(tt.question)) return expr; @@ -2075,8 +2111,8 @@ export default (superClass: Class): Class => } tryParseConditionalConsequent(): { - consequent: N.Expression, - failed: boolean, + consequent: N.Expression; + failed: boolean; } { this.state.noArrowParamsConversionAt.push(this.state.start); @@ -2132,7 +2168,7 @@ export default (superClass: Class): Class => this.toAssignableList( // node.params is Expression[] instead of $ReadOnlyArray because it // has not been converted yet. - ((node.params: any): N.Expression[]), + node.params as any as N.Expression[], node.extra?.trailingCommaLoc, /* isLHS */ false, ); @@ -2208,7 +2244,9 @@ export default (superClass: Class): Class => return decl; } - parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration { + parseExportDeclaration( + node: N.ExportNamedDeclaration, + ): N.Declaration | undefined | null { if (this.isContextual(tt._type)) { node.exportKind = "type"; @@ -2270,7 +2308,11 @@ export default (superClass: Class): Class => return hasNamespace; } - parseClassId(node: N.Class, isStatement: boolean, optionalId: ?boolean) { + parseClassId( + node: N.Class, + isStatement: boolean, + optionalId?: boolean | null, + ) { super.parseClassId(node, isStatement, optionalId); if (this.match(tt.lt)) { node.typeParameters = this.flowParseTypeParameterDeclaration(); @@ -2376,7 +2418,7 @@ export default (superClass: Class): Class => // turn type casts that we found in function parameter head into type annotated params toAssignableList( exprList: N.Expression[], - trailingCommaLoc?: ?Position, + trailingCommaLoc: Position | undefined | null, isLHS: boolean, ): void { for (let i = 0; i < exprList.length; i++) { @@ -2391,9 +2433,9 @@ export default (superClass: Class): Class => // this is a list of nodes, from something like a call expression, we need to filter the // type casts that we've found that are illegal in this context toReferencedList( - exprList: $ReadOnlyArray, + exprList: ReadonlyArray, isParenthesizedExpr?: boolean, - ): $ReadOnlyArray { + ): ReadonlyArray { for (let i = 0; i < exprList.length; i++) { const expr = exprList[i]; if ( @@ -2415,7 +2457,7 @@ export default (superClass: Class): Class => close: TokenType, canBePattern: boolean, isTuple: boolean, - refExpressionErrors: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): N.ArrayExpression | N.TupleExpression { const node = super.parseArrayLike( close, @@ -2480,10 +2522,10 @@ export default (superClass: Class): Class => isConstructor: boolean, allowsDirectSuper: boolean, ): void { - if ((method: $FlowFixMe).variance) { - this.unexpected((method: $FlowFixMe).variance.loc.start); + if ((method as any).variance) { + this.unexpected((method as any).variance.loc.start); } - delete (method: $FlowFixMe).variance; + delete (method as any).variance; if (this.match(tt.lt)) { method.typeParameters = this.flowParseTypeParameterDeclaration(); } @@ -2522,10 +2564,10 @@ export default (superClass: Class): Class => isGenerator: boolean, isAsync: boolean, ): void { - if ((method: $FlowFixMe).variance) { - this.unexpected((method: $FlowFixMe).variance.loc.start); + if ((method as any).variance) { + this.unexpected((method as any).variance.loc.start); } - delete (method: $FlowFixMe).variance; + delete (method as any).variance; if (this.match(tt.lt)) { method.typeParameters = this.flowParseTypeParameterDeclaration(); } @@ -2577,18 +2619,18 @@ export default (superClass: Class): Class => // parse type parameters for object method shorthand parseObjPropValue( prop: N.ObjectMember, - startPos: ?number, - startLoc: ?Position, + startPos: number | undefined | null, + startLoc: Position | undefined | null, isGenerator: boolean, isAsync: boolean, isPattern: boolean, isAccessor: boolean, - refExpressionErrors: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): void { - if ((prop: $FlowFixMe).variance) { - this.unexpected((prop: $FlowFixMe).variance.loc.start); + if ((prop as any).variance) { + this.unexpected((prop as any).variance.loc.start); } - delete (prop: $FlowFixMe).variance; + delete (prop as any).variance; let typeParameters; @@ -2624,7 +2666,7 @@ export default (superClass: Class): Class => this.raise(FlowErrors.ThisParamMayNotBeOptional, { at: param }); } - ((param: any): N.Identifier).optional = true; + (param as any as N.Identifier).optional = true; } if (this.match(tt.colon)) { param.typeAnnotation = this.flowParseTypeAnnotation(); @@ -2641,9 +2683,9 @@ export default (superClass: Class): Class => } parseMaybeDefault( - startPos?: ?number, - startLoc?: ?Position, - left?: ?N.Pattern, + startPos?: number | null, + startLoc?: Position | null, + left?: N.Pattern | null, ): N.Pattern { const node = super.parseMaybeDefault(startPos, startLoc, left); @@ -2872,7 +2914,7 @@ export default (superClass: Class): Class => // there // 3. This is neither. Just call the super method parseMaybeAssign( - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, afterLeftParse?: Function, ): N.Expression { let state = null; @@ -2943,10 +2985,11 @@ export default (superClass: Class): Class => return arrowExpression; }, state); - let arrowExpression: ?( + let arrowExpression: | N.ArrowFunctionExpression | N.TypeCastExpression - ) = null; + | undefined + | null = null; if ( arrow.node && @@ -3000,7 +3043,9 @@ export default (superClass: Class): Class => } // handle return types for arrow functions - parseArrow(node: N.ArrowFunctionExpression): ?N.ArrowFunctionExpression { + parseArrow( + node: N.ArrowFunctionExpression, + ): N.ArrowFunctionExpression | undefined | null { if (this.match(tt.colon)) { const result = this.tryParse(() => { const oldNoAnonFunctionType = this.state.noAnonFunctionType; @@ -3055,7 +3100,7 @@ export default (superClass: Class): Class => checkParams( node: N.Function, allowDuplicates: boolean, - isArrowFunction: ?boolean, + isArrowFunction?: boolean | null, ): void { if ( isArrowFunction && @@ -3084,7 +3129,7 @@ export default (superClass: Class): Class => base: N.Expression, startPos: number, startLoc: Position, - noCalls?: ?boolean, + noCalls?: boolean | null, ): N.Expression { if ( base.type === "Identifier" && @@ -3140,7 +3185,7 @@ export default (superClass: Class): Class => base: N.Expression, startPos: number, startLoc: Position, - noCalls: ?boolean, + noCalls: boolean | undefined | null, subscriptState: N.ParseSubscriptState, ): N.Expression { if (this.match(tt.questionDot) && this.isLookaheadToken_lt()) { @@ -3207,7 +3252,7 @@ export default (superClass: Class): Class => parseAsyncArrowWithTypeParameters( startPos: number, startLoc: Position, - ): ?N.ArrowFunctionExpression { + ): N.ArrowFunctionExpression | undefined | null { const node = this.startNodeAt(startPos, startLoc); this.parseFunctionParams(node); if (!this.parseArrow(node)) return; @@ -3329,7 +3374,13 @@ export default (superClass: Class): Class => flowEnumErrorBooleanMemberNotInitialized( loc: Position, - { enumName, memberName }: { enumName: string, memberName: string }, + { + enumName, + memberName, + }: { + enumName: string; + memberName: string; + }, ): void { this.raise(FlowErrors.EnumBooleanMemberNotInitialized, { at: loc, @@ -3357,7 +3408,13 @@ export default (superClass: Class): Class => flowEnumErrorNumberMemberNotInitialized( loc: Position, - { enumName, memberName }: { enumName: string, memberName: string }, + { + enumName, + memberName, + }: { + enumName: string; + memberName: string; + }, ): void { this.raise(FlowErrors.EnumNumberMemberNotInitialized, { at: loc, @@ -3368,7 +3425,11 @@ export default (superClass: Class): Class => flowEnumErrorStringMemberInconsistentlyInitailized( node: N.Node, - { enumName }: { enumName: string }, + { + enumName, + }: { + enumName: string; + }, ): void { this.raise(FlowErrors.EnumStringMemberInconsistentlyInitailized, { at: node, @@ -3411,7 +3472,10 @@ export default (superClass: Class): Class => } } - flowEnumMemberRaw(): { id: N.Node, init: EnumMemberInit } { + flowEnumMemberRaw(): { + id: N.Node; + init: EnumMemberInit; + } { const loc = this.state.startLoc; const id = this.parseIdentifier(true); const init = this.eat(tt.eq) @@ -3438,17 +3502,17 @@ export default (superClass: Class): Class => enumName, explicitType, }: { - enumName: string, - explicitType: EnumExplicitType, - }): {| - members: {| - booleanMembers: Array, - numberMembers: Array, - stringMembers: Array, - defaultedMembers: Array, - |}, - hasUnknownMembers: boolean, - |} { + enumName: string; + explicitType: EnumExplicitType; + }): { + members: { + booleanMembers: Array; + numberMembers: Array; + stringMembers: Array; + defaultedMembers: Array; + }; + hasUnknownMembers: boolean; + } { const seenNames = new Set(); const members = { booleanMembers: [], @@ -3547,7 +3611,11 @@ export default (superClass: Class): Class => flowEnumStringMembers( initializedMembers: Array, defaultedMembers: Array, - { enumName }: { enumName: string }, + { + enumName, + }: { + enumName: string; + }, ): Array { if (initializedMembers.length === 0) { return defaultedMembers; @@ -3573,7 +3641,7 @@ export default (superClass: Class): Class => flowEnumParseExplicitType({ enumName, }: { - enumName: string, + enumName: string; }): EnumExplicitType { if (!this.eatContextual(tt._of)) return null; diff --git a/packages/babel-parser/src/plugins/flow/scope.js b/packages/babel-parser/src/plugins/flow/scope.ts similarity index 99% rename from packages/babel-parser/src/plugins/flow/scope.js rename to packages/babel-parser/src/plugins/flow/scope.ts index 418276b59df0..7088d4499fc4 100644 --- a/packages/babel-parser/src/plugins/flow/scope.js +++ b/packages/babel-parser/src/plugins/flow/scope.ts @@ -1,5 +1,3 @@ -// @flow - import { Position } from "../../util/location"; import ScopeHandler, { Scope } from "../../util/scope"; import { diff --git a/packages/babel-parser/src/plugins/jsx/index.js b/packages/babel-parser/src/plugins/jsx/index.ts similarity index 98% rename from packages/babel-parser/src/plugins/jsx/index.js rename to packages/babel-parser/src/plugins/jsx/index.ts index f9c2bf9d6c62..1265eb33994e 100644 --- a/packages/babel-parser/src/plugins/jsx/index.js +++ b/packages/babel-parser/src/plugins/jsx/index.ts @@ -1,5 +1,3 @@ -// @flow - import * as charCodes from "charcodes"; import XHTMLEntities from "./xhtml"; @@ -24,7 +22,9 @@ const JsxErrors = ParseErrorEnum`jsx`(_ => ({ AttributeIsEmpty: _( "JSX attributes must only be assigned a non-empty expression.", ), - MissingClosingTagElement: _<{| openingTagName: string |}>( + MissingClosingTagElement: _<{ + openingTagName: string; + }>( ({ openingTagName }) => `Expected corresponding JSX closing tag for <${openingTagName}>.`, ), @@ -35,7 +35,10 @@ const JsxErrors = ParseErrorEnum`jsx`(_ => ({ "Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)?", ), // FIXME: Unify with Errors.UnexpectedToken - UnexpectedToken: _<{| unexpected: string, HTMLEntity: string |}>( + UnexpectedToken: _<{ + unexpected: string; + HTMLEntity: string; + }>( ({ unexpected, HTMLEntity }) => `Unexpected token \`${unexpected}\`. Did you mean \`${HTMLEntity}\` or \`{'${unexpected}'}\`?`, ), @@ -50,7 +53,7 @@ const JsxErrors = ParseErrorEnum`jsx`(_ => ({ /* eslint-disable sort-keys */ -function isFragment(object: ?N.JSXElement): boolean { +function isFragment(object?: N.JSXElement | null): boolean { return object ? object.type === "JSXOpeningFragment" || object.type === "JSXClosingFragment" @@ -82,7 +85,11 @@ function getQualifiedJSXName( throw new Error("Node had unexpected type: " + object.type); } -export default (superClass: Class): Class => +export default (superClass: { + new (...args: any): Parser; +}): { + new (...args: any): Parser; +} => class extends superClass { // Reads inline JSX contents token. @@ -567,7 +574,7 @@ export default (superClass: Class): Class => // Overrides // ================================== - parseExprAtom(refExpressionErrors: ?ExpressionErrors): N.Expression { + parseExprAtom(refExpressionErrors?: ExpressionErrors | null): N.Expression { if (this.match(tt.jsxText)) { return this.parseLiteral(this.state.value, "JSXText"); } else if (this.match(tt.jsxTagStart)) { diff --git a/packages/babel-parser/src/plugins/jsx/xhtml.js b/packages/babel-parser/src/plugins/jsx/xhtml.ts similarity index 98% rename from packages/babel-parser/src/plugins/jsx/xhtml.js rename to packages/babel-parser/src/plugins/jsx/xhtml.ts index 197665044343..d5f80397204e 100644 --- a/packages/babel-parser/src/plugins/jsx/xhtml.js +++ b/packages/babel-parser/src/plugins/jsx/xhtml.ts @@ -1,6 +1,7 @@ -// @flow - -const entities: { [name: string]: string, __proto__: null } = { +const entities: { + __proto__: null; + [name: string]: string; +} = { __proto__: null, quot: "\u0022", amp: "&", diff --git a/packages/babel-parser/src/plugins/placeholders.js b/packages/babel-parser/src/plugins/placeholders.ts similarity index 92% rename from packages/babel-parser/src/plugins/placeholders.js rename to packages/babel-parser/src/plugins/placeholders.ts index 805ff84b48be..2a22930af394 100644 --- a/packages/babel-parser/src/plugins/placeholders.js +++ b/packages/babel-parser/src/plugins/placeholders.ts @@ -1,5 +1,3 @@ -// @flow - import * as charCodes from "charcodes"; import { tokenLabelName, tt } from "../tokenizer/types"; @@ -7,6 +5,13 @@ import type Parser from "../parser"; import * as N from "../types"; import { ParseErrorEnum } from "../parse-error"; +type $Call1 any, A> = F extends ( + a: A, + ...args: any +) => infer R + ? R + : never; + export type PlaceholderTypes = | "Identifier" | "StringLiteral" @@ -20,15 +25,13 @@ export type PlaceholderTypes = // $PropertyType doesn't support enums. Use a fake "switch" (GetPlaceholderNode) //type MaybePlaceholder = $PropertyType | N.Placeholder; -type _Switch = $Call< - ( - $ElementType<$ElementType, 0>, - ) => $ElementType<$ElementType, 1>, - Value, +type _Switch = $Call1< + (a: Cases[Index][0]) => Cases[Index][1], + Value >; -type $Switch = _Switch; -type NodeOf = $Switch< +type $Switch = _Switch; +type NodeOf = $Switch< T, [ ["Identifier", N.Identifier], @@ -39,12 +42,12 @@ type NodeOf = $Switch< ["BlockStatement", N.BlockStatement], ["ClassBody", N.ClassBody], ["Pattern", N.Pattern], - ], + ] >; // Placeholder breaks everything, because its type is incompatible with // the substituted nodes. -type MaybePlaceholder = NodeOf; // | Placeholder +type MaybePlaceholder = NodeOf; // | Placeholder /* eslint sort-keys: "error" */ const PlaceholderErrors = ParseErrorEnum`placeholders`(_ => ({ @@ -53,11 +56,15 @@ const PlaceholderErrors = ParseErrorEnum`placeholders`(_ => ({ })); /* eslint-disable sort-keys */ -export default (superClass: Class): Class => +export default (superClass: { + new (...args: any): Parser; +}): { + new (...args: any): Parser; +} => class extends superClass { - parsePlaceholder( + parsePlaceholder( expectedNode: T, - ): /*?N.Placeholder*/ ?MaybePlaceholder { + ): /*?N.Placeholder*/ MaybePlaceholder | undefined | null { if (this.match(tt.placeholder)) { const node = this.startNode(); this.next(); @@ -73,7 +80,7 @@ export default (superClass: Class): Class => } } - finishPlaceholder( + finishPlaceholder( node: N.Node, expectedNode: T, ): /*N.Placeholder*/ MaybePlaceholder { @@ -156,7 +163,7 @@ export default (superClass: Class): Class => * parser/statement.js * * ============================================================ */ - isLet(context: ?string): boolean { + isLet(context?: string | null): boolean { if (super.isLet(context)) { return true; } @@ -215,14 +222,14 @@ export default (superClass: Class): Class => ); } - parseFunctionId(): ?MaybePlaceholder<"Identifier"> { + parseFunctionId(): MaybePlaceholder<"Identifier"> | undefined | null { return ( this.parsePlaceholder("Identifier") || super.parseFunctionId(...arguments) ); } - parseClass( + parseClass( node: T, isStatement: /* T === ClassDeclaration */ boolean, optionalId?: boolean, diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.ts similarity index 94% rename from packages/babel-parser/src/plugins/typescript/index.js rename to packages/babel-parser/src/plugins/typescript/index.ts index 90c117cc6637..c702d1c03b99 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.ts @@ -1,5 +1,3 @@ -// @flow - /*:: declare var invariant; */ import type State from "../../tokenizer/state"; @@ -51,7 +49,7 @@ type TsModifier = | N.Accessibility | N.VarianceAnnotations; -function nonNull(x: ?T): T { +function nonNull(x?: T | null): T { if (x == null) { // $FlowIgnore throw new Error(`Unexpected ${x} value.`); @@ -74,11 +72,15 @@ type ParsingContext = /* eslint sort-keys: "error" */ const TSErrors = ParseErrorEnum`typescript`(_ => ({ - AbstractMethodHasImplementation: _<{| methodName: string |}>( + AbstractMethodHasImplementation: _<{ + methodName: string; + }>( ({ methodName }) => `Method '${methodName}' cannot have an implementation because it is marked abstract.`, ), - AbstractPropertyHasInitializer: _<{| propertyName: string |}>( + AbstractPropertyHasInitializer: _<{ + propertyName: string; + }>( ({ propertyName }) => `Property '${propertyName}' cannot have an initializer because it is marked abstract.`, ), @@ -88,9 +90,9 @@ const TSErrors = ParseErrorEnum`typescript`(_ => ({ AccesorCannotHaveTypeParameters: _( "An accessor cannot have type parameters.", ), - CannotFindName: _<{| name: string |}>( - ({ name }) => `Cannot find name '${name}'.`, - ), + CannotFindName: _<{ + name: string; + }>(({ name }) => `Cannot find name '${name}'.`), ClassMethodHasDeclare: _("Class methods cannot have the 'declare' modifier."), ClassMethodHasReadonly: _( "Class methods cannot have the 'readonly' modifier.", @@ -101,42 +103,48 @@ const TSErrors = ParseErrorEnum`typescript`(_ => ({ ConstructorHasTypeParameters: _( "Type parameters cannot appear on a constructor declaration.", ), - DeclareAccessor: _<{| kind: "get" | "set" |}>( - ({ kind }) => `'declare' is not allowed in ${kind}ters.`, - ), + DeclareAccessor: _<{ + kind: "get" | "set"; + }>(({ kind }) => `'declare' is not allowed in ${kind}ters.`), DeclareClassFieldHasInitializer: _( "Initializers are not allowed in ambient contexts.", ), DeclareFunctionHasImplementation: _( "An implementation cannot be declared in ambient contexts.", ), - DuplicateAccessibilityModifier: _<{| modifier: N.Accessibility |}>( + DuplicateAccessibilityModifier: _<{ + modifier: N.Accessibility; + }>( // `Accessibility modifier already seen: ${modifier}` would be more helpful. // eslint-disable-next-line no-unused-vars ({ modifier }) => `Accessibility modifier already seen.`, ), - DuplicateModifier: _<{| modifier: TsModifier |}>( - ({ modifier }) => `Duplicate modifier: '${modifier}'.`, - ), + DuplicateModifier: _<{ + modifier: TsModifier; + }>(({ modifier }) => `Duplicate modifier: '${modifier}'.`), // `token` matches the terminology used by typescript: // https://github.com/microsoft/TypeScript/blob/main/src/compiler/types.ts#L2915 - EmptyHeritageClauseType: _<{| token: "extends" | "implements" |}>( - ({ token }) => `'${token}' list cannot be empty.`, - ), + EmptyHeritageClauseType: _<{ + token: "extends" | "implements"; + }>(({ token }) => `'${token}' list cannot be empty.`), EmptyTypeArguments: _("Type argument list cannot be empty."), EmptyTypeParameters: _("Type parameter list cannot be empty."), ExpectedAmbientAfterExportDeclare: _( "'export declare' must be followed by an ambient declaration.", ), ImportAliasHasImportType: _("An import alias can not use 'import type'."), - IncompatibleModifiers: _<{| modifiers: [TsModifier, TsModifier] |}>( + IncompatibleModifiers: _<{ + modifiers: [TsModifier, TsModifier]; + }>( ({ modifiers }) => `'${modifiers[0]}' modifier cannot be used with '${modifiers[1]}' modifier.`, ), IndexSignatureHasAbstract: _( "Index signatures cannot have the 'abstract' modifier.", ), - IndexSignatureHasAccessibility: _<{| modifier: N.Accessibility |}>( + IndexSignatureHasAccessibility: _<{ + modifier: N.Accessibility; + }>( ({ modifier }) => `Index signatures cannot have an accessibility modifier ('${modifier}').`, ), @@ -152,18 +160,26 @@ const TSErrors = ParseErrorEnum`typescript`(_ => ({ InitializerNotAllowedInAmbientContext: _( "Initializers are not allowed in ambient contexts.", ), - InvalidModifierOnTypeMember: _<{| modifier: TsModifier |}>( + InvalidModifierOnTypeMember: _<{ + modifier: TsModifier; + }>( ({ modifier }) => `'${modifier}' modifier cannot appear on a type member.`, ), - InvalidModifierOnTypeParameter: _<{| modifier: TsModifier |}>( + InvalidModifierOnTypeParameter: _<{ + modifier: TsModifier; + }>( ({ modifier }) => `'${modifier}' modifier cannot appear on a type parameter.`, ), - InvalidModifierOnTypeParameterPositions: _<{| modifier: TsModifier |}>( + InvalidModifierOnTypeParameterPositions: _<{ + modifier: TsModifier; + }>( ({ modifier }) => `'${modifier}' modifier can only appear on a type parameter of a class, interface or type alias.`, ), - InvalidModifiersOrder: _<{| orderedModifiers: [TsModifier, TsModifier] |}>( + InvalidModifiersOrder: _<{ + orderedModifiers: [TsModifier, TsModifier]; + }>( ({ orderedModifiers }) => `'${orderedModifiers[0]}' modifier must precede '${orderedModifiers[1]}' modifier.`, ), @@ -198,7 +214,9 @@ const TSErrors = ParseErrorEnum`typescript`(_ => ({ PrivateElementHasAbstract: _( "Private elements cannot have the 'abstract' modifier.", ), - PrivateElementHasAccessibility: _<{| modifier: N.Accessibility |}>( + PrivateElementHasAccessibility: _<{ + modifier: N.Accessibility; + }>( ({ modifier }) => `Private elements cannot have an accessibility modifier ('${modifier}').`, ), @@ -220,7 +238,9 @@ const TSErrors = ParseErrorEnum`typescript`(_ => ({ SetAccesorCannotHaveReturnType: _( "A 'set' accessor cannot have a return type annotation.", ), - SingleTypeParameterWithoutTrailingComma: _<{| typeParameterName: string |}>( + SingleTypeParameterWithoutTrailingComma: _<{ + typeParameterName: string; + }>( ({ typeParameterName }) => `Single type parameter ${typeParameterName} should have a trailing comma. Example usage: <${typeParameterName},>.`, ), @@ -255,7 +275,9 @@ const TSErrors = ParseErrorEnum`typescript`(_ => ({ UnsupportedParameterPropertyKind: _( "A parameter property may not be declared using a binding pattern.", ), - UnsupportedSignatureParameterKind: _<{| type: string |}>( + UnsupportedSignatureParameterKind: _<{ + type: string; + }>( ({ type }) => `Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got ${type}.`, ), @@ -294,19 +316,25 @@ function keywordTypeFromName( } } -function tsIsAccessModifier(modifier: string): boolean %checks { +function tsIsAccessModifier(modifier: string): boolean { return ( modifier === "private" || modifier === "public" || modifier === "protected" ); } -function tsIsVarianceAnnotations(modifier: string): boolean %checks { +function tsIsVarianceAnnotations(modifier: string): boolean { return modifier === "in" || modifier === "out"; } -export default (superClass: Class): Class => +export default (superClass: { + new (...args: any): Parser; +}): { + new (...args: any): Parser; +} => class extends superClass { - getScopeHandler(): Class { + getScopeHandler(): { + new (...args: any): TypeScriptScopeHandler; + } { return TypeScriptScopeHandler; } @@ -338,10 +366,10 @@ export default (superClass: Class): Class => } /** Parses a modifier matching one the given modifier names. */ - tsParseModifier( + tsParseModifier( allowedModifiers: T[], stopOnStartOfClassStaticBlock?: boolean, - ): ?T { + ): T | undefined | null { if (!tokenIsIdentifier(this.state.type) && this.state.type !== tt._in) { return undefined; } @@ -371,14 +399,14 @@ export default (superClass: Class): Class => errorTemplate = TSErrors.InvalidModifierOnTypeMember, }: { modified: { - [key: TsModifier]: ?true, - accessibility?: N.Accessibility, - }, - allowedModifiers: TsModifier[], - disallowedModifiers?: TsModifier[], - stopOnStartOfClassStaticBlock?: boolean, + accessibility?: N.Accessibility; + [key: TsModifier]: true | undefined | null; + }; + allowedModifiers: TsModifier[]; + disallowedModifiers?: TsModifier[]; + stopOnStartOfClassStaticBlock?: boolean; // FIXME: make sure errorTemplate can receive `modifier` - errorTemplate?: any, + errorTemplate?: any; }): void { const enforceOrder = (loc, modifier, before, after) => { if (modifier === before && modified[after]) { @@ -402,7 +430,7 @@ export default (superClass: Class): Class => for (;;) { const { startLoc } = this.state; - const modifier: ?TsModifier = this.tsParseModifier( + const modifier: TsModifier | undefined | null = this.tsParseModifier( allowedModifiers.concat(disallowedModifiers ?? []), stopOnStartOfClassStaticBlock, ); @@ -469,7 +497,10 @@ export default (superClass: Class): Class => throw new Error("Unreachable"); } - tsParseList(kind: ParsingContext, parseElement: () => T): T[] { + tsParseList( + kind: ParsingContext, + parseElement: () => T, + ): T[] { const result: T[] = []; while (!this.tsIsListTerminator(kind)) { // Skipping "parseListElement" from the TS source since that's just for error handling. @@ -478,10 +509,12 @@ export default (superClass: Class): Class => return result; } - tsParseDelimitedList( + tsParseDelimitedList( kind: ParsingContext, parseElement: () => T, - refTrailingCommaPos?: { value: number }, + refTrailingCommaPos?: { + value: number; + }, ): T[] { return nonNull( this.tsParseDelimitedListWorker( @@ -497,12 +530,14 @@ export default (superClass: Class): Class => * If !expectSuccess, returns undefined instead of failing to parse. * If expectSuccess, parseElement should always return a defined value. */ - tsParseDelimitedListWorker( + tsParseDelimitedListWorker( kind: ParsingContext, - parseElement: () => ?T, + parseElement: () => T | undefined | null, expectSuccess: boolean, - refTrailingCommaPos?: { value: number }, - ): ?(T[]) { + refTrailingCommaPos?: { + value: number; + }, + ): T[] | undefined | null { const result = []; let trailingCommaPos = -1; @@ -541,12 +576,14 @@ export default (superClass: Class): Class => return result; } - tsParseBracketedList( + tsParseBracketedList( kind: ParsingContext, parseElement: () => T, bracket: boolean, skipFirstToken: boolean, - refTrailingCommaPos?: { value: number }, + refTrailingCommaPos?: { + value: number; + }, ): T[] { if (!skipFirstToken) { if (bracket) { @@ -688,14 +725,16 @@ export default (superClass: Class): Class => } tsTryParseTypeParameters( - parseModifiers: ?(node: N.TsTypeParameter) => void, - ): ?N.TsTypeParameterDeclaration { + parseModifiers?: ((node: N.TsTypeParameter) => void) | null, + ): N.TsTypeParameterDeclaration | undefined | null { if (this.match(tt.lt)) { return this.tsParseTypeParameters(parseModifiers); } } - tsParseTypeParameters(parseModifiers: ?(node: N.TsTypeParameter) => void) { + tsParseTypeParameters( + parseModifiers?: ((node: N.TsTypeParameter) => void) | null, + ) { const node: N.TsTypeParameterDeclaration = this.startNode(); if (this.match(tt.lt) || this.match(tt.jsxTagStart)) { @@ -722,7 +761,7 @@ export default (superClass: Class): Class => return this.finishNode(node, "TSTypeParameterDeclaration"); } - tsTryNextParseConstantContext(): ?N.TsTypeReference { + tsTryNextParseConstantContext(): N.TsTypeReference | undefined | null { if (this.lookahead().type !== tt._const) return null; this.next(); @@ -769,8 +808,8 @@ export default (superClass: Class): Class => } } - tsParseBindingListForSignature(): $ReadOnlyArray< - N.Identifier | N.RestElement | N.ObjectPattern | N.ArrayPattern, + tsParseBindingListForSignature(): ReadonlyArray< + N.Identifier | N.RestElement | N.ObjectPattern | N.ArrayPattern > { return this.parseBindingList(tt.parenR, charCodes.rightParenthesis).map( pattern => { @@ -785,7 +824,7 @@ export default (superClass: Class): Class => type: pattern.type, }); } - return (pattern: any); + return pattern as any; }, ); } @@ -814,7 +853,9 @@ export default (superClass: Class): Class => return false; } - tsTryParseIndexSignature(node: N.Node): ?N.TsIndexSignature { + tsTryParseIndexSignature( + node: N.Node, + ): N.TsIndexSignature | undefined | null { if ( !( this.match(tt.bracketL) && @@ -974,7 +1015,7 @@ export default (superClass: Class): Class => return this.finishNode(node, "TSTypeLiteral"); } - tsParseObjectTypeMembers(): $ReadOnlyArray { + tsParseObjectTypeMembers(): ReadonlyArray { this.expect(tt.braceL); const members = this.tsParseList( "TypeMembers", @@ -1115,7 +1156,7 @@ export default (superClass: Class): Class => !type.typeParameters && type.typeName.type === "Identifier" ) { - labeledNode.label = (type.typeName: N.Identifier); + labeledNode.label = type.typeName as N.Identifier; } else { this.raise(TSErrors.InvalidTupleMemberLabel, { at: type }); // This produces an invalid AST, but at least we don't drop @@ -1495,13 +1536,13 @@ export default (superClass: Class): Class => // if it turns out to be a `TSThisType`, wrap it with `TSTypePredicate` // : asserts this if (thisTypePredicate.type === "TSThisType") { - node.parameterName = (thisTypePredicate: N.TsThisType); + node.parameterName = thisTypePredicate as N.TsThisType; node.asserts = true; - (node: N.TsTypePredicate).typeAnnotation = null; + (node as N.TsTypePredicate).typeAnnotation = null; thisTypePredicate = this.finishNode(node, "TSTypePredicate"); } else { this.resetStartLocationFromNode(thisTypePredicate, node); - (thisTypePredicate: N.TsTypePredicate).asserts = true; + (thisTypePredicate as N.TsTypePredicate).asserts = true; } t.typeAnnotation = thisTypePredicate; return this.finishNode(t, "TSTypeAnnotation"); @@ -1520,7 +1561,7 @@ export default (superClass: Class): Class => // : asserts foo node.parameterName = this.parseIdentifier(); node.asserts = asserts; - (node: N.TsTypePredicate).typeAnnotation = null; + (node as N.TsTypePredicate).typeAnnotation = null; t.typeAnnotation = this.finishNode(node, "TSTypePredicate"); return this.finishNode(t, "TSTypeAnnotation"); } @@ -1535,21 +1576,24 @@ export default (superClass: Class): Class => }); } - tsTryParseTypeOrTypePredicateAnnotation(): ?N.TsTypeAnnotation { + tsTryParseTypeOrTypePredicateAnnotation(): + | N.TsTypeAnnotation + | undefined + | null { return this.match(tt.colon) ? this.tsParseTypeOrTypePredicateAnnotation(tt.colon) : undefined; } - tsTryParseTypeAnnotation(): ?N.TsTypeAnnotation { + tsTryParseTypeAnnotation(): N.TsTypeAnnotation | undefined | null { return this.match(tt.colon) ? this.tsParseTypeAnnotation() : undefined; } - tsTryParseType(): ?N.TsType { + tsTryParseType(): N.TsType | undefined | null { return this.tsEatThenParseType(tt.colon); } - tsParseTypePredicatePrefix(): ?N.Identifier { + tsParseTypePredicatePrefix(): N.Identifier | undefined | null { const id = this.parseIdentifier(); if (this.isContextual(tt._is) && !this.hasPrecedingLineBreak()) { this.next(); @@ -1659,7 +1703,7 @@ export default (superClass: Class): Class => tsParseHeritageClause( token: "extends" | "implements", - ): $ReadOnlyArray { + ): ReadonlyArray { const originalStartLoc = this.state.startLoc; const delimitedList = this.tsParseDelimitedList( @@ -1687,8 +1731,10 @@ export default (superClass: Class): Class => tsParseInterfaceDeclaration( node: N.TsInterfaceDeclaration, - properties: { declare?: true } = {}, - ): ?N.TsInterfaceDeclaration { + properties: { + declare?: true; + } = {}, + ): N.TsInterfaceDeclaration | undefined | null { if (this.hasFollowingLineBreak()) return null; this.expectContextual(tt._interface); if (properties.declare) node.declare = true; @@ -1823,7 +1869,10 @@ export default (superClass: Class): Class => tsParseEnumDeclaration( node: N.TsEnumDeclaration, - properties: { const?: true, declare?: true } = {}, + properties: { + const?: true; + declare?: true; + } = {}, ): N.TsEnumDeclaration { if (properties.const) node.const = true; if (properties.declare) node.declare = true; @@ -1861,7 +1910,7 @@ export default (superClass: Class): Class => tsParseModuleOrNamespaceDeclaration( node: N.TsModuleDeclaration, - nested?: boolean = false, + nested: boolean = false, ): N.TsModuleDeclaration { node.id = this.parseIdentifier(); @@ -1964,7 +2013,9 @@ export default (superClass: Class): Class => return res; } - tsTryParseAndCatch(f: () => T): ?T { + tsTryParseAndCatch( + f: () => T, + ): T | undefined | null { const result = this.tryParse(abort => f() || abort()); if (result.aborted || !result.node) return undefined; @@ -1972,7 +2023,7 @@ export default (superClass: Class): Class => return result.node; } - tsTryParse(f: () => ?T): ?T { + tsTryParse(f: () => T | undefined | null): T | undefined | null { const state = this.state.clone(); const result = f(); if (result !== undefined && result !== false) { @@ -1983,7 +2034,7 @@ export default (superClass: Class): Class => } } - tsTryParseDeclare(nany: any): ?N.Declaration { + tsTryParseDeclare(nany: any): N.Declaration | undefined | null { if (this.isLineTerminator()) { return; } @@ -2056,7 +2107,7 @@ export default (superClass: Class): Class => } // Note: this won't be called unless the keyword is allowed in `shouldParseExportDeclaration`. - tsTryParseExportDeclaration(): ?N.Declaration { + tsTryParseExportDeclaration(): N.Declaration | undefined | null { return this.tsParseDeclaration( this.startNode(), this.state.value, @@ -2064,7 +2115,10 @@ export default (superClass: Class): Class => ); } - tsParseExpressionStatement(node: any, expr: N.Identifier): ?N.Declaration { + tsParseExpressionStatement( + node: any, + expr: N.Identifier, + ): N.Declaration | undefined | null { switch (expr.name) { case "declare": { const declaration = this.tsTryParseDeclare(node); @@ -2100,7 +2154,7 @@ export default (superClass: Class): Class => node: any, value: string, next: boolean, - ): ?N.Declaration { + ): N.Declaration | undefined | null { // no declaration apart from enum can be followed by a line break. switch (value) { case "abstract": @@ -2154,7 +2208,7 @@ export default (superClass: Class): Class => tsTryParseGenericAsyncArrowFunction( startPos: number, startLoc: Position, - ): ?N.ArrowFunctionExpression { + ): N.ArrowFunctionExpression | undefined | null { if (!this.match(tt.lt)) { return undefined; } @@ -2162,18 +2216,19 @@ export default (superClass: Class): Class => const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; this.state.maybeInArrowParameters = true; - const res: ?N.ArrowFunctionExpression = this.tsTryParseAndCatch(() => { - const node: N.ArrowFunctionExpression = this.startNodeAt( - startPos, - startLoc, - ); - node.typeParameters = this.tsParseTypeParameters(); - // Don't use overloaded parseFunctionParams which would look for "<" again. - super.parseFunctionParams(node); - node.returnType = this.tsTryParseTypeOrTypePredicateAnnotation(); - this.expect(tt.arrow); - return node; - }); + const res: N.ArrowFunctionExpression | undefined | null = + this.tsTryParseAndCatch(() => { + const node: N.ArrowFunctionExpression = this.startNodeAt( + startPos, + startLoc, + ); + node.typeParameters = this.tsParseTypeParameters(); + // Don't use overloaded parseFunctionParams which would look for "<" again. + super.parseFunctionParams(node); + node.returnType = this.tsTryParseTypeOrTypePredicateAnnotation(); + this.expect(tt.arrow); + return node; + }); this.state.maybeInArrowParameters = oldMaybeInArrowParameters; @@ -2230,14 +2285,14 @@ export default (superClass: Class): Class => } parseAssignableListItem( - allowModifiers: ?boolean, + allowModifiers: boolean | undefined | null, decorators: N.Decorator[], ): N.Pattern | N.TSParameterProperty { // Store original location/position to include modifiers in range const startPos = this.state.start; const startLoc = this.state.startLoc; - let accessibility: ?N.Accessibility; + let accessibility: N.Accessibility | undefined | null; let readonly = false; let override = false; if (allowModifiers !== undefined) { @@ -2277,7 +2332,7 @@ export default (superClass: Class): Class => if (elt.type !== "Identifier" && elt.type !== "AssignmentPattern") { this.raise(TSErrors.UnsupportedParameterPropertyKind, { at: pp }); } - pp.parameter = ((elt: any): N.Identifier | N.AssignmentPattern); + pp.parameter = elt as any as N.Identifier | N.AssignmentPattern; return this.finishNode(pp, "TSParameterProperty"); } @@ -2299,7 +2354,7 @@ export default (superClass: Class): Class => parseFunctionBodyAndFinish( node: N.BodilessFunctionOrMethodBase, type: string, - isMethod?: boolean = false, + isMethod: boolean = false, ): void { if (this.match(tt.colon)) { node.returnType = this.tsParseTypeOrTypePredicateAnnotation(tt.colon); @@ -2339,7 +2394,9 @@ export default (superClass: Class): Class => } } - tsCheckForInvalidTypeCasts(items: $ReadOnlyArray) { + tsCheckForInvalidTypeCasts( + items: ReadonlyArray, + ) { items.forEach(node => { if (node?.type === "TSTypeCastExpression") { this.raise(TSErrors.UnexpectedTypeAnnotation, { @@ -2350,9 +2407,10 @@ export default (superClass: Class): Class => } toReferencedList( - exprList: $ReadOnlyArray, - isInParens?: boolean, // eslint-disable-line no-unused-vars - ): $ReadOnlyArray { + exprList: ReadonlyArray, + // eslint-disable-line no-unused-vars + isInParens?: boolean, + ): ReadonlyArray { // Handles invalid scenarios like: `f(a:b)`, `(a:b);`, and `(a:b,c:d)`. // // Note that `f(a:b)` goes through a different path and is handled @@ -2375,7 +2433,7 @@ export default (superClass: Class): Class => base: N.Expression, startPos: number, startLoc: Position, - noCalls: ?boolean, + noCalls: boolean | undefined | null, state: N.ParseSubscriptState, ): N.Expression { if (!this.hasPrecedingLineBreak() && this.match(tt.bang)) { @@ -2741,7 +2799,10 @@ export default (superClass: Class): Class => return declaration; } - parseStatementContent(context: ?string, topLevel: ?boolean): N.Statement { + parseStatementContent( + context?: string | null, + topLevel?: boolean | null, + ): N.Statement { if (this.match(tt._const) && this.isLookaheadContextual("enum")) { const node: N.TsEnumDeclaration = this.startNode(); this.expect(tt._const); // eat 'const' @@ -2760,7 +2821,7 @@ export default (superClass: Class): Class => return super.parseStatementContent(context, topLevel); } - parseAccessModifier(): ?N.Accessibility { + parseAccessModifier(): N.Accessibility | undefined | null { return this.tsParseModifier(["public", "protected", "private"]); } @@ -2812,7 +2873,7 @@ export default (superClass: Class): Class => at: this.state.curPosition(), }); } - this.parseClassStaticBlock(classBody, ((member: any): N.StaticBlock)); + this.parseClassStaticBlock(classBody, member as any as N.StaticBlock); } else { this.parseClassMemberWithIsStatic( classBody, @@ -2839,32 +2900,32 @@ export default (superClass: Class): Class => if (idx) { classBody.body.push(idx); - if ((member: any).abstract) { + if ((member as any).abstract) { this.raise(TSErrors.IndexSignatureHasAbstract, { at: member }); } - if ((member: any).accessibility) { + if ((member as any).accessibility) { this.raise(TSErrors.IndexSignatureHasAccessibility, { at: member, - modifier: (member: any).accessibility, + modifier: (member as any).accessibility, }); } - if ((member: any).declare) { + if ((member as any).declare) { this.raise(TSErrors.IndexSignatureHasDeclare, { at: member }); } - if ((member: any).override) { + if ((member as any).override) { this.raise(TSErrors.IndexSignatureHasOverride, { at: member }); } return; } - if (!this.state.inAbstractClass && (member: any).abstract) { + if (!this.state.inAbstractClass && (member as any).abstract) { this.raise(TSErrors.NonAbstractClassHasAbstractMethod, { at: member, }); } - if ((member: any).override) { + if ((member as any).override) { if (!state.hadSuperClass) { this.raise(TSErrors.OverrideNotInSubClass, { at: member }); } @@ -2881,11 +2942,11 @@ export default (superClass: Class): Class => const optional = this.eat(tt.question); if (optional) methodOrProp.optional = true; - if ((methodOrProp: any).readonly && this.match(tt.parenL)) { + if ((methodOrProp as any).readonly && this.match(tt.parenL)) { this.raise(TSErrors.ClassMethodHasReadonly, { at: methodOrProp }); } - if ((methodOrProp: any).declare && this.match(tt.parenL)) { + if ((methodOrProp as any).declare && this.match(tt.parenL)) { this.raise(TSErrors.ClassMethodHasDeclare, { at: methodOrProp }); } } @@ -2917,7 +2978,7 @@ export default (superClass: Class): Class => expr: N.Expression, startPos: number, startLoc: Position, - refExpressionErrors?: ?ExpressionErrors, + refExpressionErrors?: ExpressionErrors | null, ): N.Expression { // only do the expensive clone if there is a question mark // and if we come from inside parens @@ -2976,7 +3037,9 @@ export default (superClass: Class): Class => return node; } - parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration { + parseExportDeclaration( + node: N.ExportNamedDeclaration, + ): N.Declaration | undefined | null { if (!this.state.isAmbientContext && this.isContextual(tt._declare)) { return this.tsInAmbientContext(() => this.parseExportDeclaration(node)); } @@ -2997,7 +3060,7 @@ export default (superClass: Class): Class => } const isIdentifier = tokenIsIdentifier(this.state.type); - const declaration: ?N.Declaration = + const declaration: N.Declaration | undefined | null = (isIdentifier && this.tsTryParseExportDeclaration()) || super.parseExportDeclaration(node); @@ -3024,7 +3087,7 @@ export default (superClass: Class): Class => parseClassId( node: N.Class, isStatement: boolean, - optionalId: ?boolean, + optionalId?: boolean | null, ): void { if ((!isStatement || optionalId) && this.isContextual(tt._implements)) { return; @@ -3034,7 +3097,7 @@ export default (superClass: Class): Class => node, isStatement, optionalId, - (node: any).declare ? BIND_TS_AMBIENT : BIND_CLASS, + (node as any).declare ? BIND_TS_AMBIENT : BIND_CLASS, ); const typeParameters = this.tsTryParseTypeParameters( this.tsParseInOutModifiers.bind(this), @@ -3208,7 +3271,7 @@ export default (superClass: Class): Class => parseMaybeAssign(...args): N.Expression { // Note: When the JSX plugin is on, type assertions (` x`) aren't valid syntax. - let state: ?State; + let state: State | undefined | null; let jsx; let typeCast; @@ -3246,7 +3309,7 @@ export default (superClass: Class): Class => // so we still need to clone it. if (!state || state === this.state) state = this.state.clone(); - let typeParameters: ?N.TsTypeParameterDeclaration; + let typeParameters: N.TsTypeParameterDeclaration | undefined | null; const arrow = this.tryParse(abort => { // This is similar to TypeScript's `tryParseParenthesizedArrowFunctionExpression`. typeParameters = this.tsParseTypeParameters(); @@ -3347,7 +3410,9 @@ export default (superClass: Class): Class => } // Handle type assertions - parseMaybeUnary(refExpressionErrors?: ?ExpressionErrors): N.Expression { + parseMaybeUnary( + refExpressionErrors?: ExpressionErrors | null, + ): N.Expression { if (!this.hasPlugin("jsx") && this.match(tt.lt)) { return this.tsParseTypeAssertion(); } else { @@ -3355,7 +3420,9 @@ export default (superClass: Class): Class => } } - parseArrow(node: N.ArrowFunctionExpression): ?N.ArrowFunctionExpression { + parseArrow( + node: N.ArrowFunctionExpression, + ): N.ArrowFunctionExpression | undefined | null { if (this.match(tt.colon)) { // This is different from how the TS parser does it. // TS uses lookahead. The Babel Parser parses it as a parenthesized expression and converts. @@ -3390,7 +3457,7 @@ export default (superClass: Class): Class => this.raise(TSErrors.PatternIsOptional, { at: param }); } - ((param: any): N.Identifier).optional = true; + (param as any as N.Identifier).optional = true; } const type = this.tsTryParseTypeAnnotation(); if (type) param.typeAnnotation = type; @@ -3673,9 +3740,9 @@ export default (superClass: Class): Class => } } - parseClass(node: T, ...args: any[]): T { + parseClass(node: T, ...args: any[]): T { const oldInAbstractClass = this.state.inAbstractClass; - this.state.inAbstractClass = !!(node: any).abstract; + this.state.inAbstractClass = !!(node as any).abstract; try { return super.parseClass(node, ...args); } finally { @@ -3685,11 +3752,11 @@ export default (superClass: Class): Class => tsParseAbstractDeclaration( node: any, - ): N.ClassDeclaration | ?N.TsInterfaceDeclaration { + ): N.ClassDeclaration | N.TsInterfaceDeclaration | undefined | null { if (this.match(tt._class)) { node.abstract = true; return this.parseClass( - (node: N.ClassDeclaration), + node as N.ClassDeclaration, /* isStatement */ true, /* optionalId */ false, ); @@ -3705,7 +3772,7 @@ export default (superClass: Class): Class => at: node, }); return this.tsParseInterfaceDeclaration( - (node: N.TsInterfaceDeclaration), + node as N.TsInterfaceDeclaration, ); } } else { diff --git a/packages/babel-parser/src/plugins/typescript/scope.js b/packages/babel-parser/src/plugins/typescript/scope.ts similarity index 99% rename from packages/babel-parser/src/plugins/typescript/scope.js rename to packages/babel-parser/src/plugins/typescript/scope.ts index 0019ac9cdf1c..360e1eaaa2b0 100644 --- a/packages/babel-parser/src/plugins/typescript/scope.js +++ b/packages/babel-parser/src/plugins/typescript/scope.ts @@ -1,5 +1,3 @@ -// @flow - import { Position } from "../../util/location"; import ScopeHandler, { Scope } from "../../util/scope"; import { diff --git a/packages/babel-parser/src/plugins/v8intrinsic.js b/packages/babel-parser/src/plugins/v8intrinsic.ts similarity index 91% rename from packages/babel-parser/src/plugins/v8intrinsic.js rename to packages/babel-parser/src/plugins/v8intrinsic.ts index 0d0c0ecbad6c..6d341ed8bda1 100644 --- a/packages/babel-parser/src/plugins/v8intrinsic.js +++ b/packages/babel-parser/src/plugins/v8intrinsic.ts @@ -2,7 +2,11 @@ import type Parser from "../parser"; import { tokenIsIdentifier, tt } from "../tokenizer/types"; import * as N from "../types"; -export default (superClass: Class): Class => +export default (superClass: { + new (...args: any): Parser; +}): { + new (...args: any): Parser; +} => class extends superClass { parseV8Intrinsic(): N.Expression { if (this.match(tt.modulo)) { diff --git a/packages/babel-parser/src/tokenizer/context.js b/packages/babel-parser/src/tokenizer/context.ts similarity index 94% rename from packages/babel-parser/src/tokenizer/context.js rename to packages/babel-parser/src/tokenizer/context.ts index f0b0c687a98a..4bb309c6a735 100644 --- a/packages/babel-parser/src/tokenizer/context.js +++ b/packages/babel-parser/src/tokenizer/context.ts @@ -1,5 +1,3 @@ -// @flow - // The token context is used in JSX plugin to track // jsx tag / jsx text / normal JavaScript expression @@ -14,7 +12,7 @@ export class TokContext { } const types: { - [key: string]: TokContext, + [key: string]: TokContext; } = { brace: new TokContext("{"), // normal JavaScript expression j_oTag: new TokContext("( toParseError: ParseErrorConstructor, raiseProperties: RaiseProperties, - ): ParseError | empty { + ): ParseError | never { const { at, ...details } = raiseProperties; const loc = at instanceof Position ? at : at.loc.start; const pos = loc.index; diff --git a/packages/babel-parser/src/tokenizer/state.js b/packages/babel-parser/src/tokenizer/state.ts similarity index 95% rename from packages/babel-parser/src/tokenizer/state.js rename to packages/babel-parser/src/tokenizer/state.ts index cd2c4dd7b66c..2aad851ef946 100644 --- a/packages/babel-parser/src/tokenizer/state.js +++ b/packages/babel-parser/src/tokenizer/state.ts @@ -1,5 +1,3 @@ -// @flow - import type { Options } from "../options"; import * as N from "../types"; import type { CommentWhitespace } from "../parser/comments"; @@ -17,13 +15,12 @@ type TopicContextState = { // When a topic binding has been currently established, // then this is 1. Otherwise, it is 0. This is forwards compatible // with a future plugin for multiple lexical topics. - maxNumOfResolvableTopics: number, - + maxNumOfResolvableTopics: number; // When a topic binding has been currently established, and if that binding // has been used as a topic reference `#`, then this is 0. Otherwise, it is // `null`. This is forwards compatible with a future plugin for multiple // lexical topics. - maxTopicIndex: null | 0, + maxTopicIndex: null | 0; }; export default class State { @@ -89,9 +86,9 @@ export default class State { // Labels in scope. labels: Array<{ - kind: ?("loop" | "switch"), - name?: ?string, - statementStart?: number, + kind: "loop" | "switch" | undefined | null; + name?: string | null; + statementStart?: number; }> = []; // Leading decorators. Last element of the stack represents the decorators in current context. @@ -175,11 +172,11 @@ export default class State { } export type LookaheadState = { - pos: number, - value: any, - type: TokenType, - start: number, - end: number, + pos: number; + value: any; + type: TokenType; + start: number; + end: number; /* Used only in readToken_mult_modulo */ - inType: boolean, + inType: boolean; }; diff --git a/packages/babel-parser/src/tokenizer/types.js b/packages/babel-parser/src/tokenizer/types.ts similarity index 97% rename from packages/babel-parser/src/tokenizer/types.js rename to packages/babel-parser/src/tokenizer/types.ts index 3f096156599f..7145dc4275ec 100644 --- a/packages/babel-parser/src/tokenizer/types.js +++ b/packages/babel-parser/src/tokenizer/types.ts @@ -1,4 +1,3 @@ -// @flow import { types as tc, type TokContext } from "./context"; // ## Token types @@ -30,26 +29,26 @@ const prefix = true; const postfix = true; type TokenOptions = { - keyword?: string, - beforeExpr?: boolean, - startsExpr?: boolean, - rightAssociative?: boolean, - isLoop?: boolean, - isAssign?: boolean, - prefix?: boolean, - postfix?: boolean, - binop?: ?number, + keyword?: string; + beforeExpr?: boolean; + startsExpr?: boolean; + rightAssociative?: boolean; + isLoop?: boolean; + isAssign?: boolean; + prefix?: boolean; + postfix?: boolean; + binop?: number | null; }; // Internally the tokenizer stores token as a number -export opaque type TokenType = number; +export type TokenType = number; // The `ExportedTokenType` is exported via `tokTypes` and accessible // when `tokens: true` is enabled. Unlike internal token type, it provides // metadata of the tokens. export class ExportedTokenType { label: string; - keyword: ?string; + keyword: string | undefined | null; beforeExpr: boolean; startsExpr: boolean; rightAssociative: boolean; @@ -57,9 +56,12 @@ export class ExportedTokenType { isAssign: boolean; prefix: boolean; postfix: boolean; - binop: ?number; + binop: number | undefined | null; // todo(Babel 8): remove updateContext from exposed token layout - declare updateContext: ?(context: Array) => void; + declare updateContext: + | ((context: Array) => void) + | undefined + | null; constructor(label: string, conf: TokenOptions = {}) { this.label = label; @@ -132,7 +134,9 @@ function createKeywordLike( // For performance the token type helpers depend on the following declarations order. // When adding new token types, please also check if the token helpers need update. -export const tt: { [name: string]: TokenType } = { +export const tt: { + [name: string]: TokenType; +} = { // Punctuation token types. bracketL: createToken("[", { beforeExpr, startsExpr }), bracketHashL: createToken("#[", { beforeExpr, startsExpr }), diff --git a/packages/babel-parser/src/types.js b/packages/babel-parser/src/types.ts similarity index 54% rename from packages/babel-parser/src/types.js rename to packages/babel-parser/src/types.ts index 904f6bbd3464..79e8dbbccb35 100644 --- a/packages/babel-parser/src/types.js +++ b/packages/babel-parser/src/types.ts @@ -1,5 +1,3 @@ -// @flow - import type { SourceType } from "./options"; import type { Token } from "./tokenizer"; import type { SourceLocation } from "./util/location"; @@ -17,31 +15,31 @@ import type { ParseError } from "./parse-error"; */ type CommentBase = { - type: "CommentBlock" | "CommentLine", - value: string, - start: number, - end: number, - loc: SourceLocation, + type: "CommentBlock" | "CommentLine"; + value: string; + start: number; + end: number; + loc: SourceLocation; }; export type CommentBlock = CommentBase & { - type: "CommentBlock", + type: "CommentBlock"; }; export type CommentLine = CommentBase & { - type: "CommentLine", + type: "CommentLine"; }; export type Comment = CommentBlock | CommentLine; // A whitespace containing comments export type CommentWhitespace = { - start: number, - end: number, - comments: Array, - leadingNode: Node | null, - trailingNode: Node | null, - containerNode: Node | null, + start: number; + end: number; + comments: Array; + leadingNode: Node | null; + trailingNode: Node | null; + containerNode: Node | null; }; export interface NodeBase { @@ -52,13 +50,16 @@ export interface NodeBase { leadingComments?: Array; trailingComments?: Array; innerComments?: Array; - - extra: { [key: string]: any }; + extra: { + [key: string]: any; + }; } // Using a union type for `Node` makes type-checking too slow. // Instead, add an index signature to allow a Node to be treated as anything. -export type Node = NodeBase & { [key: string]: any }; +export type Node = NodeBase & { + [key: string]: any; +}; export type Expression = Node; export type Statement = Node; export type Pattern = @@ -81,34 +82,32 @@ export type Declaration = export type DeclarationBase = NodeBase & { // TypeScript allows declarations to be prefixed by `declare`. //TODO: a FunctionDeclaration is never "declare", because it's a TSDeclareFunction instead. - declare?: true, + declare?: true; }; // TODO: Not in spec export type HasDecorators = NodeBase & { - decorators?: $ReadOnlyArray, + decorators?: ReadonlyArray; }; export type InterpreterDirective = NodeBase & { - type: "InterpreterDirective", - value: string, + type: "InterpreterDirective"; + value: string; }; export type Identifier = PatternBase & { - type: "Identifier", - name: string, - + type: "Identifier"; + name: string; // @deprecated - __clone(): Identifier, - + __clone(): Identifier; // TypeScript only. Used in case of an optional parameter. - optional?: ?true, + optional?: true | null; }; // | Placeholder<"Identifier">; export type PrivateName = NodeBase & { - type: "PrivateName", - id: Identifier, + type: "PrivateName"; + id: Identifier; }; // Literals @@ -123,60 +122,60 @@ export type Literal = | DecimalLiteral; export type RegExpLiteral = NodeBase & { - type: "RegExpLiteral", - pattern: string, - flags: RegExp$flags, + type: "RegExpLiteral"; + pattern: string; + flags: RegExp$flags; }; export type NullLiteral = NodeBase & { - type: "NullLiteral", + type: "NullLiteral"; }; export type StringLiteral = NodeBase & { - type: "StringLiteral", - value: string, + type: "StringLiteral"; + value: string; }; export type BooleanLiteral = NodeBase & { - type: "BooleanLiteral", - value: boolean, + type: "BooleanLiteral"; + value: boolean; }; export type NumericLiteral = NodeBase & { - type: "NumericLiteral", - value: number, + type: "NumericLiteral"; + value: number; }; export type BigIntLiteral = NodeBase & { - type: "BigIntLiteral", - value: number, + type: "BigIntLiteral"; + value: number; }; export type DecimalLiteral = NodeBase & { - type: "DecimalLiteral", - value: number, + type: "DecimalLiteral"; + value: number; }; export type ParserOutput = { - comments: $ReadOnlyArray, - errors: Array>, - tokens?: $ReadOnlyArray, + comments: ReadonlyArray; + errors: Array>; + tokens?: ReadonlyArray; }; // Programs export type BlockStatementLike = Program | BlockStatement; export type File = NodeBase & { - type: "File", - program: Program, + type: "File"; + program: Program; } & ParserOutput; export type Program = NodeBase & { - type: "Program", - sourceType: SourceType, - body: Array, // TODO: $ReadOnlyArray - directives: $ReadOnlyArray, // TODO: Not in spec - interpreter: InterpreterDirective | null, + type: "Program"; + sourceType: SourceType; + body: Array; // TODO: $ReadOnlyArray, + directives: ReadonlyArray; // TODO: Not in spec, + interpreter: InterpreterDirective | null; }; // Functions @@ -192,259 +191,266 @@ export type NormalFunction = FunctionDeclaration | FunctionExpression; export type BodilessFunctionOrMethodBase = HasDecorators & { // TODO: Remove this. Should not assign "id" to methods. // https://github.com/babel/babylon/issues/535 - id: ?Identifier, - - params: $ReadOnlyArray, - body: BlockStatement, - generator: boolean, - async: boolean, - + id: Identifier | undefined | null; + params: ReadonlyArray; + body: BlockStatement; + generator: boolean; + async: boolean; // TODO: All not in spec - expression: boolean, - typeParameters?: ?TypeParameterDeclarationBase, - returnType?: ?TypeAnnotationBase, + expression: boolean; + typeParameters?: TypeParameterDeclarationBase | null; + returnType?: TypeAnnotationBase | null; }; export type BodilessFunctionBase = BodilessFunctionOrMethodBase & { - id: ?Identifier, + id: Identifier | undefined | null; }; export type FunctionBase = BodilessFunctionBase & { - body: BlockStatement, + body: BlockStatement; }; // Statements export type ExpressionStatement = NodeBase & { - type: "ExpressionStatement", - expression: Expression, + type: "ExpressionStatement"; + expression: Expression; }; export type BlockStatement = NodeBase & { - type: "BlockStatement", - body: Array, // TODO: $ReadOnlyArray - directives: $ReadOnlyArray, + type: "BlockStatement"; + body: Array; // TODO: $ReadOnlyArray, + directives: ReadonlyArray; }; // | Placeholder<"BlockStatement">; export type EmptyStatement = NodeBase & { - type: "EmptyStatement", + type: "EmptyStatement"; }; export type DebuggerStatement = NodeBase & { - type: "DebuggerStatement", + type: "DebuggerStatement"; }; export type WithStatement = NodeBase & { - type: "WithStatement", - object: Expression, - body: Statement, + type: "WithStatement"; + object: Expression; + body: Statement; }; export type ReturnStatement = NodeBase & { - type: "ReturnStatement", - argument: ?Expression, + type: "ReturnStatement"; + argument: Expression | undefined | null; }; export type LabeledStatement = NodeBase & { - type: "LabeledStatement", - label: Identifier, - body: Statement, + type: "LabeledStatement"; + label: Identifier; + body: Statement; }; export type BreakStatement = NodeBase & { - type: "BreakStatement", - label: ?Identifier, + type: "BreakStatement"; + label: Identifier | undefined | null; }; export type ContinueStatement = NodeBase & { - type: "ContinueStatement", - label: ?Identifier, + type: "ContinueStatement"; + label: Identifier | undefined | null; }; // Choice export type IfStatement = NodeBase & { - type: "IfStatement", - test: Expression, - consequent: Statement, - alternate: ?Statement, + type: "IfStatement"; + test: Expression; + consequent: Statement; + alternate: Statement | undefined | null; }; export type SwitchStatement = NodeBase & { - type: "SwitchStatement", - discriminant: Expression, - cases: $ReadOnlyArray, + type: "SwitchStatement"; + discriminant: Expression; + cases: ReadonlyArray; }; export type SwitchCase = NodeBase & { - type: "SwitchCase", - test: ?Expression, - consequent: $ReadOnlyArray, + type: "SwitchCase"; + test: Expression | undefined | null; + consequent: ReadonlyArray; }; // Exceptions export type ThrowStatement = NodeBase & { - type: "ThrowStatement", - argument: Expression, + type: "ThrowStatement"; + argument: Expression; }; export type TryStatement = NodeBase & { - type: "TryStatement", - block: BlockStatement, - handler: CatchClause | null, - finalizer: BlockStatement | null, + type: "TryStatement"; + block: BlockStatement; + handler: CatchClause | null; + finalizer: BlockStatement | null; }; export type CatchClause = NodeBase & { - type: "CatchClause", - param: Pattern, - body: BlockStatement, + type: "CatchClause"; + param: Pattern; + body: BlockStatement; }; // Loops export type WhileStatement = NodeBase & { - type: "WhileStatement", - test: Expression, - body: Statement, + type: "WhileStatement"; + test: Expression; + body: Statement; }; export type DoWhileStatement = NodeBase & { - type: "DoWhileStatement", - body: Statement, - test: Expression, + type: "DoWhileStatement"; + body: Statement; + test: Expression; }; export type ForLike = ForStatement | ForInOf; export type ForStatement = NodeBase & { - type: "ForStatement", - init: ?(VariableDeclaration | Expression), - test: ?Expression, - update: ?Expression, - body: Statement, + type: "ForStatement"; + init: VariableDeclaration | Expression | undefined | null; + test: Expression | undefined | null; + update: Expression | undefined | null; + body: Statement; }; export type ForInOf = ForInStatement | ForOfStatement; export type ForInOfBase = NodeBase & { - type: "ForInStatement", - left: VariableDeclaration | Expression, - right: Expression, - body: Statement, + type: "ForInStatement"; + left: VariableDeclaration | Expression; + right: Expression; + body: Statement; }; export type ForInStatement = ForInOfBase & { - type: "ForInStatement", + type: "ForInStatement"; // TODO: Shouldn't be here, but have to declare it because it's assigned to a ForInOf unconditionally. - await: boolean, + await: boolean; }; export type ForOfStatement = ForInOfBase & { - type: "ForOfStatement", - await: boolean, + type: "ForOfStatement"; + await: boolean; }; // Declarations export type OptFunctionDeclaration = FunctionBase & DeclarationBase & { - type: "FunctionDeclaration", + type: "FunctionDeclaration"; }; export type FunctionDeclaration = OptFunctionDeclaration & { - id: Identifier, + id: Identifier; }; export type VariableDeclaration = DeclarationBase & HasDecorators & { - type: "VariableDeclaration", - declarations: $ReadOnlyArray, - kind: "var" | "let" | "const", + type: "VariableDeclaration"; + declarations: ReadonlyArray; + kind: "var" | "let" | "const"; }; export type VariableDeclarator = NodeBase & { - type: "VariableDeclarator", - id: Pattern, - init: ?Expression, - + type: "VariableDeclarator"; + id: Pattern; + init: Expression | undefined | null; // TypeScript only: - definite?: true, + definite?: true; }; // Misc -export type ArgumentPlaceholder = NodeBase & { type: "ArgumentPlaceholder" }; +export type ArgumentPlaceholder = NodeBase & { + type: "ArgumentPlaceholder"; +}; export type Decorator = NodeBase & { - type: "Decorator", - expression: Expression, - arguments?: Array, + type: "Decorator"; + expression: Expression; + arguments?: Array; }; export type Directive = NodeBase & { - type: "Directive", - value: DirectiveLiteral, + type: "Directive"; + value: DirectiveLiteral; }; -export type DirectiveLiteral = StringLiteral & { type: "DirectiveLiteral" }; +export type DirectiveLiteral = StringLiteral & { + type: "DirectiveLiteral"; +}; export type ImportAttribute = NodeBase & { - type: "ImportAttribute", - key: Identifier | StringLiteral, - value: StringLiteral, + type: "ImportAttribute"; + key: Identifier | StringLiteral; + value: StringLiteral; }; // Expressions -export type Super = NodeBase & { type: "Super" }; +export type Super = NodeBase & { + type: "Super"; +}; -export type Import = NodeBase & { type: "Import" }; +export type Import = NodeBase & { + type: "Import"; +}; -export type ThisExpression = NodeBase & { type: "ThisExpression" }; +export type ThisExpression = NodeBase & { + type: "ThisExpression"; +}; export type ArrowFunctionExpression = FunctionBase & { - type: "ArrowFunctionExpression", - body: BlockStatement | Expression, + type: "ArrowFunctionExpression"; + body: BlockStatement | Expression; }; export type YieldExpression = NodeBase & { - type: "YieldExpression", - argument: ?Expression, - delegate: boolean, + type: "YieldExpression"; + argument: Expression | undefined | null; + delegate: boolean; }; export type AwaitExpression = NodeBase & { - type: "AwaitExpression", - argument: Expression, + type: "AwaitExpression"; + argument: Expression; }; export type ArrayExpression = NodeBase & { - type: "ArrayExpression", - elements: $ReadOnlyArray, + type: "ArrayExpression"; + elements: ReadonlyArray; }; export type DoExpression = NodeBase & { - type: "DoExpression", - body: ?BlockStatement, - async: boolean, + type: "DoExpression"; + body: BlockStatement | undefined | null; + async: boolean; }; export type TupleExpression = NodeBase & { - type: "TupleExpression", - elements: $ReadOnlyArray, + type: "TupleExpression"; + elements: ReadonlyArray; }; export type ObjectExpression = NodeBase & { - type: "ObjectExpression", - properties: $ReadOnlyArray, + type: "ObjectExpression"; + properties: ReadonlyArray; }; export type RecordExpression = NodeBase & { - type: "RecordExpression", - properties: $ReadOnlyArray, + type: "RecordExpression"; + properties: ReadonlyArray; }; export type ObjectOrClassMember = ClassMethod | ClassProperty | ObjectMember; @@ -452,39 +458,39 @@ export type ObjectOrClassMember = ClassMethod | ClassProperty | ObjectMember; export type ObjectMember = ObjectProperty | ObjectMethod; export type ObjectMemberBase = NodeBase & { - key: Expression, - computed: boolean, - value: Expression, - decorators: $ReadOnlyArray, - kind?: "get" | "set" | "method", - method: boolean, // TODO: Not in spec - typeParameters?: ?TypeParameterInstantiationBase, // TODO: Not in spec - variance?: ?FlowVariance, // TODO: Not in spec + key: Expression; + computed: boolean; + value: Expression; + decorators: ReadonlyArray; + kind?: "get" | "set" | "method"; + method: boolean; // TODO: Not in spec, + typeParameters?: TypeParameterInstantiationBase | null; // TODO: Not in spec, + variance?: FlowVariance | null; // TODO: Not in spec }; export type ObjectProperty = ObjectMemberBase & { - type: "ObjectProperty", - shorthand: boolean, + type: "ObjectProperty"; + shorthand: boolean; }; export type ObjectMethod = ObjectMemberBase & MethodBase & { - type: "ObjectMethod", - kind: "get" | "set" | "method", // Never "constructor" + type: "ObjectMethod"; + kind: "get" | "set" | "method"; // Never "constructor" }; export type FunctionExpression = MethodBase & { - kind?: void, // never set - type: "FunctionExpression", + kind?: void; // never set, + type: "FunctionExpression"; }; // Unary operations export type UnaryExpression = NodeBase & { - type: "UnaryExpression", - operator: UnaryOperator, - prefix: boolean, - argument: Expression, + type: "UnaryExpression"; + operator: UnaryOperator; + prefix: boolean; + argument: Expression; }; export type UnaryOperator = @@ -498,10 +504,10 @@ export type UnaryOperator = | "throw"; export type UpdateExpression = NodeBase & { - type: "UpdateExpression", - operator: UpdateOperator, - argument: Expression, - prefix: boolean, + type: "UpdateExpression"; + operator: UpdateOperator; + argument: Expression; + prefix: boolean; }; export type UpdateOperator = "++" | "--"; @@ -509,10 +515,10 @@ export type UpdateOperator = "++" | "--"; // Binary operations export type BinaryExpression = NodeBase & { - type: "BinaryExpression", - operator: BinaryOperator, - left: Expression, - right: Expression, + type: "BinaryExpression"; + operator: BinaryOperator; + left: Expression; + right: Expression; }; export type BinaryOperator = @@ -539,10 +545,10 @@ export type BinaryOperator = | "instanceof"; export type AssignmentExpression = NodeBase & { - type: "AssignmentExpression", - operator: AssignmentOperator, - left: Pattern | Expression, - right: Expression, + type: "AssignmentExpression"; + operator: AssignmentOperator; + left: Pattern | Expression; + right: Expression; }; export type AssignmentOperator = @@ -560,107 +566,107 @@ export type AssignmentOperator = | "&="; export type LogicalExpression = NodeBase & { - type: "LogicalExpression", - operator: LogicalOperator, - left: Expression, - right: Expression, + type: "LogicalExpression"; + operator: LogicalOperator; + left: Expression; + right: Expression; }; export type LogicalOperator = "||" | "&&"; export type SpreadElement = NodeBase & { - type: "SpreadElement", - argument: Expression, + type: "SpreadElement"; + argument: Expression; }; export type MemberExpression = NodeBase & { - type: "MemberExpression", - object: Expression | Super, - property: Expression, - computed: boolean, + type: "MemberExpression"; + object: Expression | Super; + property: Expression; + computed: boolean; }; export type OptionalMemberExpression = NodeBase & { - type: "OptionalMemberExpression", - object: Expression | Super, - property: Expression, - computed: boolean, - optional: boolean, + type: "OptionalMemberExpression"; + object: Expression | Super; + property: Expression; + computed: boolean; + optional: boolean; }; export type OptionalCallExpression = CallOrNewBase & { - type: "OptionalCallExpression", - optional: boolean, + type: "OptionalCallExpression"; + optional: boolean; }; export type BindExpression = NodeBase & { - type: "BindExpression", - object: $ReadOnlyArray, - callee: $ReadOnlyArray, + type: "BindExpression"; + object: ReadonlyArray; + callee: ReadonlyArray; }; export type ConditionalExpression = NodeBase & { - type: "ConditionalExpression", - test: Expression, - alternate: Expression, - consequent: Expression, + type: "ConditionalExpression"; + test: Expression; + alternate: Expression; + consequent: Expression; }; export type CallOrNewBase = NodeBase & { - callee: Expression | Super | Import, - arguments: Array, // TODO: $ReadOnlyArray - typeArguments: ?TypeParameterInstantiationBase, - typeParameters?: ?TypeParameterInstantiationBase, // TODO: Not in spec + callee: Expression | Super | Import; + arguments: Array; // TODO: $ReadOnlyArray, + typeArguments: TypeParameterInstantiationBase | undefined | null; + typeParameters?: TypeParameterInstantiationBase | null; // TODO: Not in spec }; export type CallExpression = CallOrNewBase & { - type: "CallExpression", + type: "CallExpression"; }; export type NewExpression = CallOrNewBase & { - type: "NewExpression", - optional?: boolean, // TODO: Not in spec + type: "NewExpression"; + optional?: boolean; // TODO: Not in spec }; export type SequenceExpression = NodeBase & { - type: "SequenceExpression", - expressions: $ReadOnlyArray, + type: "SequenceExpression"; + expressions: ReadonlyArray; }; export type ParenthesizedExpression = NodeBase & { - type: "ParenthesizedExpression", - expression: Expression, + type: "ParenthesizedExpression"; + expression: Expression; }; // Hack pipe operator export type TopicReference = NodeBase & { - type: "TopicReference", + type: "TopicReference"; }; // Smart-mix pipe operator export type PipelineBody = NodeBase & { - type: "PipelineBody", + type: "PipelineBody"; }; export type PipelineBareFunctionBody = NodeBase & { - type: "PipelineBareFunctionBody", - callee: Expression, + type: "PipelineBareFunctionBody"; + callee: Expression; }; export type PipelineBareConstructorBody = NodeBase & { - type: "PipelineBareConstructorBody", - callee: Expression, + type: "PipelineBareConstructorBody"; + callee: Expression; }; export type PipelineBareAwaitedFunctionBody = NodeBase & { - type: "PipelineBareAwaitedFunctionBody", - callee: Expression, + type: "PipelineBareAwaitedFunctionBody"; + callee: Expression; }; export type PipelineTopicBody = NodeBase & { - type: "PipelineTopicBody", - expression: Expression, + type: "PipelineTopicBody"; + expression: Expression; }; export type PipelineStyle = @@ -670,36 +676,36 @@ export type PipelineStyle = | "PipelineTopicExpression"; export type PipelinePrimaryTopicReference = NodeBase & { - type: "PipelinePrimaryTopicReference", + type: "PipelinePrimaryTopicReference"; }; // Template Literals export type TemplateLiteral = NodeBase & { - type: "TemplateLiteral", - quasis: $ReadOnlyArray, - expressions: $ReadOnlyArray, + type: "TemplateLiteral"; + quasis: ReadonlyArray; + expressions: ReadonlyArray; }; export type TaggedTemplateExpression = NodeBase & { - type: "TaggedTemplateExpression", - tag: Expression, - quasi: TemplateLiteral, - typeParameters?: ?TypeParameterInstantiationBase, // TODO: Not in spec + type: "TaggedTemplateExpression"; + tag: Expression; + quasi: TemplateLiteral; + typeParameters?: TypeParameterInstantiationBase | null; // TODO: Not in spec }; export type TemplateElement = NodeBase & { - type: "TemplateElement", - tail: boolean, + type: "TemplateElement"; + tail: boolean; value: { - cooked: string, - raw: string, - }, + cooked: string; + raw: string; + }; }; export type ModuleExpression = NodeBase & { - type: "ModuleExpression", - body: Program, + type: "ModuleExpression"; + body: Program; }; // Patterns @@ -712,32 +718,32 @@ export type VarianceAnnotations = "in" | "out"; export type PatternBase = HasDecorators & { // TODO: All not in spec // Flow/TypeScript only: - typeAnnotation?: ?TypeAnnotationBase, + typeAnnotation?: TypeAnnotationBase | null; }; export type AssignmentProperty = ObjectProperty & { - value: Pattern, + value: Pattern; }; export type ObjectPattern = PatternBase & { - type: "ObjectPattern", - properties: $ReadOnlyArray, + type: "ObjectPattern"; + properties: ReadonlyArray; }; export type ArrayPattern = PatternBase & { - type: "ArrayPattern", - elements: $ReadOnlyArray, + type: "ArrayPattern"; + elements: ReadonlyArray; }; export type RestElement = PatternBase & { - type: "RestElement", - argument: Pattern, + type: "RestElement"; + argument: Pattern; }; export type AssignmentPattern = PatternBase & { - type: "AssignmentPattern", - left: Pattern, - right: Expression, + type: "AssignmentPattern"; + left: Pattern; + right: Expression; }; // Classes @@ -745,39 +751,40 @@ export type AssignmentPattern = PatternBase & { export type Class = ClassDeclaration | ClassExpression; export type ClassBase = HasDecorators & { - id: ?Identifier, - superClass: ?Expression, - body: ClassBody, - decorators: $ReadOnlyArray, - + id: Identifier | undefined | null; + superClass: Expression | undefined | null; + body: ClassBody; + decorators: ReadonlyArray; // TODO: All not in spec - typeParameters?: ?TypeParameterDeclarationBase, - superTypeParameters?: ?TypeParameterInstantiationBase, + typeParameters?: TypeParameterDeclarationBase | null; + superTypeParameters?: TypeParameterInstantiationBase | null; implements?: - | ?$ReadOnlyArray - | $ReadOnlyArray, + | ReadonlyArray + | undefined + | null + | ReadonlyArray; }; export type ClassBody = NodeBase & { - type: "ClassBody", - body: Array, // TODO: $ReadOnlyArray + type: "ClassBody"; + body: Array; // TODO: $ReadOnlyArray }; // | Placeholder<"ClassBody">; export type ClassMemberBase = NodeBase & HasDecorators & { - static: boolean, - computed: boolean, + static: boolean; + computed: boolean; // TypeScript only: - accessibility?: ?Accessibility, - override?: ?true, - abstract?: ?true, - optional?: ?true, + accessibility?: Accessibility | null; + override?: true | null; + abstract?: true | null; + optional?: true | null; }; export type StaticBlock = NodeBase & { - type: "StaticBlock", - body: Array, + type: "StaticBlock"; + body: Array; }; export type ClassMember = @@ -795,101 +802,95 @@ export type MethodLike = | TSDeclareMethod; export type MethodBase = FunctionBase & { - +kind: MethodKind, + readonly kind: MethodKind; }; export type MethodKind = "constructor" | "method" | "get" | "set"; export type ClassMethodOrDeclareMethodCommon = ClassMemberBase & { - key: Expression, - kind: MethodKind, - static: boolean, - decorators: $ReadOnlyArray, + key: Expression; + kind: MethodKind; + static: boolean; + decorators: ReadonlyArray; }; export type ClassMethod = MethodBase & ClassMethodOrDeclareMethodCommon & { - type: "ClassMethod", - variance?: ?FlowVariance, // TODO: Not in spec + type: "ClassMethod"; + variance?: FlowVariance | null; // TODO: Not in spec }; export type ClassPrivateMethod = NodeBase & ClassMethodOrDeclareMethodCommon & MethodBase & { - type: "ClassPrivateMethod", - key: PrivateName, - computed: false, - variance?: ?FlowVariance, // TODO: Not in spec + type: "ClassPrivateMethod"; + key: PrivateName; + computed: false; + variance?: FlowVariance | null; // TODO: Not in spec }; export type ClassProperty = ClassMemberBase & DeclarationBase & { - type: "ClassProperty", - key: Expression, - value: ?Expression, // TODO: Not in spec that this is nullable. - - typeAnnotation?: ?TypeAnnotationBase, // TODO: Not in spec - + type: "ClassProperty"; + key: Expression; + value: Expression | undefined | null; // TODO: Not in spec that this is nullable., + typeAnnotation?: TypeAnnotationBase | null; // TODO: Not in spec, // Flow only: - variance?: ?FlowVariance, // TODO: Not in spec - + variance?: FlowVariance | null; // TODO: Not in spec, // TypeScript only: (TODO: Not in spec) - readonly?: true, - definite?: true, + readonly?: true; + definite?: true; }; export type ClassPrivateProperty = NodeBase & { - type: "ClassPrivateProperty", - key: PrivateName, - value: ?Expression, // TODO: Not in spec that this is nullable. - static: boolean, - computed: false, - + type: "ClassPrivateProperty"; + key: PrivateName; + value: Expression | undefined | null; // TODO: Not in spec that this is nullable., + static: boolean; + computed: false; // Flow and Typescript - typeAnnotation?: ?TypeAnnotationBase, - + typeAnnotation?: TypeAnnotationBase | null; // TypeScript only - optional?: true, - definite?: true, - readonly?: true, - override?: true, - + optional?: true; + definite?: true; + readonly?: true; + override?: true; // Flow only - variance?: ?FlowVariance, + variance?: FlowVariance | null; }; export type ClassAccessorProperty = ClassMemberBase & DeclarationBase & { - type: "ClassAccessorProperty", - key: Expression | PrivateName, - value: ?Expression, - - typeAnnotation?: ?TypeAnnotationBase, // TODO: Not in spec - variance?: ?FlowVariance, // TODO: Not in spec - + type: "ClassAccessorProperty"; + key: Expression | PrivateName; + value: Expression | undefined | null; + typeAnnotation?: TypeAnnotationBase | null; // TODO: Not in spec, + variance?: FlowVariance | null; // TODO: Not in spec, // TypeScript only: (TODO: Not in spec) - readonly?: true, - definite?: true, + readonly?: true; + definite?: true; }; export type OptClassDeclaration = ClassBase & DeclarationBase & HasDecorators & { - type: "ClassDeclaration", + type: "ClassDeclaration"; // TypeScript only - abstract?: ?true, + abstract?: true | null; }; export type ClassDeclaration = OptClassDeclaration & { - id: Identifier, + id: Identifier; }; -export type ClassExpression = ClassBase & { type: "ClassExpression" }; +export type ClassExpression = ClassBase & { + type: "ClassExpression"; +}; export type MetaProperty = NodeBase & { - type: "MetaProperty", - meta: Identifier, - property: Identifier, + type: "MetaProperty"; + meta: Identifier; + property: Identifier; }; // Modules @@ -907,77 +908,73 @@ export type AnyExport = | TsNamespaceExportDeclaration; export type ModuleSpecifier = NodeBase & { - local: Identifier, + local: Identifier; }; // Imports export type ImportDeclaration = NodeBase & { - type: "ImportDeclaration", + type: "ImportDeclaration"; // TODO: $ReadOnlyArray specifiers: Array< - ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier, - >, - source: Literal, - - importKind?: "type" | "typeof" | "value", // TODO: Not in spec - - assertions?: $ReadOnlyArray, + ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier + >; + source: Literal; + importKind?: "type" | "typeof" | "value"; // TODO: Not in spec, + assertions?: ReadonlyArray; }; export type ImportSpecifier = ModuleSpecifier & { - type: "ImportSpecifier", - imported: Identifier | StringLiteral, - importKind?: "type" | "value", + type: "ImportSpecifier"; + imported: Identifier | StringLiteral; + importKind?: "type" | "value"; }; export type ImportDefaultSpecifier = ModuleSpecifier & { - type: "ImportDefaultSpecifier", + type: "ImportDefaultSpecifier"; }; export type ImportNamespaceSpecifier = ModuleSpecifier & { - type: "ImportNamespaceSpecifier", + type: "ImportNamespaceSpecifier"; }; // Exports export type ExportNamedDeclaration = NodeBase & { - type: "ExportNamedDeclaration", - declaration: ?Declaration, - specifiers: $ReadOnlyArray, - source: ?Literal, - - exportKind?: "type" | "value", // TODO: Not in spec - - assertions?: $ReadOnlyArray, + type: "ExportNamedDeclaration"; + declaration: Declaration | undefined | null; + specifiers: ReadonlyArray; + source: Literal | undefined | null; + exportKind?: "type" | "value"; // TODO: Not in spec, + assertions?: ReadonlyArray; }; export type ExportSpecifier = NodeBase & { - type: "ExportSpecifier", - exported: Identifier | StringLiteral, - local: Identifier, - exportKind?: "type" | "value", + type: "ExportSpecifier"; + exported: Identifier | StringLiteral; + local: Identifier; + exportKind?: "type" | "value"; }; export type ExportDefaultSpecifier = NodeBase & { - type: "ExportDefaultSpecifier", - exported: Identifier, + type: "ExportDefaultSpecifier"; + exported: Identifier; }; export type ExportDefaultDeclaration = NodeBase & { - type: "ExportDefaultDeclaration", + type: "ExportDefaultDeclaration"; declaration: | OptFunctionDeclaration | OptTSDeclareFunction | OptClassDeclaration - | Expression, + | Expression; }; export type ExportAllDeclaration = NodeBase & { - type: "ExportAllDeclaration", - source: Literal, - exportKind?: "type" | "value", // TODO: Not in spec - assertions?: $ReadOnlyArray, + type: "ExportAllDeclaration"; + source: Literal; + exportKind?: "type" | "value"; // TODO: Not in spec, + assertions?: ReadonlyArray; }; // JSX (TODO: Not in spec) @@ -990,11 +987,11 @@ export type JSXSpreadChild = Node; export type JSXExpressionContainer = Node; export type JSXAttribute = Node; export type JSXOpeningElement = NodeBase & { - type: "JSXOpeningElement", - name: JSXNamespacedName | JSXMemberExpression, - typeParameters?: ?TypeParameterInstantiationBase, // TODO: Not in spec - attributes: $ReadOnlyArray, - selfClosing: boolean, + type: "JSXOpeningElement"; + name: JSXNamespacedName | JSXMemberExpression; + typeParameters?: TypeParameterInstantiationBase | null; // TODO: Not in spec, + attributes: ReadonlyArray; + selfClosing: boolean; }; export type JSXClosingElement = Node; export type JSXElement = Node; @@ -1005,80 +1002,80 @@ export type JSXFragment = Node; // Flow/TypeScript common (TODO: Not in spec) export type TypeAnnotationBase = NodeBase & { - typeAnnotation: Node, + typeAnnotation: Node; }; export type TypeAnnotation = NodeBase & { - type: "TypeAnnotation", - typeAnnotation: FlowTypeAnnotation, + type: "TypeAnnotation"; + typeAnnotation: FlowTypeAnnotation; }; export type TsTypeAnnotation = NodeBase & { - type: "TSTypeAnnotation", - typeAnnotation: TsType, + type: "TSTypeAnnotation"; + typeAnnotation: TsType; }; export type TypeParameterDeclarationBase = NodeBase & { - params: $ReadOnlyArray, + params: ReadonlyArray; }; export type TypeParameterDeclaration = TypeParameterDeclarationBase & { - type: "TypeParameterDeclaration", - params: $ReadOnlyArray, + type: "TypeParameterDeclaration"; + params: ReadonlyArray; }; export type TsTypeParameterDeclaration = TypeParameterDeclarationBase & { - type: "TsTypeParameterDeclaration", - params: $ReadOnlyArray, + type: "TsTypeParameterDeclaration"; + params: ReadonlyArray; }; export type TypeParameter = NodeBase & { - type: "TypeParameter", - name: string, - default?: TypeAnnotation, + type: "TypeParameter"; + name: string; + default?: TypeAnnotation; }; export type TsTypeParameter = NodeBase & { - type: "TSTypeParameter", + type: "TSTypeParameter"; // TODO(Babel-8): remove string type support - name: string | Identifier, - in?: boolean, - out?: boolean, - constraint?: TsType, - default?: TsType, + name: string | Identifier; + in?: boolean; + out?: boolean; + constraint?: TsType; + default?: TsType; }; export type TypeParameterInstantiationBase = NodeBase & { - params: $ReadOnlyArray, + params: ReadonlyArray; }; export type TypeParameterInstantiation = TypeParameterInstantiationBase & { - type: "TypeParameterInstantiation", - params: $ReadOnlyArray, + type: "TypeParameterInstantiation"; + params: ReadonlyArray; }; export type TsTypeParameterInstantiation = TypeParameterInstantiationBase & { - type: "TSTypeParameterInstantiation", - params: $ReadOnlyArray, + type: "TSTypeParameterInstantiation"; + params: ReadonlyArray; }; // Flow (TODO: Not in spec) export type TypeCastExpressionBase = NodeBase & { - expression: Expression, - typeAnnotation: TypeAnnotationBase, + expression: Expression; + typeAnnotation: TypeAnnotationBase; }; export type TypeCastExpression = NodeBase & { - type: "TypeCastExpression", - expression: Expression, - typeAnnotation: TypeAnnotation, + type: "TypeCastExpression"; + expression: Expression; + typeAnnotation: TypeAnnotation; }; export type TsTypeCastExpression = NodeBase & { - type: "TSTypeCastExpression", - expression: Expression, - typeAnnotation: TsTypeAnnotation, + type: "TSTypeCastExpression"; + expression: Expression; + typeAnnotation: TsTypeAnnotation; }; export type FlowType = Node; @@ -1114,104 +1111,103 @@ export type FlowVariance = Node; export type FlowClassImplements = Node; export type FlowInterfaceType = NodeBase & { - type: "FlowInterfaceType", - extends: FlowInterfaceExtends, - body: FlowObjectTypeAnnotation, + type: "FlowInterfaceType"; + extends: FlowInterfaceExtends; + body: FlowObjectTypeAnnotation; }; export type FlowIndexedAccessType = Node & { - type: "IndexedAccessType", - objectType: FlowType, - indexType: FlowType, + type: "IndexedAccessType"; + objectType: FlowType; + indexType: FlowType; }; export type FlowOptionalIndexedAccessType = Node & { - type: "OptionalIndexedAccessType", - objectType: FlowType, - indexType: FlowType, - optional: boolean, + type: "OptionalIndexedAccessType"; + objectType: FlowType; + indexType: FlowType; + optional: boolean; }; export type StringLiteralTypeAnnotation = NodeBase & { - type: "StringLiteralTypeAnnotation", - value: string, + type: "StringLiteralTypeAnnotation"; + value: string; }; export type BooleanLiteralTypeAnnotation = NodeBase & { - type: "BooleanLiteralTypeAnnotation", - value: boolean, + type: "BooleanLiteralTypeAnnotation"; + value: boolean; }; export type NumberLiteralTypeAnnotation = NodeBase & { - type: "NumberLiteralTypeAnnotation", - value: number, + type: "NumberLiteralTypeAnnotation"; + value: number; }; export type BigIntLiteralTypeAnnotation = NodeBase & { - type: "BigIntLiteralTypeAnnotation", + type: "BigIntLiteralTypeAnnotation"; //todo(flow): use bigint when Flow supports BigInt - value: number, + value: number; }; // ESTree export type EstreeLiteral = NodeBase & { - type: "Literal", - value: any, + type: "Literal"; + value: any; }; type EstreeRegExpLiteralRegex = { - pattern: string, - flags: string, + pattern: string; + flags: string; }; + export type EstreeRegExpLiteral = EstreeLiteral & { - regex: EstreeRegExpLiteralRegex, + regex: EstreeRegExpLiteralRegex; }; export type EstreeBigIntLiteral = EstreeLiteral & { - value: number | null, - bigint: string, + value: number | null; + bigint: string; }; export type EstreeProperty = NodeBase & { - type: "Property", - shorthand: boolean, - key: Expression, - computed: boolean, - value: Expression, - decorators: $ReadOnlyArray, - kind?: "get" | "set" | "init", - - variance?: ?FlowVariance, + type: "Property"; + shorthand: boolean; + key: Expression; + computed: boolean; + value: Expression; + decorators: ReadonlyArray; + kind?: "get" | "set" | "init"; + variance?: FlowVariance | null; }; export type EstreeMethodDefinition = NodeBase & { - type: "MethodDefinition", - static: boolean, - key: Expression, - computed: boolean, - value: Expression, - decorators: $ReadOnlyArray, - kind?: "get" | "set" | "method", - - variance?: ?FlowVariance, + type: "MethodDefinition"; + static: boolean; + key: Expression; + computed: boolean; + value: Expression; + decorators: ReadonlyArray; + kind?: "get" | "set" | "method"; + variance?: FlowVariance | null; }; export type EstreeImportExpression = NodeBase & { - type: "ImportExpression", - source: Expression, - attributes?: Expression | null, + type: "ImportExpression"; + source: Expression; + attributes?: Expression | null; }; export type EstreePrivateIdentifier = NodeBase & { - type: "PrivateIdentifier", - name: string, + type: "PrivateIdentifier"; + name: string; }; export type EstreePropertyDefinition = NodeBase & { - type: "PropertyDefinition", - static: boolean, - key: Expression | EstreePrivateIdentifier, - computed: boolean, - value: Expression, + type: "PropertyDefinition"; + static: boolean; + key: Expression | EstreePrivateIdentifier; + computed: boolean; + value: Expression; }; // === === === === @@ -1234,33 +1230,33 @@ export type EstreePropertyDefinition = NodeBase & { export type TSParameterProperty = HasDecorators & { // Note: This has decorators instead of its parameter. - type: "TSParameterProperty", + type: "TSParameterProperty"; // At least one of `accessibility` or `readonly` must be set. - accessibility?: ?Accessibility, - readonly?: ?true, - override?: ?true, - parameter: Identifier | AssignmentPattern, + accessibility?: Accessibility | null; + readonly?: true | null; + override?: true | null; + parameter: Identifier | AssignmentPattern; }; export type OptTSDeclareFunction = BodilessFunctionBase & DeclarationBase & { - type: "TSDeclareFunction", + type: "TSDeclareFunction"; }; export type TSDeclareFunction = OptTSDeclareFunction & { - id: Identifier, + id: Identifier; }; export type TSDeclareMethod = BodilessFunctionOrMethodBase & ClassMethodOrDeclareMethodCommon & { - type: "TSDeclareMethod", - +kind: MethodKind, + type: "TSDeclareMethod"; + readonly kind: MethodKind; }; export type TsQualifiedName = NodeBase & { - type: "TSQualifiedName", - left: TsEntityName, - right: Identifier, + type: "TSQualifiedName"; + left: TsEntityName; + right: Identifier; }; export type TsEntityName = Identifier | TsQualifiedName; @@ -1274,20 +1270,20 @@ export type TsSignatureDeclaration = export type TsSignatureDeclarationOrIndexSignatureBase = NodeBase & { // Not using TypeScript's "ParameterDeclaration" here, since it's inconsistent with regular functions. - params: $ReadOnlyArray< - Identifier | RestElement | ObjectPattern | ArrayPattern, - >, - returnType: ?TsTypeAnnotation, + params: ReadonlyArray< + Identifier | RestElement | ObjectPattern | ArrayPattern + >; + returnType: TsTypeAnnotation | undefined | null; // TODO(Babel-8): Remove - parameters: $ReadOnlyArray< - Identifier | RestElement | ObjectPattern | ArrayPattern, - >, - typeAnnotation: ?TsTypeAnnotation, + parameters: ReadonlyArray< + Identifier | RestElement | ObjectPattern | ArrayPattern + >; + typeAnnotation: TsTypeAnnotation | undefined | null; }; export type TsSignatureDeclarationBase = TsSignatureDeclarationOrIndexSignatureBase & { - typeParameters: ?TsTypeParameterDeclaration, + typeParameters: TsTypeParameterDeclaration | undefined | null; }; // ================ @@ -1302,39 +1298,39 @@ export type TsTypeElement = | TsIndexSignature; export type TsCallSignatureDeclaration = TsSignatureDeclarationBase & { - type: "TSCallSignatureDeclaration", + type: "TSCallSignatureDeclaration"; }; export type TsConstructSignatureDeclaration = TsSignatureDeclarationBase & { - type: "TSConstructSignature", + type: "TSConstructSignature"; }; export type TsNamedTypeElementBase = NodeBase & { // Not using TypeScript's `PropertyName` here since we don't have a `ComputedPropertyName` node type. // This is usually an Identifier but may be e.g. `Symbol.iterator` if `computed` is true. - key: Expression, - computed: boolean, - optional?: true, + key: Expression; + computed: boolean; + optional?: true; }; export type TsPropertySignature = TsNamedTypeElementBase & { - type: "TSPropertySignature", - readonly?: true, - typeAnnotation?: TsTypeAnnotation, - initializer?: Expression, + type: "TSPropertySignature"; + readonly?: true; + typeAnnotation?: TsTypeAnnotation; + initializer?: Expression; }; export type TsMethodSignature = TsSignatureDeclarationBase & TsNamedTypeElementBase & { - type: "TSMethodSignature", - kind: "method" | "get" | "set", + type: "TSMethodSignature"; + kind: "method" | "get" | "set"; }; // *Not* a ClassMemberBase: Can't have accessibility, can't be abstract, can't be optional. export type TsIndexSignature = TsSignatureDeclarationOrIndexSignatureBase & { - readonly?: true, - static?: true, - type: "TSIndexSignature", + readonly?: true; + static?: true; + type: "TSIndexSignature"; // Note: parameters.length must be 1. }; @@ -1360,9 +1356,8 @@ export type TsType = | TsTypeOperator | TsIndexedAccessType | TsMappedType - | TsLiteralType + | TsLiteralType // TODO: This probably shouldn't be included here. | TsImportType - // TODO: This probably shouldn't be included here. | TsTypePredicate; export type TsTypeBase = NodeBase; @@ -1382,143 +1377,143 @@ export type TsKeywordTypeType = | "TSNeverKeyword" | "TSIntrinsicKeyword"; export type TsKeywordType = TsTypeBase & { - type: TsKeywordTypeType, + type: TsKeywordTypeType; }; export type TsThisType = TsTypeBase & { - type: "TSThisType", + type: "TSThisType"; }; export type TsFunctionOrConstructorType = TsFunctionType | TsConstructorType; export type TsFunctionType = TsTypeBase & TsSignatureDeclarationBase & { - type: "TSFunctionType", - typeAnnotation: TypeAnnotation, // not optional + type: "TSFunctionType"; + typeAnnotation: TypeAnnotation; // not optional }; export type TsConstructorType = TsTypeBase & TsSignatureDeclarationBase & { - type: "TSConstructorType", - typeAnnotation: TsTypeAnnotation, - abstract: boolean, + type: "TSConstructorType"; + typeAnnotation: TsTypeAnnotation; + abstract: boolean; }; export type TsTypeReference = TsTypeBase & { - type: "TSTypeReference", - typeName: TsEntityName, - typeParameters?: TsTypeParameterInstantiation, + type: "TSTypeReference"; + typeName: TsEntityName; + typeParameters?: TsTypeParameterInstantiation; }; export type TsTypePredicate = TsTypeBase & { - type: "TSTypePredicate", - parameterName: Identifier | TsThisType, - typeAnnotation: TsTypeAnnotation | null, - asserts: boolean, + type: "TSTypePredicate"; + parameterName: Identifier | TsThisType; + typeAnnotation: TsTypeAnnotation | null; + asserts: boolean; }; // `typeof` operator export type TsTypeQuery = TsTypeBase & { - type: "TSTypeQuery", - exprName: TsEntityName | TsImportType, - typeParameters?: TsTypeParameterInstantiation, + type: "TSTypeQuery"; + exprName: TsEntityName | TsImportType; + typeParameters?: TsTypeParameterInstantiation; }; export type TsTypeLiteral = TsTypeBase & { - type: "TSTypeLiteral", - members: $ReadOnlyArray, + type: "TSTypeLiteral"; + members: ReadonlyArray; }; export type TsArrayType = TsTypeBase & { - type: "TSArrayType", - elementType: TsType, + type: "TSArrayType"; + elementType: TsType; }; export type TsTupleType = TsTypeBase & { - type: "TSTupleType", - elementTypes: $ReadOnlyArray, + type: "TSTupleType"; + elementTypes: ReadonlyArray; }; export type TsNamedTupleMember = NodeBase & { - type: "TSNamedTupleMember", - label: Identifier, - optional: boolean, - elementType: TsType, + type: "TSNamedTupleMember"; + label: Identifier; + optional: boolean; + elementType: TsType; }; export type TsOptionalType = TsTypeBase & { - type: "TSOptionalType", - typeAnnotation: TsType, + type: "TSOptionalType"; + typeAnnotation: TsType; }; export type TsRestType = TsTypeBase & { - type: "TSRestType", - typeAnnotation: TsType | TsNamedTupleMember, + type: "TSRestType"; + typeAnnotation: TsType | TsNamedTupleMember; }; export type TsUnionOrIntersectionType = TsUnionType | TsIntersectionType; export type TsUnionOrIntersectionTypeBase = TsTypeBase & { - types: $ReadOnlyArray, + types: ReadonlyArray; }; export type TsUnionType = TsUnionOrIntersectionTypeBase & { - type: "TSUnionType", + type: "TSUnionType"; }; export type TsIntersectionType = TsUnionOrIntersectionTypeBase & { - type: "TSIntersectionType", + type: "TSIntersectionType"; }; export type TsConditionalType = TsTypeBase & { - type: "TSConditionalType", - checkType: TsType, - extendsType: TsType, - trueType: TsType, - falseType: TsType, + type: "TSConditionalType"; + checkType: TsType; + extendsType: TsType; + trueType: TsType; + falseType: TsType; }; export type TsInferType = TsTypeBase & { - type: "TSInferType", - typeParameter: TsTypeParameter, + type: "TSInferType"; + typeParameter: TsTypeParameter; }; export type TsParenthesizedType = TsTypeBase & { - type: "TSParenthesizedType", - typeAnnotation: TsType, + type: "TSParenthesizedType"; + typeAnnotation: TsType; }; export type TsTypeOperator = TsTypeBase & { - type: "TSTypeOperator", - operator: "keyof" | "unique" | "readonly", - typeAnnotation: TsType, + type: "TSTypeOperator"; + operator: "keyof" | "unique" | "readonly"; + typeAnnotation: TsType; }; export type TsIndexedAccessType = TsTypeBase & { - type: "TSIndexedAccessType", - objectType: TsType, - indexType: TsType, + type: "TSIndexedAccessType"; + objectType: TsType; + indexType: TsType; }; export type TsMappedType = TsTypeBase & { - type: "TSMappedType", - readonly?: true | "+" | "-", - typeParameter: TsTypeParameter, - optional?: true | "+" | "-", - typeAnnotation: ?TsType, - nameType: ?TsType, + type: "TSMappedType"; + readonly?: true | "+" | "-"; + typeParameter: TsTypeParameter; + optional?: true | "+" | "-"; + typeAnnotation: TsType | undefined | null; + nameType: TsType | undefined | null; }; export type TsLiteralType = TsTypeBase & { - type: "TSLiteralType", - literal: NumericLiteral | StringLiteral | BooleanLiteral | TemplateLiteral, + type: "TSLiteralType"; + literal: NumericLiteral | StringLiteral | BooleanLiteral | TemplateLiteral; }; export type TsImportType = TsTypeBase & { - type: "TsImportType", - argument: StringLiteral, - qualifier?: TsEntityName, - typeParameters?: TsTypeParameterInstantiation, + type: "TsImportType"; + argument: StringLiteral; + qualifier?: TsEntityName; + typeParameters?: TsTypeParameterInstantiation; }; // ================ @@ -1526,93 +1521,93 @@ export type TsImportType = TsTypeBase & { // ================ export type TsInterfaceDeclaration = DeclarationBase & { - type: "TSInterfaceDeclaration", - id: ?Identifier, - typeParameters: ?TsTypeParameterDeclaration, + type: "TSInterfaceDeclaration"; + id: Identifier | undefined | null; + typeParameters: TsTypeParameterDeclaration | undefined | null; // TS uses "heritageClauses", but want this to resemble ClassBase. - extends?: $ReadOnlyArray, - body: TSInterfaceBody, + extends?: ReadonlyArray; + body: TSInterfaceBody; }; export type TSInterfaceBody = NodeBase & { - type: "TSInterfaceBody", - body: $ReadOnlyArray, + type: "TSInterfaceBody"; + body: ReadonlyArray; }; export type TsExpressionWithTypeArguments = TsTypeBase & { - type: "TSExpressionWithTypeArguments", - expression: TsEntityName, - typeParameters?: TsTypeParameterInstantiation, + type: "TSExpressionWithTypeArguments"; + expression: TsEntityName; + typeParameters?: TsTypeParameterInstantiation; }; export type TsTypeAliasDeclaration = DeclarationBase & { - type: "TSTypeAliasDeclaration", - id: Identifier, - typeParameters: ?TsTypeParameterDeclaration, - typeAnnotation: TsType, + type: "TSTypeAliasDeclaration"; + id: Identifier; + typeParameters: TsTypeParameterDeclaration | undefined | null; + typeAnnotation: TsType; }; export type TsEnumDeclaration = DeclarationBase & { - type: "TSEnumDeclaration", - const?: true, - id: Identifier, - members: $ReadOnlyArray, + type: "TSEnumDeclaration"; + const?: true; + id: Identifier; + members: ReadonlyArray; }; export type TsEnumMember = NodeBase & { - type: "TSEnumMemodulmber", - id: Identifier | StringLiteral, - initializer?: Expression, + type: "TSEnumMemodulmber"; + id: Identifier | StringLiteral; + initializer?: Expression; }; export type TsModuleDeclaration = DeclarationBase & { - type: "TSModuleDeclaration", - global?: true, // In TypeScript, this is only available through `node.flags`. - id: TsModuleName, - body: TsNamespaceBody, + type: "TSModuleDeclaration"; + global?: true; // In TypeScript, this is only available through `node.flags`., + id: TsModuleName; + body: TsNamespaceBody; }; // `namespace A.B { }` is a namespace named `A` with another TsNamespaceDeclaration as its body. export type TsNamespaceBody = TsModuleBlock | TsNamespaceDeclaration; export type TsModuleBlock = NodeBase & { - type: "TSModuleBlock", - body: $ReadOnlyArray, + type: "TSModuleBlock"; + body: ReadonlyArray; }; export type TsNamespaceDeclaration = TsModuleDeclaration & { - id: Identifier, - body: TsNamespaceBody, + id: Identifier; + body: TsNamespaceBody; }; export type TsModuleName = Identifier | StringLiteral; export type TsImportEqualsDeclaration = NodeBase & { - type: "TSImportEqualsDeclaration", - isExport: boolean, - id: Identifier, - importKind: "type" | "value", - moduleReference: TsModuleReference, + type: "TSImportEqualsDeclaration"; + isExport: boolean; + id: Identifier; + importKind: "type" | "value"; + moduleReference: TsModuleReference; }; export type TsModuleReference = TsEntityName | TsExternalModuleReference; export type TsExternalModuleReference = NodeBase & { - type: "TSExternalModuleReference", - expression: StringLiteral, + type: "TSExternalModuleReference"; + expression: StringLiteral; }; // TypeScript's own parser uses ExportAssignment for both `export default` and `export =`. // But for @babel/parser, `export default` is an ExportDefaultDeclaration, // so a TsExportAssignment is always `export =`. export type TsExportAssignment = NodeBase & { - type: "TSExportAssignment", - expression: Expression, + type: "TSExportAssignment"; + expression: Expression; }; export type TsNamespaceExportDeclaration = NodeBase & { - type: "TSNamespaceExportDeclaration", - id: Identifier, + type: "TSNamespaceExportDeclaration"; + id: Identifier; }; // ================ @@ -1620,37 +1615,37 @@ export type TsNamespaceExportDeclaration = NodeBase & { // ================ export type TsTypeAssertionLikeBase = NodeBase & { - expression: Expression, - typeAnnotation: TsType, + expression: Expression; + typeAnnotation: TsType; }; export type TsAsExpression = TsTypeAssertionLikeBase & { - type: "TSAsExpression", + type: "TSAsExpression"; }; export type TsTypeAssertion = TsTypeAssertionLikeBase & { - type: "TSTypeAssertion", + type: "TSTypeAssertion"; }; export type TsNonNullExpression = NodeBase & { - type: "TSNonNullExpression", - expression: Expression, + type: "TSNonNullExpression"; + expression: Expression; }; export type TsInstantiationExpression = NodeBase & { - type: "TSInstantiationExpression", - expression: Expression, - typeParameters: TsTypeParameterInstantiation, + type: "TSInstantiationExpression"; + expression: Expression; + typeParameters: TsTypeParameterInstantiation; }; // ================ // Babel placeholders %%foo%% // ================ -export type Placeholder = NodeBase & { - type: "Placeholder", - id: Identifier, - expectedNode: N, +export type Placeholder = NodeBase & { + type: "Placeholder"; + id: Identifier; + expectedNode: N; }; // ================ @@ -1658,12 +1653,12 @@ export type Placeholder = NodeBase & { // ================ export type ParseSubscriptState = { - optionalChainMember: boolean, - maybeAsyncArrow: boolean, - stop: boolean, + optionalChainMember: boolean; + maybeAsyncArrow: boolean; + stop: boolean; }; -export type ParseClassMemberState = {| - hadConstructor: boolean, - hadSuperClass: boolean, -|}; +export type ParseClassMemberState = { + hadConstructor: boolean; + hadSuperClass: boolean; +}; diff --git a/packages/babel-parser/src/util/class-scope.js b/packages/babel-parser/src/util/class-scope.ts similarity index 99% rename from packages/babel-parser/src/util/class-scope.js rename to packages/babel-parser/src/util/class-scope.ts index 41fc5e87dddb..ce3dabfc0ab0 100644 --- a/packages/babel-parser/src/util/class-scope.js +++ b/packages/babel-parser/src/util/class-scope.ts @@ -1,5 +1,3 @@ -// @flow - import { CLASS_ELEMENT_KIND_ACCESSOR, CLASS_ELEMENT_FLAG_STATIC, diff --git a/packages/babel-parser/src/util/expression-scope.js b/packages/babel-parser/src/util/expression-scope.ts similarity index 95% rename from packages/babel-parser/src/util/expression-scope.js rename to packages/babel-parser/src/util/expression-scope.ts index fee099aa74db..a7f7056de9c6 100644 --- a/packages/babel-parser/src/util/expression-scope.js +++ b/packages/babel-parser/src/util/expression-scope.ts @@ -1,5 +1,3 @@ -// @flow - import { Errors, type ParseErrorConstructor } from "../parse-error"; import { Position } from "./location"; import type { Node } from "../types"; @@ -79,21 +77,24 @@ class ExpressionScope { type ArrowHeadParsingParameterInitializerError = | typeof Errors.AwaitExpressionFormalParameter | typeof Errors.YieldInParameter; - type ArrowHeadParsingDeclarationError = | ArrowHeadParsingParameterInitializerError | typeof Errors.InvalidParenthesizedAssignment | typeof Errors.AwaitBindingIdentifier; class ArrowHeadParsingScope extends ExpressionScope { - declarationErrors: Map, Position]> = + declarationErrors: Map, Position]> = new Map(); constructor(type: 1 | 2) { super(type); } recordDeclarationError( - ParsingErrorClass: ParseErrorConstructor<{||}>, - { at }: { at: Position }, + ParsingErrorClass: ParseErrorConstructor<{}>, + { + at, + }: { + at: Position; + }, ) { const index = at.index; @@ -103,7 +104,7 @@ class ArrowHeadParsingScope extends ExpressionScope { this.declarationErrors.delete(index); } iterateErrors( - iterator: ([ArrowHeadParsingDeclarationError, Position]) => void, + iterator: (a: [ArrowHeadParsingDeclarationError, Position]) => void, ) { this.declarationErrors.forEach(iterator); } @@ -136,7 +137,11 @@ export default class ExpressionScopeHandler { */ recordParameterInitializerError( toParseError: ArrowHeadParsingParameterInitializerError, - { at: node }: { at: Node }, + { + at: node, + }: { + at: Node; + }, ): void { const origin = { at: node.loc.start }; const { stack } = this; @@ -180,8 +185,12 @@ export default class ExpressionScopeHandler { * @memberof ExpressionScopeHandler */ recordArrowParemeterBindingError( - error: ParseErrorConstructor<{||}>, - { at: node }: { at: Node }, + error: ParseErrorConstructor<{}>, + { + at: node, + }: { + at: Node; + }, ): void { const { stack } = this; const scope: ExpressionScope = stack[stack.length - 1]; diff --git a/packages/babel-parser/src/util/identifier.js b/packages/babel-parser/src/util/identifier.ts similarity index 99% rename from packages/babel-parser/src/util/identifier.js rename to packages/babel-parser/src/util/identifier.ts index 9295c43ae83f..bb86246f54be 100644 --- a/packages/babel-parser/src/util/identifier.js +++ b/packages/babel-parser/src/util/identifier.ts @@ -1,7 +1,5 @@ /* eslint max-len: 0 */ -// @flow - import * as charCodes from "charcodes"; import { isIdentifierStart } from "@babel/helper-validator-identifier"; diff --git a/packages/babel-parser/src/util/location.js b/packages/babel-parser/src/util/location.ts similarity index 95% rename from packages/babel-parser/src/util/location.js rename to packages/babel-parser/src/util/location.ts index 109a45c7e662..06dd6dcba3c4 100644 --- a/packages/babel-parser/src/util/location.js +++ b/packages/babel-parser/src/util/location.ts @@ -1,7 +1,5 @@ -// @flow - export type Pos = { - start: number, + start: number; }; // These are used when `options.locations` is on, for the @@ -23,7 +21,7 @@ export class SourceLocation { start: Position; end: Position; filename: string; - identifierName: ?string; + identifierName: string | undefined | null; constructor(start: Position, end?: Position) { this.start = start; diff --git a/packages/babel-parser/src/util/production-parameter.js b/packages/babel-parser/src/util/production-parameter.ts similarity index 87% rename from packages/babel-parser/src/util/production-parameter.js rename to packages/babel-parser/src/util/production-parameter.ts index 5ad1bf6bbc28..3b5f22cf730c 100644 --- a/packages/babel-parser/src/util/production-parameter.js +++ b/packages/babel-parser/src/util/production-parameter.ts @@ -1,8 +1,11 @@ -// @flow -export const PARAM = 0b0000, // Initial Parameter flags - PARAM_YIELD = 0b0001, // track [Yield] production parameter - PARAM_AWAIT = 0b0010, // track [Await] production parameter - PARAM_RETURN = 0b0100, // track [Return] production parameter +export const // Initial Parameter flags + PARAM = 0b0000, + // track [Yield] production parameter + PARAM_YIELD = 0b0001, + // track [Await] production parameter + PARAM_AWAIT = 0b0010, + // track [Return] production parameter + PARAM_RETURN = 0b0100, PARAM_IN = 0b1000; // track [In] production parameter // ProductionParameterHandler is a stack fashioned production parameter tracker diff --git a/packages/babel-parser/src/util/scope.js b/packages/babel-parser/src/util/scope.ts similarity index 98% rename from packages/babel-parser/src/util/scope.js rename to packages/babel-parser/src/util/scope.ts index 4f15035a1742..f4ff1789389e 100644 --- a/packages/babel-parser/src/util/scope.js +++ b/packages/babel-parser/src/util/scope.ts @@ -1,4 +1,3 @@ -// @flow import { SCOPE_ARROW, SCOPE_DIRECT_SUPER, @@ -38,7 +37,7 @@ export class Scope { // The functions in this module keep track of declared variables in the // current scope in order to detect duplicate variable names. -export default class ScopeHandler { +export default class ScopeHandler { parser: Tokenizer; scopeStack: Array = []; inModule: boolean; diff --git a/packages/babel-parser/src/util/scopeflags.js b/packages/babel-parser/src/util/scopeflags.ts similarity index 88% rename from packages/babel-parser/src/util/scopeflags.js rename to packages/babel-parser/src/util/scopeflags.ts index 924d94d40b96..9eb651ec04fd 100644 --- a/packages/babel-parser/src/util/scopeflags.js +++ b/packages/babel-parser/src/util/scopeflags.ts @@ -1,18 +1,6 @@ -// @flow - // Each scope gets a bitset that may contain these flags // prettier-ignore -export const SCOPE_OTHER = 0b000000000, - SCOPE_PROGRAM = 0b000000001, - SCOPE_FUNCTION = 0b000000010, - SCOPE_ARROW = 0b000000100, - SCOPE_SIMPLE_CATCH = 0b000001000, - SCOPE_SUPER = 0b000010000, - SCOPE_DIRECT_SUPER = 0b000100000, - SCOPE_CLASS = 0b001000000, - SCOPE_STATIC_BLOCK = 0b010000000, - SCOPE_TS_MODULE = 0b100000000, - SCOPE_VAR = SCOPE_PROGRAM | SCOPE_FUNCTION | SCOPE_TS_MODULE; +export const SCOPE_OTHER = 0b000000000, SCOPE_PROGRAM = 0b000000001, SCOPE_FUNCTION = 0b000000010, SCOPE_ARROW = 0b000000100, SCOPE_SIMPLE_CATCH = 0b000001000, SCOPE_SUPER = 0b000010000, SCOPE_DIRECT_SUPER = 0b000100000, SCOPE_CLASS = 0b001000000, SCOPE_STATIC_BLOCK = 0b010000000, SCOPE_TS_MODULE = 0b100000000, SCOPE_VAR = SCOPE_PROGRAM | SCOPE_FUNCTION | SCOPE_TS_MODULE; export type ScopeFlags = | typeof SCOPE_OTHER diff --git a/packages/babel-parser/src/util/whitespace.js b/packages/babel-parser/src/util/whitespace.ts similarity index 99% rename from packages/babel-parser/src/util/whitespace.js rename to packages/babel-parser/src/util/whitespace.ts index e13eb5c1f230..095fa9322899 100644 --- a/packages/babel-parser/src/util/whitespace.js +++ b/packages/babel-parser/src/util/whitespace.ts @@ -1,5 +1,3 @@ -// @flow - import * as charCodes from "charcodes"; // Matches a whole line break (where CRLF is considered a single diff --git a/tsconfig.json b/tsconfig.json index 90ad03b5a02e..dd860787b090 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,6 +39,7 @@ "./packages/babel-helpers/src/**/*.ts", "./packages/babel-highlight/src/**/*.ts", "./packages/babel-node/src/**/*.ts", + "./packages/babel-parser/src/**/*.ts", "./packages/babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/src/**/*.ts", "./packages/babel-plugin-bugfix-v8-spread-parameters-in-optional-chaining/src/**/*.ts", "./packages/babel-plugin-external-helpers/src/**/*.ts", @@ -279,6 +280,9 @@ "@babel/node": [ "./packages/babel-node/src" ], + "@babel/parser": [ + "./packages/babel-parser/src" + ], "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": [ "./packages/babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/src" ], From edba44e8b3673af9b3d3de04ee4883eee4343d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 20 Jul 2022 16:08:26 -0400 Subject: [PATCH 2/9] fix parser integration typing errors --- .../src/transformation/normalize-file.ts | 3 +- packages/babel-parser/src/index.ts | 14 ++++ packages/babel-parser/src/parser/base.ts | 10 +-- packages/babel-parser/src/plugin-utils.ts | 2 +- packages/babel-parser/src/typings.ts | 73 +++++++++++++++++++ packages/babel-template/src/parse.ts | 1 + .../babel-traverse/src/path/replacement.ts | 1 + 7 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 packages/babel-parser/src/typings.ts diff --git a/packages/babel-core/src/transformation/normalize-file.ts b/packages/babel-core/src/transformation/normalize-file.ts index ce9c0ae2df1e..6f9aa6230402 100644 --- a/packages/babel-core/src/transformation/normalize-file.ts +++ b/packages/babel-core/src/transformation/normalize-file.ts @@ -39,6 +39,7 @@ export default function* normalizeFile( ast = cloneDeep(ast) as t.File; } } else { + // @ts-expect-error todo: use babel-types ast typings in Babel parser ast = yield* parser(pluginPasses, options, code); } @@ -91,7 +92,7 @@ export default function* normalizeFile( return new File(options, { code, - ast, + ast: ast as t.File, inputMap, }); } diff --git a/packages/babel-parser/src/index.ts b/packages/babel-parser/src/index.ts index 2121db1bbc37..35641724fbd2 100644 --- a/packages/babel-parser/src/index.ts +++ b/packages/babel-parser/src/index.ts @@ -6,6 +6,12 @@ import { mixinPlugins, type PluginList, } from "./plugin-utils"; +import type { + PluginConfig as ParserPlugin, + FlowPluginOptions, + RecordAndTuplePluginOptions, + PipelineOperatorPluginOptions, +} from "./typings"; import Parser from "./parser"; import { getExportedToken, tt as internalTokenTypes } from "./tokenizer/types"; @@ -110,3 +116,11 @@ function getParserClass(pluginsFromOptions: PluginList): { } return cls; } + +export type { + FlowPluginOptions, + ParserPlugin, + PipelineOperatorPluginOptions, + RecordAndTuplePluginOptions, +}; +export type ParserOptions = Partial; diff --git a/packages/babel-parser/src/parser/base.ts b/packages/babel-parser/src/parser/base.ts index fcb2c6ece510..3a8fbd524685 100644 --- a/packages/babel-parser/src/parser/base.ts +++ b/packages/babel-parser/src/parser/base.ts @@ -5,6 +5,7 @@ import type ScopeHandler from "../util/scope"; import type ExpressionScopeHandler from "../util/expression-scope"; import type ClassScopeHandler from "../util/class-scope"; import type ProductionParameterHandler from "../util/production-parameter"; +import type { PluginConfig } from "../typings"; export default class BaseParser { // Properties set by constructor in index.js @@ -55,12 +56,3 @@ export default class BaseParser { return this.plugins.get(plugin)?.[name]; } } - -export type PluginConfig = - | string - | [ - string, - { - [x: string]: any; - }, - ]; diff --git a/packages/babel-parser/src/plugin-utils.ts b/packages/babel-parser/src/plugin-utils.ts index d36d691268ae..3054d5f99fc7 100644 --- a/packages/babel-parser/src/plugin-utils.ts +++ b/packages/babel-parser/src/plugin-utils.ts @@ -3,7 +3,7 @@ import type { PluginConfig } from "./parser/base"; export type Plugin = PluginConfig; -export type PluginList = ReadonlyArray; +export type PluginList = PluginConfig[]; export type MixinPlugin = (superClass: { new (...args: any): Parser }) => { new (...args: any): Parser; diff --git a/packages/babel-parser/src/typings.ts b/packages/babel-parser/src/typings.ts new file mode 100644 index 000000000000..54c0e8e07228 --- /dev/null +++ b/packages/babel-parser/src/typings.ts @@ -0,0 +1,73 @@ +export type PluginConfig = + | "asyncDoExpressions" + | "asyncGenerators" + | "bigInt" + | "classPrivateMethods" + | "classPrivateProperties" + | "classProperties" + | "classStaticBlock" // Enabled by default + | "decimal" + | "decorators" + | "decorators-legacy" + | "decoratorAutoAccessors" + | "destructuringPrivate" + | "doExpressions" + | "dynamicImport" + | "estree" + | "exportDefaultFrom" + | "exportNamespaceFrom" // deprecated + | "flow" + | "flowComments" + | "functionBind" + | "functionSent" + | "importMeta" + | "jsx" + | "logicalAssignment" + | "importAssertions" + | "moduleBlocks" + | "moduleStringNames" + | "nullishCoalescingOperator" + | "numericSeparator" + | "objectRestSpread" + | "optionalCatchBinding" + | "optionalChaining" + | "partialApplication" + | "pipelineOperator" + | "placeholders" + | "privateIn" // Enabled by default + | "regexpUnicodeSets" + | "throwExpressions" + | "topLevelAwait" + | "typescript" + | "v8intrinsic" + | ParserPluginWithOptions; + +export type ParserPluginWithOptions = + | ["decorators", DecoratorsPluginOptions] + | ["pipelineOperator", PipelineOperatorPluginOptions] + | ["recordAndTuple", RecordAndTuplePluginOptions] + | ["flow", FlowPluginOptions] + | ["typescript", TypeScriptPluginOptions]; + +export interface DecoratorsPluginOptions { + decoratorsBeforeExport?: boolean; +} + +export interface PipelineOperatorPluginOptions { + proposal: "minimal" | "fsharp" | "hack" | "smart"; + topicToken?: "%" | "#" | "@@" | "^^" | "^"; +} + +export interface RecordAndTuplePluginOptions { + syntaxType: "bar" | "hash"; +} + +export interface FlowPluginOptions { + all?: boolean; + enums?: boolean; +} + +export interface TypeScriptPluginOptions { + dts?: boolean; + disallowAmbiguousJSXLike?: boolean; +} diff --git a/packages/babel-template/src/parse.ts b/packages/babel-template/src/parse.ts index 2fd61025ac2f..3e9e958b8d74 100644 --- a/packages/babel-template/src/parse.ts +++ b/packages/babel-template/src/parse.ts @@ -221,6 +221,7 @@ function parseWithCodeFrame( }; try { + // @ts-expect-error todo: use babel-types ast typings in Babel parser return parse(code, parserOpts); } catch (err) { const loc = err.loc; diff --git a/packages/babel-traverse/src/path/replacement.ts b/packages/babel-traverse/src/path/replacement.ts index 5c851f8183d5..71f23f13ddfd 100644 --- a/packages/babel-traverse/src/path/replacement.ts +++ b/packages/babel-traverse/src/path/replacement.ts @@ -75,6 +75,7 @@ export function replaceWithSourceString(this: NodePath, replacement: string) { try { replacement = `(${replacement})`; + // @ts-expect-error todo: use babel-types ast typings in Babel parser ast = parse(replacement); } catch (err) { const loc = err.loc; From 3772d5d0c1c2cbf88df7b653ae230c4bc66d63b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 20 Jul 2022 16:17:07 -0400 Subject: [PATCH 3/9] chore: remove unused $FlowIgnore --- packages/babel-cli/src/babel/file.ts | 1 - packages/babel-cli/src/babel/options.ts | 1 - packages/babel-plugin-transform-unicode-escapes/src/index.ts | 1 - packages/babel-preset-env/src/filter-items.ts | 1 - packages/babel-preset-env/src/polyfills/babel-polyfill.ts | 2 -- 5 files changed, 6 deletions(-) diff --git a/packages/babel-cli/src/babel/file.ts b/packages/babel-cli/src/babel/file.ts index 63222479cfbd..16bdb03fe3d7 100644 --- a/packages/babel-cli/src/babel/file.ts +++ b/packages/babel-cli/src/babel/file.ts @@ -116,7 +116,6 @@ export default async function ({ process.stdin.on("readable", function () { const chunk = process.stdin.read(); - // $FlowIgnore if (chunk !== null) code += chunk; }); diff --git a/packages/babel-cli/src/babel/options.ts b/packages/babel-cli/src/babel/options.ts index 38d35f9a07fa..98842f8e4a4a 100644 --- a/packages/babel-cli/src/babel/options.ts +++ b/packages/babel-cli/src/babel/options.ts @@ -311,7 +311,6 @@ export default function parseArgv(args: Array): CmdOptions | null { }; if (!process.env.BABEL_8_BREAKING) { - // $FlowIgnore Object.assign(babelOptions, { moduleRoot: opts.moduleRoot, moduleIds: opts.moduleIds, diff --git a/packages/babel-plugin-transform-unicode-escapes/src/index.ts b/packages/babel-plugin-transform-unicode-escapes/src/index.ts index da962b899f38..0a45651c849e 100644 --- a/packages/babel-plugin-transform-unicode-escapes/src/index.ts +++ b/packages/babel-plugin-transform-unicode-escapes/src/index.ts @@ -49,7 +49,6 @@ export default declare(api => { if (!generatorOpts.jsescOption) { generatorOpts.jsescOption = {}; } - // $FlowIgnore: Flow does not support logical assignment generatorOpts.jsescOption.minimal ??= false; }, visitor: { diff --git a/packages/babel-preset-env/src/filter-items.ts b/packages/babel-preset-env/src/filter-items.ts index 9393ed8261c3..2ff3508dbbb4 100644 --- a/packages/babel-preset-env/src/filter-items.ts +++ b/packages/babel-preset-env/src/filter-items.ts @@ -1,7 +1,6 @@ import semver from "semver"; import { minVersions } from "./available-plugins"; -// $FlowIgnore const has = Function.call.bind(Object.hasOwnProperty); export function addProposalSyntaxPlugins( diff --git a/packages/babel-preset-env/src/polyfills/babel-polyfill.ts b/packages/babel-preset-env/src/polyfills/babel-polyfill.ts index 948b3159d949..0098d5b57b49 100644 --- a/packages/babel-preset-env/src/polyfills/babel-polyfill.ts +++ b/packages/babel-preset-env/src/polyfills/babel-polyfill.ts @@ -21,7 +21,6 @@ export default function ( ImportDeclaration(path: NodePath) { const src = getImportSource(path); if (usage && isPolyfillSource(src)) { - // $FlowIgnore console.warn(NO_DIRECT_POLYFILL_IMPORT.replace("SPECIFIER", src)); if (!deprecated) path.remove(); } else if (src === "@babel/polyfill") { @@ -43,7 +42,6 @@ export default function ( path.get("body").forEach(bodyPath => { const src = getRequireSource(bodyPath); if (usage && isPolyfillSource(src)) { - // $FlowIgnore console.warn(NO_DIRECT_POLYFILL_IMPORT.replace("SPECIFIER", src)); if (!deprecated) bodyPath.remove(); } else if (src === "@babel/polyfill") { From 4466730d2c2c22247ab02513f1fc1853992588f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Thu, 21 Jul 2022 12:41:51 -0400 Subject: [PATCH 4/9] fix parser-error typing errors --- packages/babel-parser/src/parse-error.ts | 52 +++++++++---------- .../src/parse-error/credentials.ts | 18 ++++--- .../parse-error/pipeline-operator-errors.ts | 9 ++-- .../src/parse-error/standard-errors.ts | 1 - .../src/parse-error/to-node-description.ts | 4 +- 5 files changed, 46 insertions(+), 38 deletions(-) diff --git a/packages/babel-parser/src/parse-error.ts b/packages/babel-parser/src/parse-error.ts index 4a55588a7171..74cdf5fdaa7c 100644 --- a/packages/babel-parser/src/parse-error.ts +++ b/packages/babel-parser/src/parse-error.ts @@ -45,7 +45,7 @@ export type ParseErrorConstructor = (a: { details: ErrorDetails; }) => ParseError; -function toParseErrorConstructor({ +function toParseErrorConstructor({ toMessage, ...properties }: ParseErrorCredentials): ParseErrorConstructor { @@ -55,7 +55,7 @@ function toParseErrorConstructor({ }; return function constructor({ loc, details }: ConstructorArgument) { - return instantiate>( + return instantiate>( SyntaxError, { ...properties, loc }, { @@ -68,8 +68,11 @@ function toParseErrorConstructor({ const loc = overrides.loc || {}; return constructor({ loc: new Position( + // @ts-expect-error line has been guarded "line" in loc ? loc.line : this.loc.line, + // @ts-expect-error column has been guarded "column" in loc ? loc.column : this.loc.column, + // @ts-expect-error index has been guarded "index" in loc ? loc.index : this.loc.index, ), details: { ...this.details, ...overrides.details }, @@ -77,7 +80,7 @@ function toParseErrorConstructor({ }, details: { value: details, enumerable: false }, message: { - get() { + get(this: ConstructorArgument): string { return `${toMessage(this.details)} (${this.loc.line}:${ this.loc.column })`; @@ -108,9 +111,9 @@ export // This part is tricky. You'll probably notice from the name of this func // to the type system, avoiding the need to do so with $ObjMap (which doesn't // work) in `ParseErrorEnum`. This hack won't be necessary when we switch to // Typescript. -function toParseErrorCredentials( - b: T, - a: +function toParseErrorCredentials( + b: string, + a?: | { code?: ParseErrorCode; reasonCode?: string; @@ -120,13 +123,9 @@ function toParseErrorCredentials( | boolean, ): ParseErrorConstructor<{}>; -export // ESLint seems to erroneously think that Flow's overloading syntax is an -// accidental redeclaration of the function: -// https://github.com/babel/eslint-plugin-babel/issues/162 -// eslint-disable-next-line no-redeclare -function toParseErrorCredentials( +export function toParseErrorCredentials( b: (a: ErrorDetails) => string, - a: + a?: | { code?: ParseErrorCode; reasonCode?: string; @@ -136,9 +135,10 @@ function toParseErrorCredentials( | boolean, ): ParseErrorConstructor; -// See comment about eslint and Flow overloading above. -// eslint-disable-next-line no-redeclare -export function toParseErrorCredentials(toMessageOrMessage, credentials) { +export function toParseErrorCredentials( + toMessageOrMessage: string | ((details: unknown) => string), + credentials: any, +) { return { toMessage: typeof toMessageOrMessage === "string" @@ -149,14 +149,11 @@ export function toParseErrorCredentials(toMessageOrMessage, credentials) { } export // This is the templated form. -function ParseErrorEnum(a: string[]): typeof ParseErrorEnum; +function ParseErrorEnum(a: TemplateStringsArray): typeof ParseErrorEnum; -export // See comment about eslint and Flow overloading above. -// eslint-disable-next-line no-redeclare -function ParseErrorEnum( - toParseErrorCredentials: (a: typeof toParseErrorCredentials) => T, - syntaxPlugin?: string, -): T; +export function ParseErrorEnum< + T extends (a: typeof toParseErrorCredentials) => unknown, +>(toParseErrorCredentials: T, syntaxPlugin?: string): ReturnType; // You call `ParseErrorEnum` with a mapping from `ReasonCode`'s to either error // messages, or `toMessage` functions that define additional necessary `details` @@ -167,19 +164,20 @@ function ParseErrorEnum( // ErrorWithDynamicMessage: _<{ type: string }>(({ type }) => `${type}`), // }); // -// See comment about eslint and Flow overloading above. -// eslint-disable-next-line no-redeclare -export function ParseErrorEnum(argument, syntaxPlugin) { +export function ParseErrorEnum(argument: any, syntaxPlugin?: string) { // If the first parameter is an array, that means we were called with a tagged // template literal. Extract the syntaxPlugin from this, and call again in // the "normalized" form. if (Array.isArray(argument)) { - return toParseErrorCredentialsMap => + return (toParseErrorCredentialsMap: any) => ParseErrorEnum(toParseErrorCredentialsMap, argument[0]); } const partialCredentials = argument(toParseErrorCredentials); - const ParseErrorConstructors = {}; + const ParseErrorConstructors = {} as Record< + string, + ParseErrorConstructor + >; for (const reasonCode of Object.keys(partialCredentials)) { ParseErrorConstructors[reasonCode] = toParseErrorConstructor({ diff --git a/packages/babel-parser/src/parse-error/credentials.ts b/packages/babel-parser/src/parse-error/credentials.ts index 9ddca01f1699..e793af3c2425 100644 --- a/packages/babel-parser/src/parse-error/credentials.ts +++ b/packages/babel-parser/src/parse-error/credentials.ts @@ -23,19 +23,25 @@ export type ParseErrorCredentials = { }; const reflect = (keys: string[], last = keys.length - 1) => ({ - get() { - return keys.reduce((object, key) => object[key], this); + get(): unknown { + return keys.reduce( + (object, key) => + // @ts-expect-error key should index object + object[key], + this, + ); }, - set(value) { + set(value: unknown) { keys.reduce( + // @ts-expect-error key should index item (item, key, i) => (i === last ? (item[key] = value) : item[key]), this, ); }, }); -const instantiate = ( - constructor: () => any, +const instantiate = ( + constructor: new () => T, properties: any, descriptors: any, ) => @@ -56,7 +62,7 @@ const instantiate = ( configurable: true, ...descriptor, }), - Object.assign(new constructor() as T, properties), + Object.assign(new constructor() as U, properties), ); export { instantiate }; diff --git a/packages/babel-parser/src/parse-error/pipeline-operator-errors.ts b/packages/babel-parser/src/parse-error/pipeline-operator-errors.ts index fd6a1c0e67a5..c1edbf3c3426 100644 --- a/packages/babel-parser/src/parse-error/pipeline-operator-errors.ts +++ b/packages/babel-parser/src/parse-error/pipeline-operator-errors.ts @@ -1,12 +1,15 @@ import { toParseErrorCredentials } from "../parse-error"; import toNodeDescription from "./to-node-description"; -export const UnparenthesizedPipeBodyDescriptions = new Set([ +const UnparenthesizedPipeBodyDescriptionsList = [ "ArrowFunctionExpression", "AssignmentExpression", "ConditionalExpression", "YieldExpression", -]); +] as const; +export const UnparenthesizedPipeBodyDescriptions = new Set( + UnparenthesizedPipeBodyDescriptionsList, +); export default (_: typeof toParseErrorCredentials) => ({ // This error is only used by the smart-mix proposal @@ -29,7 +32,7 @@ export default (_: typeof toParseErrorCredentials) => ({ "Hack-style pipe body does not contain a topic reference; Hack-style pipes must use topic at least once.", ), PipeUnparenthesizedBody: _<{ - type: string; + type: typeof UnparenthesizedPipeBodyDescriptionsList[number]; }>( ({ type }) => `Hack-style pipe body cannot be an unparenthesized ${toNodeDescription({ diff --git a/packages/babel-parser/src/parse-error/standard-errors.ts b/packages/babel-parser/src/parse-error/standard-errors.ts index e1954852500d..883d816dd0d9 100644 --- a/packages/babel-parser/src/parse-error/standard-errors.ts +++ b/packages/babel-parser/src/parse-error/standard-errors.ts @@ -15,7 +15,6 @@ export type LValAncestor = | "FormalParameters" | "ForInStatement" | "ForStatement" - | "Identfier" | "ObjectPattern" | "RestElement" | "VariableDeclarator"; diff --git a/packages/babel-parser/src/parse-error/to-node-description.ts b/packages/babel-parser/src/parse-error/to-node-description.ts index 41577e925e9e..99055bcae484 100644 --- a/packages/babel-parser/src/parse-error/to-node-description.ts +++ b/packages/babel-parser/src/parse-error/to-node-description.ts @@ -4,6 +4,7 @@ const NodeDescriptions = { AssignmentPattern: "assignment expression", ArrowFunctionExpression: "arrow function expression", ConditionalExpression: "conditional expression", + CatchClause: "catch clause", ForOfStatement: "for-of statement", ForInStatement: "for-in statement", ForStatement: "for-loop", @@ -34,10 +35,11 @@ type NodeWithDescription = type: NodeTypesWithDescriptions; }; +// @ts-expect-error prefix is specified only when type is UpdateExpression // eslint-disable-next-line no-confusing-arrow const toNodeDescription = ({ type, prefix }: NodeWithDescription) => type === "UpdateExpression" - ? NodeDescriptions.UpdateExpression[String(prefix)] + ? NodeDescriptions.UpdateExpression[String(prefix) as "true" | "false"] : NodeDescriptions[type]; export default toNodeDescription; From 542ca359ee8af75025072e8225a8920a64973c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Thu, 21 Jul 2022 13:29:48 -0400 Subject: [PATCH 5/9] fix tokenizer types optimizer --- babel.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/babel.config.js b/babel.config.js index f4e2a8bcadb0..474d538db65d 100644 --- a/babel.config.js +++ b/babel.config.js @@ -742,7 +742,7 @@ function pluginAddImportExtension() { } const tokenTypesMapping = new Map(); -const tokenTypeSourcePath = "./packages/babel-parser/src/tokenizer/types.js"; +const tokenTypeSourcePath = "./packages/babel-parser/src/tokenizer/types.ts"; function pluginBabelParserTokenType({ types: { isIdentifier, numericLiteral }, @@ -777,7 +777,7 @@ function pluginBabelParserTokenType({ }), { configFile: false, - parserOpts: { attachComments: false, plugins: ["flow"] }, + parserOpts: { attachComments: false, plugins: ["typescript"] }, } ); From 120e5d604dba439ba0587dc38b8249ddc672e24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Fri, 22 Jul 2022 12:56:14 -0400 Subject: [PATCH 6/9] fix parser core typing errors --- packages/babel-parser/src/index.ts | 13 +- packages/babel-parser/src/options.ts | 1 + packages/babel-parser/src/parse-error.ts | 3 +- .../src/parse-error/standard-errors.ts | 3 + .../src/parse-error/to-node-description.ts | 3 + packages/babel-parser/src/parser/base.ts | 4 +- .../babel-parser/src/parser/expression.ts | 465 +++++++++++----- packages/babel-parser/src/parser/index.ts | 6 +- packages/babel-parser/src/parser/lval.ts | 93 ++-- packages/babel-parser/src/parser/node.ts | 34 +- packages/babel-parser/src/parser/statement.ts | 517 ++++++++++++------ packages/babel-parser/src/parser/util.ts | 9 +- packages/babel-parser/src/plugin-utils.ts | 11 +- packages/babel-parser/src/tokenizer/index.ts | 35 +- packages/babel-parser/src/tokenizer/state.ts | 15 +- packages/babel-parser/src/tokenizer/types.ts | 6 +- packages/babel-parser/src/types.ts | 128 +++-- packages/babel-parser/src/typings.ts | 10 +- .../babel-parser/src/util/expression-scope.ts | 8 +- packages/babel-parser/src/util/location.ts | 2 +- .../src/util/production-parameter.ts | 9 +- packages/babel-parser/src/util/scope.ts | 6 +- 22 files changed, 891 insertions(+), 490 deletions(-) diff --git a/packages/babel-parser/src/index.ts b/packages/babel-parser/src/index.ts index 35641724fbd2..be5a26a05e28 100644 --- a/packages/babel-parser/src/index.ts +++ b/packages/babel-parser/src/index.ts @@ -14,7 +14,12 @@ import type { } from "./typings"; import Parser from "./parser"; -import { getExportedToken, tt as internalTokenTypes } from "./tokenizer/types"; +import { + ExportedTokenType, + getExportedToken, + tt as internalTokenTypes, + type InternalTokenTypes, +} from "./tokenizer/types"; import "./tokenizer/context"; import type { Expression, File } from "./types"; @@ -71,8 +76,10 @@ export function parseExpression(input: string, options?: Options): Expression { return parser.getExpression(); } -function generateExportedTokenTypes(internalTokenTypes) { - const tokenTypes = {}; +function generateExportedTokenTypes( + internalTokenTypes: InternalTokenTypes, +): Record { + const tokenTypes: Record = {}; for (const typeName of Object.keys(internalTokenTypes)) { tokenTypes[typeName] = getExportedToken(internalTokenTypes[typeName]); } diff --git a/packages/babel-parser/src/options.ts b/packages/babel-parser/src/options.ts index b31c14174338..ec729544d8c3 100644 --- a/packages/babel-parser/src/options.ts +++ b/packages/babel-parser/src/options.ts @@ -81,6 +81,7 @@ export const defaultOptions: Options = { export function getOptions(opts?: Options | null): Options { const options: any = {}; for (const key of Object.keys(defaultOptions)) { + // @ts-expect-error key may not exist in opts options[key] = opts && opts[key] != null ? opts[key] : defaultOptions[key]; } return options; diff --git a/packages/babel-parser/src/parse-error.ts b/packages/babel-parser/src/parse-error.ts index 74cdf5fdaa7c..a0934a211446 100644 --- a/packages/babel-parser/src/parse-error.ts +++ b/packages/babel-parser/src/parse-error.ts @@ -6,6 +6,7 @@ import { ParseErrorCodes, type ParseErrorCredentials, } from "./parse-error/credentials"; +import type { Undone } from "../src/parser/node"; // Babel uses "normal" SyntaxErrors for it's errors, but adds some extra // functionality. This functionality is defined in the @@ -192,7 +193,7 @@ export function ParseErrorEnum(argument: any, syntaxPlugin?: string) { } export type RaiseProperties = { - at: Position | NodeBase; + at: Position | Undone; } & ErrorDetails; import ModuleErrors from "./parse-error/module-errors"; diff --git a/packages/babel-parser/src/parse-error/standard-errors.ts b/packages/babel-parser/src/parse-error/standard-errors.ts index 883d816dd0d9..5457ed56a97e 100644 --- a/packages/babel-parser/src/parse-error/standard-errors.ts +++ b/packages/babel-parser/src/parse-error/standard-errors.ts @@ -15,6 +15,9 @@ export type LValAncestor = | "FormalParameters" | "ForInStatement" | "ForStatement" + | "ImportSpecifier" + | "ImportNamespaceSpecifier" + | "ImportDefaultSpecifier" | "ObjectPattern" | "RestElement" | "VariableDeclarator"; diff --git a/packages/babel-parser/src/parse-error/to-node-description.ts b/packages/babel-parser/src/parse-error/to-node-description.ts index 99055bcae484..6fa5e816a490 100644 --- a/packages/babel-parser/src/parse-error/to-node-description.ts +++ b/packages/babel-parser/src/parse-error/to-node-description.ts @@ -10,6 +10,9 @@ const NodeDescriptions = { ForStatement: "for-loop", FormalParameters: "function parameter list", Identifier: "identifier", + ImportSpecifier: "import specifier", + ImportDefaultSpecifier: "import default specifier", + ImportNamespaceSpecifier: "import namespace specifier", ObjectPattern: "object destructuring pattern", ParenthesizedExpression: "parenthesized expression", RestElement: "rest element", diff --git a/packages/babel-parser/src/parser/base.ts b/packages/babel-parser/src/parser/base.ts index 3a8fbd524685..5158a34f2a0a 100644 --- a/packages/babel-parser/src/parser/base.ts +++ b/packages/babel-parser/src/parser/base.ts @@ -43,7 +43,9 @@ export default class BaseParser { return false; } const actualOptions = this.plugins.get(pluginName); - for (const key of Object.keys(pluginOptions)) { + for (const key of Object.keys( + pluginOptions, + ) as (keyof typeof pluginOptions)[]) { if (actualOptions?.[key] !== pluginOptions[key]) { return false; } diff --git a/packages/babel-parser/src/parser/expression.ts b/packages/babel-parser/src/parser/expression.ts index f2ac4fc62551..9d3569e45ed9 100644 --- a/packages/babel-parser/src/parser/expression.ts +++ b/packages/babel-parser/src/parser/expression.ts @@ -68,7 +68,8 @@ import { import { Errors, type ParseError } from "../parse-error"; import { UnparenthesizedPipeBodyDescriptions } from "../parse-error/pipeline-operator-errors"; import { setInnerComments } from "./comments"; -import { cloneIdentifier } from "./node"; +import { cloneIdentifier, type Undone } from "./node"; +import type Parser from "."; /*:: import type { SourceType } from "../options"; @@ -127,7 +128,7 @@ export default class ExpressionParser extends LValParser { prop.type === "SpreadElement" || this.isObjectMethod(prop) || prop.computed || - // $FlowIgnore + // @ts-expect-error prop.shorthand ) { return; @@ -165,7 +166,7 @@ export default class ExpressionParser extends LValParser { } // Convenience method to parse an Expression only - getExpression(): N.Expression & N.ParserOutput { + getExpression(this: Parser): N.Expression & N.ParserOutput { this.enterInitialScopes(); this.nextToken(); const expr = this.parseExpression(); @@ -180,6 +181,7 @@ export default class ExpressionParser extends LValParser { if (this.options.tokens) { expr.tokens = this.tokens; } + // @ts-expect-error fixme: refine types return expr; } @@ -203,6 +205,7 @@ export default class ExpressionParser extends LValParser { // delayed syntax error at correct position). parseExpression( + this: Parser, disallowIn?: boolean, refExpressionErrors?: ExpressionErrors, ): N.Expression { @@ -215,7 +218,10 @@ export default class ExpressionParser extends LValParser { } // https://tc39.es/ecma262/#prod-Expression - parseExpressionBase(refExpressionErrors?: ExpressionErrors): N.Expression { + parseExpressionBase( + this: Parser, + refExpressionErrors?: ExpressionErrors, + ): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const expr = this.parseMaybeAssign(refExpressionErrors); @@ -233,6 +239,7 @@ export default class ExpressionParser extends LValParser { // Set [~In] parameter for assignment expression parseMaybeAssignDisallowIn( + this: Parser, refExpressionErrors?: ExpressionErrors | null, afterLeftParse?: Function, ) { @@ -243,6 +250,7 @@ export default class ExpressionParser extends LValParser { // Set [+In] parameter for assignment expression parseMaybeAssignAllowIn( + this: Parser, refExpressionErrors?: ExpressionErrors | null, afterLeftParse?: Function, ) { @@ -265,6 +273,7 @@ export default class ExpressionParser extends LValParser { // operators like `+=`. // https://tc39.es/ecma262/#prod-AssignmentExpression parseMaybeAssign( + this: Parser, refExpressionErrors?: ExpressionErrors | null, afterLeftParse?: Function, ): N.Expression { @@ -298,7 +307,7 @@ export default class ExpressionParser extends LValParser { left = afterLeftParse.call(this, left, startPos, startLoc); } if (tokenIsAssignment(this.state.type)) { - const node = this.startNodeAt(startPos, startLoc); + const node = this.startNodeAt(startPos, startLoc); const operator = this.state.value; node.operator = operator; @@ -345,7 +354,10 @@ export default class ExpressionParser extends LValParser { // Parse a ternary conditional (`?:`) operator. // https://tc39.es/ecma262/#prod-ConditionalExpression - parseMaybeConditional(refExpressionErrors: ExpressionErrors): N.Expression { + parseMaybeConditional( + this: Parser, + refExpressionErrors: ExpressionErrors, + ): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const potentialArrowAt = this.state.potentialArrowAt; @@ -359,10 +371,11 @@ export default class ExpressionParser extends LValParser { } parseConditional( + this: Parser, expr: N.Expression, startPos: number, startLoc: Position, - // eslint-disable-next-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars refExpressionErrors?: ExpressionErrors | null, ): N.Expression { if (this.eat(tt.question)) { @@ -377,6 +390,7 @@ export default class ExpressionParser extends LValParser { } parseMaybeUnaryOrPrivate( + this: Parser, refExpressionErrors?: ExpressionErrors, ): N.Expression | N.PrivateName { return this.match(tt.privateName) @@ -387,7 +401,10 @@ export default class ExpressionParser extends LValParser { // Start the precedence parser. // https://tc39.es/ecma262/#prod-ShortCircuitExpression - parseExprOps(refExpressionErrors: ExpressionErrors): N.Expression { + parseExprOps( + this: Parser, + refExpressionErrors: ExpressionErrors, + ): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const potentialArrowAt = this.state.potentialArrowAt; @@ -407,6 +424,7 @@ export default class ExpressionParser extends LValParser { // operator that has a lower precedence than the set it is parsing. parseExprOp( + this: Parser, left: N.Expression | N.PrivateName, leftStartPos: number, leftStartLoc: Position, @@ -444,7 +462,10 @@ export default class ExpressionParser extends LValParser { } this.checkPipelineAtInfixOperator(left, leftStartLoc); } - const node = this.startNodeAt(leftStartPos, leftStartLoc); + const node = this.startNodeAt( + leftStartPos, + leftStartLoc, + ); node.left = left; node.operator = this.state.value; @@ -471,7 +492,7 @@ export default class ExpressionParser extends LValParser { } node.right = this.parseExprOpRightExpr(op, prec); - this.finishNode( + const finishedNode = this.finishNode( node, logical || coalesce ? "LogicalExpression" : "BinaryExpression", ); @@ -490,7 +511,12 @@ export default class ExpressionParser extends LValParser { }); } - return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec); + return this.parseExprOp( + finishedNode, + leftStartPos, + leftStartLoc, + minPrec, + ); } } return left; @@ -499,7 +525,11 @@ export default class ExpressionParser extends LValParser { // Helper function for `parseExprOp`. Parse the right-hand side of binary- // operator expressions, then apply any operator-specific functions. - parseExprOpRightExpr(op: TokenType, prec: number): N.Expression { + parseExprOpRightExpr( + this: Parser, + op: TokenType, + prec: number, + ): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; switch (op) { @@ -539,7 +569,11 @@ export default class ExpressionParser extends LValParser { // Helper function for `parseExprOpRightExpr`. Parse the right-hand side of // binary-operator expressions without applying any operator-specific functions. - parseExprOpBaseRightExpr(op: TokenType, prec: number): N.Expression { + parseExprOpBaseRightExpr( + this: Parser, + op: TokenType, + prec: number, + ): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; @@ -551,7 +585,7 @@ export default class ExpressionParser extends LValParser { ); } - parseHackPipeBody(): N.Expression { + parseHackPipeBody(this: Parser): N.Expression { const { startLoc } = this.state; const body = this.parseMaybeAssign(); const requiredParentheses = UnparenthesizedPipeBodyDescriptions.has( @@ -573,7 +607,9 @@ export default class ExpressionParser extends LValParser { return body; } - checkExponentialAfterUnary(node: N.AwaitExpression | N.UnaryExpression) { + checkExponentialAfterUnary( + node: N.AwaitExpression | Undone, + ) { if (this.match(tt.exponent)) { this.raise(Errors.UnexpectedTokenUnaryExponentiation, { at: node.argument, @@ -584,6 +620,7 @@ export default class ExpressionParser extends LValParser { // Parse unary operators, both prefix and postfix. // https://tc39.es/ecma262/#prod-UnaryExpression parseMaybeUnary( + this: Parser, refExpressionErrors?: ExpressionErrors | null, sawUnary?: boolean, ): N.Expression { @@ -598,7 +635,7 @@ export default class ExpressionParser extends LValParser { return expr; } const update = this.match(tt.incDec); - const node = this.startNode(); + const node = this.startNode(); if (tokenIsPrefix(this.state.type)) { node.operator = this.state.value; node.prefix = true; @@ -624,7 +661,9 @@ export default class ExpressionParser extends LValParser { } if (!update) { - if (!sawUnary) this.checkExponentialAfterUnary(node); + if (!sawUnary) { + this.checkExponentialAfterUnary(node as Undone); + } return this.finishNode(node, "UnaryExpression"); } } @@ -647,13 +686,17 @@ export default class ExpressionParser extends LValParser { // https://tc39.es/ecma262/#prod-UpdateExpression parseUpdate( + this: Parser, node: N.Expression, update: boolean, refExpressionErrors?: ExpressionErrors | null, ): N.Expression { if (update) { - this.checkLVal(node.argument, { - in: this.finishNode(node, "UpdateExpression"), + this.checkLVal((node as Undone).argument, { + in: this.finishNode( + node as Undone, + "UpdateExpression", + ), }); return node; } @@ -663,7 +706,7 @@ export default class ExpressionParser extends LValParser { let expr = this.parseExprSubscripts(refExpressionErrors); if (this.checkExpressionErrors(refExpressionErrors, false)) return expr; while (tokenIsPostfix(this.state.type) && !this.canInsertSemicolon()) { - const node = this.startNodeAt(startPos, startLoc); + const node = this.startNodeAt(startPos, startLoc); node.operator = this.state.value; node.prefix = false; node.argument = expr; @@ -678,6 +721,7 @@ export default class ExpressionParser extends LValParser { // Parse call, dot, and `[]`-subscript expressions. // https://tc39.es/ecma262/#prod-LeftHandSideExpression parseExprSubscripts( + this: Parser, refExpressionErrors?: ExpressionErrors | null, ): N.Expression { const startPos = this.state.start; @@ -693,6 +737,7 @@ export default class ExpressionParser extends LValParser { } parseSubscripts( + this: Parser, base: N.Expression, startPos: number, startLoc: Position, @@ -717,6 +762,7 @@ export default class ExpressionParser extends LValParser { * state.optionalChainMember to indicate that the member is currently in OptionalChain */ parseSubscript( + this: Parser, base: N.Expression, startPos: number, startLoc: Position, @@ -778,6 +824,7 @@ export default class ExpressionParser extends LValParser { // base[?Yield, ?Await] . PrivateIdentifier // where `base` is one of CallExpression, MemberExpression and OptionalChain parseMember( + this: Parser, base: N.Expression, startPos: number, startLoc: Position, @@ -785,7 +832,9 @@ export default class ExpressionParser extends LValParser { computed: boolean, optional: boolean, ): N.OptionalMemberExpression | N.MemberExpression { - const node = this.startNodeAt(startPos, startLoc); + const node = this.startNodeAt< + N.OptionalMemberExpression | N.MemberExpression + >(startPos, startLoc); node.object = base; node.computed = computed; if (computed) { @@ -802,7 +851,7 @@ export default class ExpressionParser extends LValParser { } if (state.optionalChainMember) { - node.optional = optional; + (node as N.OptionalMemberExpression).optional = optional; return this.finishNode(node, "OptionalMemberExpression"); } else { return this.finishNode(node, "MemberExpression"); @@ -811,6 +860,7 @@ export default class ExpressionParser extends LValParser { // https://github.com/tc39/proposal-bind-operator#syntax parseBind( + this: Parser, base: N.Expression, startPos: number, startLoc: Position, @@ -835,6 +885,7 @@ export default class ExpressionParser extends LValParser { // CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] // OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] parseCoverCallAndAsyncArrowHead( + this: Parser, base: N.Expression, startPos: number, startLoc: Position, @@ -842,12 +893,15 @@ export default class ExpressionParser extends LValParser { optional: boolean, ): N.Expression { const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; - let refExpressionErrors = null; + let refExpressionErrors: ExpressionErrors | null = null; this.state.maybeInArrowParameters = true; this.next(); // eat `(` - let node = this.startNodeAt(startPos, startLoc); + const node = this.startNodeAt( + startPos, + startLoc, + ); node.callee = base; const { maybeAsyncArrow, optionalChainMember } = state; @@ -857,6 +911,7 @@ export default class ExpressionParser extends LValParser { } if (optionalChainMember) { + // @ts-expect-error when optionalChainMember is true, node must be an optional call node.optional = optional; } @@ -871,7 +926,13 @@ export default class ExpressionParser extends LValParser { refExpressionErrors, ); } - this.finishCallExpression(node, optionalChainMember); + let finishedNode: + | N.CallExpression + | N.OptionalCallExpression + | N.ArrowFunctionExpression = this.finishCallExpression( + node, + optionalChainMember, + ); if (maybeAsyncArrow && this.shouldParseAsyncArrow() && !optional) { /*:: invariant(refExpressionErrors != null) */ @@ -879,21 +940,21 @@ export default class ExpressionParser extends LValParser { this.checkDestructuringPrivate(refExpressionErrors); this.expressionScope.validateAsPattern(); this.expressionScope.exit(); - node = this.parseAsyncArrowFromCallExpression( - this.startNodeAt(startPos, startLoc), - node, + finishedNode = this.parseAsyncArrowFromCallExpression( + this.startNodeAt(startPos, startLoc), + finishedNode as N.CallExpression, ); } else { if (maybeAsyncArrow) { this.checkExpressionErrors(refExpressionErrors, true); this.expressionScope.exit(); } - this.toReferencedArguments(node); + this.toReferencedArguments(finishedNode); } this.state.maybeInArrowParameters = oldMaybeInArrowParameters; - return node; + return finishedNode; } toReferencedArguments( @@ -906,12 +967,13 @@ export default class ExpressionParser extends LValParser { // MemberExpression [?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] // CallExpression [?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] parseTaggedTemplateExpression( + this: Parser, base: N.Expression, startPos: number, startLoc: Position, state: N.ParseSubscriptState, ): N.TaggedTemplateExpression { - const node: N.TaggedTemplateExpression = this.startNodeAt( + const node = this.startNodeAt( startPos, startLoc, ); @@ -936,9 +998,9 @@ export default class ExpressionParser extends LValParser { } finishCallExpression( - node: T, + node: Undone, optional: boolean, - ): N.Expression { + ): T { if (node.callee.type === "Import") { if (node.arguments.length === 2) { if (process.env.BABEL_8_BREAKING) { @@ -973,13 +1035,14 @@ export default class ExpressionParser extends LValParser { } parseCallExpressionArguments( + this: Parser, close: TokenType, dynamicImport?: boolean, allowPlaceholder?: boolean, nodeForExtra?: N.Node | null, refExpressionErrors?: ExpressionErrors | null, - ): ReadonlyArray { - const elts = []; + ): Array { + const elts: N.Expression[] = []; let first = true; const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; this.state.inFSharpPipelineDirectBody = false; @@ -1022,7 +1085,8 @@ export default class ExpressionParser extends LValParser { } parseAsyncArrowFromCallExpression( - node: N.ArrowFunctionExpression, + this: Parser, + node: Undone, call: N.CallExpression, ): N.ArrowFunctionExpression { this.resetPreviousNodeTrailingComments(call); @@ -1041,12 +1105,12 @@ export default class ExpressionParser extends LValParser { if (call.callee.trailingComments) { setInnerComments(node, call.callee.trailingComments); } - return node; + return node as N.ArrowFunctionExpression; } // Parse a no-call expression (like argument of `new` or `::` operators). // https://tc39.es/ecma262/#prod-MemberExpression - parseNoCallExpr(): N.Expression { + parseNoCallExpr(this: Parser): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); @@ -1064,7 +1128,10 @@ export default class ExpressionParser extends LValParser { // Import // AsyncArrowFunction - parseExprAtom(refExpressionErrors?: ExpressionErrors | null): N.Expression { + parseExprAtom( + this: Parser, + refExpressionErrors?: ExpressionErrors | null, + ): N.Expression { let node; const { type } = this.state; @@ -1073,11 +1140,11 @@ export default class ExpressionParser extends LValParser { return this.parseSuper(); case tt._import: - node = this.startNode(); + node = this.startNode(); this.next(); if (this.match(tt.dot)) { - return this.parseImportMetaProperty(node); + return this.parseImportMetaProperty(node as Undone); } if (!this.match(tt.parenL)) { @@ -1165,7 +1232,7 @@ export default class ExpressionParser extends LValParser { this.parseDecorators(); // fall through case tt._class: - node = this.startNode(); + node = this.startNode(); this.takeDecorators(node); return this.parseClass(node, false); @@ -1358,7 +1425,7 @@ export default class ExpressionParser extends LValParser { // its configuration might not match the current token’s type. // See . parseTopicReference(pipeProposal: string): N.Expression { - const node = this.startNode(); + const node = this.startNode(); const startLoc = this.state.startLoc; const tokenType = this.state.type; @@ -1451,6 +1518,7 @@ export default class ExpressionParser extends LValParser { return this.hasPlugin([ "pipelineOperator", { + // @ts-expect-error token must have a label topicToken: tokenLabelName(tokenType), }, ]); @@ -1463,7 +1531,10 @@ export default class ExpressionParser extends LValParser { } // async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] - parseAsyncArrowUnaryFunction(node: N.Node): N.ArrowFunctionExpression { + parseAsyncArrowUnaryFunction( + this: Parser, + node: Undone, + ): N.ArrowFunctionExpression { // We don't need to push a new ParameterDeclarationScope here since we are sure // 1) it is an async arrow, 2) no biding pattern is allowed in params this.prodParam.enter(functionFlags(true, this.prodParam.hasYield)); @@ -1476,13 +1547,16 @@ export default class ExpressionParser extends LValParser { } this.expect(tt.arrow); // let foo = async bar => {}; - this.parseArrowExpression(node, params, true); - return node; + return this.parseArrowExpression(node, params, true); } // https://github.com/tc39/proposal-do-expressions // https://github.com/tc39/proposal-async-do-expressions - parseDo(node: N.Node, isAsync: boolean): N.DoExpression { + parseDo( + this: Parser, + node: Undone, + isAsync: boolean, + ): N.DoExpression { this.expectPlugin("doExpressions"); if (isAsync) { this.expectPlugin("asyncDoExpressions"); @@ -1507,7 +1581,7 @@ export default class ExpressionParser extends LValParser { // Parse the `super` keyword parseSuper(): N.Super { - const node = this.startNode(); + const node = this.startNode(); this.next(); // eat `super` if ( this.match(tt.parenL) && @@ -1534,8 +1608,8 @@ export default class ExpressionParser extends LValParser { } parsePrivateName(): N.PrivateName { - const node = this.startNode(); - const id = this.startNodeAt( + const node = this.startNode(); + const id = this.startNodeAt( this.state.start + 1, // The position is hardcoded because we merge `#` and name into a single // tt.privateName token @@ -1551,8 +1625,10 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, "PrivateName"); } - parseFunctionOrFunctionSent(): N.FunctionExpression | N.MetaProperty { - const node = this.startNode(); + parseFunctionOrFunctionSent( + this: Parser, + ): N.FunctionExpression | N.MetaProperty { + const node = this.startNode(); // We do not do parseIdentifier here because when parseFunctionOrFunctionSent // is called we already know that the current token is a "name" with the value "function" @@ -1563,7 +1639,7 @@ export default class ExpressionParser extends LValParser { if (this.prodParam.hasYield && this.match(tt.dot)) { const meta = this.createIdentifier( - this.startNodeAtNode(node), + this.startNodeAtNode(node), "function", ); this.next(); // eat `.` @@ -1576,11 +1652,11 @@ export default class ExpressionParser extends LValParser { } return this.parseMetaProperty(node, meta, "sent"); } - return this.parseFunction(node); + return this.parseFunction(node as Undone); } parseMetaProperty( - node: N.MetaProperty, + node: Undone, meta: N.Identifier, propertyName: string, ): N.MetaProperty { @@ -1602,8 +1678,11 @@ export default class ExpressionParser extends LValParser { } // https://tc39.es/ecma262/#prod-ImportMeta - parseImportMetaProperty(node: N.MetaProperty): N.MetaProperty { - const id = this.createIdentifier(this.startNodeAtNode(node), "import"); + parseImportMetaProperty(node: Undone): N.MetaProperty { + const id = this.createIdentifier( + this.startNodeAtNode(node), + "import", + ); this.next(); // eat `.` if (this.isContextual(tt._meta)) { @@ -1649,7 +1728,11 @@ export default class ExpressionParser extends LValParser { return this.parseLiteral(value, "DecimalLiteral"); } - parseRegExpLiteral(value: { value: any; pattern: string; flags: string }) { + parseRegExpLiteral(value: { + value: any; + pattern: string; + flags: N.RegExpLiteral["flags"]; + }) { const node = this.parseLiteral( value.value, "RegExpLiteral", @@ -1660,20 +1743,23 @@ export default class ExpressionParser extends LValParser { } parseBooleanLiteral(value: boolean) { - const node = this.startNode(); + const node = this.startNode(); node.value = value; this.next(); - return this.finishNode(node, "BooleanLiteral"); + return this.finishNode(node, "BooleanLiteral"); } parseNullLiteral() { - const node = this.startNode(); + const node = this.startNode(); this.next(); - return this.finishNode(node, "NullLiteral"); + return this.finishNode(node, "NullLiteral"); } // https://tc39.es/ecma262/#prod-CoverParenthesizedExpressionAndArrowParameterList - parseParenAndDistinguishExpression(canBeArrow: boolean): N.Expression { + parseParenAndDistinguishExpression( + this: Parser, + canBeArrow: boolean, + ): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; @@ -1688,7 +1774,7 @@ export default class ExpressionParser extends LValParser { const innerStartPos = this.state.start; const innerStartLoc = this.state.startLoc; - const exprList = []; + const exprList: N.Expression[] = []; const refExpressionErrors = new ExpressionErrors(); let first = true; let spreadStartLoc; @@ -1741,7 +1827,10 @@ export default class ExpressionParser extends LValParser { this.state.maybeInArrowParameters = oldMaybeInArrowParameters; this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; - let arrowNode = this.startNodeAt(startPos, startLoc); + let arrowNode = this.startNodeAt( + startPos, + startLoc, + ); if ( canBeArrow && this.shouldParseArrow(exprList) && @@ -1764,7 +1853,10 @@ export default class ExpressionParser extends LValParser { this.toReferencedListDeep(exprList, /* isParenthesizedExpr */ true); if (exprList.length > 1) { - val = this.startNodeAt(innerStartPos, innerStartLoc); + val = this.startNodeAt( + innerStartPos, + innerStartLoc, + ); val.expressions = exprList; // finish node at current location so it can pick up comments after `)` this.finishNode(val, "SequenceExpression"); @@ -1794,20 +1886,22 @@ export default class ExpressionParser extends LValParser { return expression; } - const parenExpression = this.startNodeAt(startPos, startLoc); + const parenExpression = this.startNodeAt( + startPos, + startLoc, + ); parenExpression.expression = expression; - this.finishNode(parenExpression, "ParenthesizedExpression"); - return parenExpression; + return this.finishNode(parenExpression, "ParenthesizedExpression"); } - // eslint-disable-next-line no-unused-vars -- `params` is used in typescript plugin + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- `params` is used in typescript plugin shouldParseArrow(params: Array): boolean { return !this.canInsertSemicolon(); } parseArrow( - node: N.ArrowFunctionExpression, - ): N.ArrowFunctionExpression | undefined | null { + node: Undone, + ): Undone | undefined { if (this.eat(tt.arrow)) { return node; } @@ -1815,22 +1909,29 @@ export default class ExpressionParser extends LValParser { parseParenItem( node: N.Expression, - // eslint-disable-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars startPos: number, - // eslint-disable-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars startLoc: Position, ): N.Expression { return node; } - parseNewOrNewTarget(): N.NewExpression | N.MetaProperty { - const node = this.startNode(); + parseNewOrNewTarget(this: Parser): N.NewExpression | N.MetaProperty { + const node = this.startNode(); this.next(); if (this.match(tt.dot)) { // https://tc39.es/ecma262/#prod-NewTarget - const meta = this.createIdentifier(this.startNodeAtNode(node), "new"); + const meta = this.createIdentifier( + this.startNodeAtNode(node), + "new", + ); this.next(); - const metaProp = this.parseMetaProperty(node, meta, "target"); + const metaProp = this.parseMetaProperty( + node as Undone, + meta, + "target", + ); if (!this.scope.inNonArrowFunction && !this.scope.inClass) { this.raise(Errors.UnexpectedNewTarget, { at: metaProp }); @@ -1839,7 +1940,7 @@ export default class ExpressionParser extends LValParser { return metaProp; } - return this.parseNew(node); + return this.parseNew(node as Undone); } // New's precedence is slightly tricky. It must allow its argument to @@ -1848,13 +1949,13 @@ export default class ExpressionParser extends LValParser { // argument to parseSubscripts to prevent it from consuming the // argument list. // https://tc39.es/ecma262/#prod-NewExpression - parseNew(node: N.NewExpression): N.NewExpression { + parseNew(this: Parser, node: Undone): N.NewExpression { this.parseNewCallee(node); if (this.eat(tt.parenL)) { const args = this.parseExprList(tt.parenR); this.toReferencedList(args); - // $FlowFixMe (parseExprList should be all non-null in this case) + // (parseExprList should be all non-null in this case) node.arguments = args; } else { node.arguments = []; @@ -1863,7 +1964,7 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, "NewExpression"); } - parseNewCallee(node: N.NewExpression): void { + parseNewCallee(this: Parser, node: Undone): void { node.callee = this.parseNoCallExpr(); if (node.callee.type === "Import") { this.raise(Errors.ImportCallNotNewExpression, { at: node.callee }); @@ -1883,7 +1984,7 @@ export default class ExpressionParser extends LValParser { parseTemplateElement(isTagged: boolean): N.TemplateElement { const { start, startLoc, end, value } = this.state; const elemStart = start + 1; - const elem = this.startNodeAt( + const elem = this.startNodeAt( elemStart, createPositionWithColumnOffset(startLoc, 1), ); @@ -1905,17 +2006,17 @@ export default class ExpressionParser extends LValParser { }; elem.tail = isTail; this.next(); - this.finishNode(elem, "TemplateElement"); + const finishedNode = this.finishNode(elem, "TemplateElement"); this.resetEndLocation( - elem, + finishedNode, createPositionWithColumnOffset(this.state.lastTokEndLoc, endOffset), ); - return elem; + return finishedNode; } // https://tc39.es/ecma262/#prod-TemplateLiteral - parseTemplate(isTagged: boolean): N.TemplateLiteral { - const node = this.startNode(); + parseTemplate(this: Parser, isTagged: boolean): N.TemplateLiteral { + const node = this.startNode(); node.expressions = []; let curElt = this.parseTemplateElement(isTagged); node.quasis = [curElt]; @@ -1928,13 +2029,32 @@ export default class ExpressionParser extends LValParser { } // This is overwritten by the TypeScript plugin to parse template types - parseTemplateSubstitution(): N.Expression { + parseTemplateSubstitution(this: Parser): N.Expression { return this.parseExpression(); } // Parse an object literal, binding pattern, or record. + parseObjectLike( + close: TokenType, + isPattern: true, + isRecord?: boolean | null, + refExpressionErrors?: ExpressionErrors | null, + ): N.ObjectPattern; + parseObjectLike( + close: TokenType, + isPattern: false, + isRecord?: false | null, + refExpressionErrors?: ExpressionErrors | null, + ): N.ObjectExpression; + parseObjectLike( + close: TokenType, + isPattern: false, + isRecord?: true, + refExpressionErrors?: ExpressionErrors | null, + ): N.RecordExpression; parseObjectLike( + this: Parser, close: TokenType, isPattern: boolean, isRecord?: boolean | null, @@ -1947,7 +2067,9 @@ export default class ExpressionParser extends LValParser { this.state.inFSharpPipelineDirectBody = false; const propHash: any = Object.create(null); let first = true; - const node = this.startNode(); + const node = this.startNode< + N.ObjectExpression | N.ObjectPattern | N.RecordExpression + >(); node.properties = []; this.next(); @@ -1979,11 +2101,12 @@ export default class ExpressionParser extends LValParser { this.raise(Errors.InvalidRecordProperty, { at: prop }); } - // $FlowIgnore + // @ts-expect-error if (prop.shorthand) { this.addExtra(prop, "shorthand", true); } + // @ts-expect-error Fixme: refine typings node.properties.push(prop); } @@ -1996,6 +2119,7 @@ export default class ExpressionParser extends LValParser { } else if (isRecord) { type = "RecordExpression"; } + // @ts-expect-error type is well defined return this.finishNode(node, type); } @@ -2007,7 +2131,7 @@ export default class ExpressionParser extends LValParser { // Check grammar production: // IdentifierName *_opt PropertyName // It is used in `parsePropertyDefinition` to detect AsyncMethod and Accessors - maybeAsyncOrAccessorProp(prop: N.ObjectProperty): boolean { + maybeAsyncOrAccessorProp(prop: Undone): boolean { return ( !prop.computed && prop.key.type === "Identifier" && @@ -2019,6 +2143,7 @@ export default class ExpressionParser extends LValParser { // https://tc39.es/ecma262/#prod-PropertyDefinition parsePropertyDefinition( + this: Parser, refExpressionErrors?: ExpressionErrors | null, ): N.ObjectMember | N.SpreadElement { let decorators = []; @@ -2036,7 +2161,7 @@ export default class ExpressionParser extends LValParser { } } - const prop = this.startNode(); + const prop = this.startNode(); let isAsync = false; let isAccessor = false; let startPos; @@ -2092,7 +2217,7 @@ export default class ExpressionParser extends LValParser { } } - this.parseObjPropValue( + return this.parseObjPropValue( prop, startPos, startLoc, @@ -2102,8 +2227,6 @@ export default class ExpressionParser extends LValParser { isAccessor, refExpressionErrors, ); - - return prop; } getGetterSetterExpectedParamCount( @@ -2140,7 +2263,8 @@ export default class ExpressionParser extends LValParser { // https://tc39.es/ecma262/#prod-MethodDefinition parseObjectMethod( - prop: N.ObjectMethod, + this: Parser, + prop: Undone, isGenerator: boolean, isAsync: boolean, isPattern: boolean, @@ -2148,7 +2272,7 @@ export default class ExpressionParser extends LValParser { ): N.ObjectMethod | undefined | null { if (isAccessor) { // isAccessor implies isAsync: false, isPattern: false, isGenerator: false - this.parseMethod( + const finishedProp = this.parseMethod( prop, // This _should_ be false, but with error recovery, we allow it to be // set for informational purposes @@ -2158,8 +2282,8 @@ export default class ExpressionParser extends LValParser { false, "ObjectMethod", ); - this.checkGetterSetterParams(prop); - return prop; + this.checkGetterSetterParams(finishedProp); + return finishedProp; } if (isAsync || isGenerator || this.match(tt.parenL)) { @@ -2180,7 +2304,8 @@ export default class ExpressionParser extends LValParser { // if `isPattern` is true, parse https://tc39.es/ecma262/#prod-BindingProperty // else https://tc39.es/ecma262/#prod-PropertyDefinition parseObjectProperty( - prop: N.ObjectProperty, + this: Parser, + prop: Undone, startPos: number | undefined | null, startLoc: Position | undefined | null, isPattern: boolean, @@ -2235,7 +2360,8 @@ export default class ExpressionParser extends LValParser { } parseObjPropValue( - prop: any, + this: Parser, + prop: Undone, startPos: number | undefined | null, startLoc: Position | undefined | null, isGenerator: boolean, @@ -2243,17 +2369,17 @@ export default class ExpressionParser extends LValParser { isPattern: boolean, isAccessor: boolean, refExpressionErrors?: ExpressionErrors | null, - ): void { + ): N.ObjectMethod | N.ObjectProperty { const node = this.parseObjectMethod( - prop, + prop as Undone, isGenerator, isAsync, isPattern, isAccessor, ) || this.parseObjectProperty( - prop, + prop as Undone, startPos, startLoc, isPattern, @@ -2262,7 +2388,6 @@ export default class ExpressionParser extends LValParser { if (!node) this.unexpected(); - // $FlowFixMe return node; } @@ -2270,11 +2395,14 @@ export default class ExpressionParser extends LValParser { // when refExpressionErrors presents, it will parse private name // and record the position of the first private name parsePropertyName( - prop: N.ObjectOrClassMember | N.ClassMember | N.TsNamedTypeElementBase, + this: Parser, + prop: Undone< + N.ObjectOrClassMember | N.ClassMember | N.TsNamedTypeElementBase + >, refExpressionErrors?: ExpressionErrors | null, ): N.Expression | N.Identifier { if (this.eat(tt.bracketL)) { - (prop as $FlowSubtype).computed = true; + (prop as Undone).computed = true; prop.key = this.parseMaybeAssignAllowIn(); this.expect(tt.bracketR); } else { @@ -2340,13 +2468,14 @@ export default class ExpressionParser extends LValParser { // Parse object or class method. - parseMethod( - node: T, + parseMethod( + this: Parser, + node: Undone, isGenerator: boolean, isAsync: boolean, isConstructor: boolean, allowDirectSuper: boolean, - type: string, + type: T["type"], inClassScope: boolean = false, ): T { this.initFunction(node, isAsync); @@ -2359,18 +2488,19 @@ export default class ExpressionParser extends LValParser { (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0), ); this.prodParam.enter(functionFlags(isAsync, node.generator)); - this.parseFunctionParams(node as any, allowModifiers); - this.parseFunctionBodyAndFinish(node, type, true); + this.parseFunctionParams(node, allowModifiers); + const finishedNode = this.parseFunctionBodyAndFinish(node, type, true); this.prodParam.exit(); this.scope.exit(); - return node; + return finishedNode; } // parse an array literal or tuple literal // https://tc39.es/ecma262/#prod-ArrayLiteral // https://tc39.es/proposal-record-tuple/#prod-TupleLiteral parseArrayLike( + this: Parser, close: TokenType, canBePattern: boolean, isTuple: boolean, @@ -2381,7 +2511,7 @@ export default class ExpressionParser extends LValParser { } const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; this.state.inFSharpPipelineDirectBody = false; - const node = this.startNode(); + const node = this.startNode(); this.next(); node.elements = this.parseExprList( close, @@ -2400,7 +2530,8 @@ export default class ExpressionParser extends LValParser { // If the parameters are provided, they will be converted to an // assignable list. parseArrowExpression( - node: N.ArrowFunctionExpression, + this: Parser, + node: Undone, params: N.Expression[] | undefined | null, isAsync: boolean, trailingCommaLoc?: Position | null, @@ -2432,27 +2563,30 @@ export default class ExpressionParser extends LValParser { } setArrowFunctionParameters( - node: N.ArrowFunctionExpression, + node: Undone, params: N.Expression[], trailingCommaLoc?: Position | null, ): void { this.toAssignableList(params, trailingCommaLoc, false); - node.params = params; + node.params = params as (N.Pattern | N.TSParameterProperty)[]; } - parseFunctionBodyAndFinish( - node: N.BodilessFunctionOrMethodBase, - type: string, - isMethod: boolean = false, - ): void { - // $FlowIgnore (node is not bodiless if we get here) + parseFunctionBodyAndFinish< + T extends + | N.Function + | N.TSDeclareMethod + | N.TSDeclareFunction + | N.ClassPrivateMethod, + >(node: Undone, type: T["type"], isMethod: boolean = false): T { + // @ts-expect-error (node is not bodiless if we get here) this.parseFunctionBody(node, false, isMethod); - this.finishNode(node, type); + return this.finishNode(node, type); } // Parse function body and check parameters. parseFunctionBody( - node: N.Function, + this: Parser, + node: Undone, allowExpression?: boolean | null, isMethod: boolean = false, ): void { @@ -2461,7 +2595,9 @@ export default class ExpressionParser extends LValParser { if (isExpression) { // https://tc39.es/ecma262/#prod-ExpressionBody - node.body = this.parseMaybeAssign(); + // @ts-expect-error Fixme: refine typings + (node as Undone).body = + this.parseMaybeAssign(); this.checkParams(node, false, allowExpression, false); } else { const oldStrict = this.state.strict; @@ -2484,11 +2620,12 @@ export default class ExpressionParser extends LValParser { // This logic is here to align the error location with the ESTree plugin. this.raise(Errors.IllegalLanguageModeDirective, { at: - // $FlowIgnore + // @ts-expect-error (node.kind === "method" || node.kind === "constructor") && - // $FlowIgnore + // @ts-expect-error !!node.key - ? node.key.loc.end + ? // @ts-expect-error node.key has been gaurded + node.key.loc.end : node, }); } @@ -2530,20 +2667,20 @@ export default class ExpressionParser extends LValParser { } checkParams( - node: N.Function, + node: Undone, allowDuplicates: boolean, - // eslint-disable-next-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars isArrowFunction?: boolean | null, strictModeChanged: boolean = true, ): void { - const checkClashes = !allowDuplicates && new Set(); + const checkClashes = !allowDuplicates && new Set(); // We create a fake node with the "ephemeral" type `FormalParameters`[1] // since we just store an array of parameters. Perhaps someday we can have // something like class FormalParameters extends Array { ... }, which would // also be helpful when traversing this node. // // 1. https://tc39.es/ecma262/#prod-FormalParameters - const formalParameters = { type: "FormalParameters" }; + const formalParameters = { type: "FormalParameters" } as const; for (const param of node.params) { this.checkLVal(param, { in: formalParameters, @@ -2561,12 +2698,13 @@ export default class ExpressionParser extends LValParser { // for array literals). parseExprList( + this: Parser, close: TokenType, allowEmpty?: boolean, refExpressionErrors?: ExpressionErrors | null, nodeForExtra?: N.Node | null, - ): ReadonlyArray { - const elts = []; + ): (N.Expression | null)[] { + const elts: (N.Expression | null)[] = []; let first = true; while (!this.eat(close)) { @@ -2589,10 +2727,23 @@ export default class ExpressionParser extends LValParser { } parseExprListItem( + this: Parser, + allowEmpty?: boolean, + refExpressionErrors?: ExpressionErrors | null, + allowPlaceholder?: boolean | null, + ): N.Expression | null; + parseExprListItem( + this: Parser, + allowEmpty?: false, + refExpressionErrors?: ExpressionErrors | null, + allowPlaceholder?: boolean | null, + ): N.Expression; + parseExprListItem( + this: Parser, allowEmpty?: boolean | null, refExpressionErrors?: ExpressionErrors | null, allowPlaceholder?: boolean | null, - ): N.Expression | undefined | null { + ): N.Expression | null { let elt; if (this.match(tt.comma)) { if (!allowEmpty) { @@ -2637,13 +2788,16 @@ export default class ExpressionParser extends LValParser { // are not identifiers and cannot contain escape sequences. parseIdentifier(liberal?: boolean): N.Identifier { - const node = this.startNode(); + const node = this.startNode(); const name = this.parseIdentifierName(node.start, liberal); return this.createIdentifier(node, name); } - createIdentifier(node: N.Identifier, name: string): N.Identifier { + createIdentifier( + node: Omit, + name: string, + ): N.Identifier { node.name = name; node.loc.identifierName = name; @@ -2752,8 +2906,12 @@ export default class ExpressionParser extends LValParser { // Parses await expression inside async function. - parseAwait(startPos: number, startLoc: Position): N.AwaitExpression { - const node = this.startNodeAt(startPos, startLoc); + parseAwait( + this: Parser, + startPos: number, + startLoc: Position, + ): N.AwaitExpression { + const node = this.startNodeAt(startPos, startLoc); this.expressionScope.recordParameterInitializerError( Errors.AwaitExpressionFormalParameter, @@ -2801,8 +2959,8 @@ export default class ExpressionParser extends LValParser { // Parses yield expression inside generator. - parseYield(): N.YieldExpression { - const node = this.startNode(); + parseYield(this: Parser): N.YieldExpression { + const node = this.startNode(); this.expressionScope.recordParameterInitializerError( Errors.YieldInParameter, @@ -2811,7 +2969,7 @@ export default class ExpressionParser extends LValParser { this.next(); let delegating = false; - let argument = null; + let argument: N.Expression | null = null; if (!this.hasPrecedingLineBreak()) { delegating = this.eat(tt.star); switch (this.state.type) { @@ -2856,12 +3014,19 @@ export default class ExpressionParser extends LValParser { childExpr: N.Expression, startPos: number, startLoc: Position, - ): N.PipelineBody { - const bodyNode = this.startNodeAt(startPos, startLoc); + ) { if (this.isSimpleReference(childExpr)) { + const bodyNode = this.startNodeAt( + startPos, + startLoc, + ); bodyNode.callee = childExpr; return this.finishNode(bodyNode, "PipelineBareFunction"); } else { + const bodyNode = this.startNodeAt( + startPos, + startLoc, + ); this.checkSmartPipeTopicBodyEarlyErrors(startLoc); bodyNode.expression = childExpr; return this.finishNode(bodyNode, "PipelineTopicExpression"); @@ -3013,7 +3178,7 @@ export default class ExpressionParser extends LValParser { ); } - parseFSharpPipelineBody(prec: number): N.Expression { + parseFSharpPipelineBody(this: Parser, prec: number): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; @@ -3034,7 +3199,7 @@ export default class ExpressionParser extends LValParser { } // https://github.com/tc39/proposal-js-module-blocks - parseModuleExpression(): N.ModuleExpression { + parseModuleExpression(this: Parser): N.ModuleExpression { this.expectPlugin("moduleBlocks"); const node = this.startNode(); this.next(); // eat "module" @@ -3055,7 +3220,7 @@ export default class ExpressionParser extends LValParser { // Used in Flow plugin parsePropertyNamePrefixOperator( - // eslint-disable-next-line no-unused-vars - prop: N.ObjectOrClassMember | N.ClassMember, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + prop: Undone, ): void {} } diff --git a/packages/babel-parser/src/parser/index.ts b/packages/babel-parser/src/parser/index.ts index c9bea68c3a3e..776449a899f5 100644 --- a/packages/babel-parser/src/parser/index.ts +++ b/packages/babel-parser/src/parser/index.ts @@ -1,5 +1,5 @@ import type { Options } from "../options"; -import type { File /*::, JSXOpeningElement */ } from "../types"; +import type { File, Program /*::, JSXOpeningElement */ } from "../types"; import type { PluginList } from "../plugin-utils"; import { getOptions } from "../options"; import StatementParser from "./statement"; @@ -39,8 +39,8 @@ export default class Parser extends StatementParser { parse(): File { this.enterInitialScopes(); - const file = this.startNode(); - const program = this.startNode(); + const file = this.startNode() as File; + const program = this.startNode() as Program; this.nextToken(); file.errors = null; this.parseTopLevel(file, program); diff --git a/packages/babel-parser/src/parser/lval.ts b/packages/babel-parser/src/parser/lval.ts index cb6207166934..0432891c0692 100644 --- a/packages/babel-parser/src/parser/lval.ts +++ b/packages/babel-parser/src/parser/lval.ts @@ -2,6 +2,7 @@ import * as charCodes from "charcodes"; import { tt, type TokenType } from "../tokenizer/types"; import type { + AssignmentPattern, TSParameterProperty, Decorator, Expression, @@ -13,17 +14,20 @@ import type { /*:: ObjectOrClassMember, */ /*:: ClassMember, */ ObjectMember, + ObjectExpression, + ArrayExpression, + ArrayPattern, /*:: TsNamedTypeElementBase, */ /*:: PrivateName, */ /*:: ObjectExpression, */ /*:: ObjectPattern, */ } from "../types"; -import type { Pos, Position } from "../util/location"; +import type { Position } from "../util/location"; import { isStrictBindOnlyReservedWord, isStrictBindReservedWord, } from "../util/identifier"; -import { NodeUtils } from "./node"; +import { NodeUtils, type Undone } from "./node"; import { type BindingTypes, BIND_NONE, @@ -31,8 +35,9 @@ import { } from "../util/scopeflags"; import { ExpressionErrors } from "./util"; import { Errors, type LValAncestor } from "../parse-error"; +import type Parser from "./index"; -const getOwn = (object, key) => +const getOwn = (object: T, key: keyof T) => Object.hasOwnProperty.call(object, key) && object[key]; const unwrapParenthesizedExpression = (node: Node): Node => { @@ -48,7 +53,6 @@ export default class LValParser extends NodeUtils { +parseMaybeAssignAllowIn: ( refExpressionErrors?: ?ExpressionErrors, afterLeftParse?: Function, - refNeedsArrowPos?: ?Pos, ) => Expression; +parseObjectLike: ( close: TokenType, @@ -267,13 +271,15 @@ export default class LValParser extends NodeUtils { 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) - ); - }); + return (node.properties as ObjectExpression["properties"]).every( + (prop, i) => { + return ( + prop.type !== "ObjectMethod" && + (i === last || prop.type !== "SpreadElement") && + this.isAssignable(prop) + ); + }, + ); } case "ObjectProperty": @@ -283,7 +289,7 @@ export default class LValParser extends NodeUtils { return this.isAssignable(node.argument); case "ArrayExpression": - return node.elements.every( + return (node as ArrayExpression).elements.every( element => element === null || this.isAssignable(element), ); @@ -306,7 +312,7 @@ export default class LValParser extends NodeUtils { toReferencedList( exprList: ReadonlyArray, - // eslint-disable-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars isParenthesizedExpr?: boolean, ): ReadonlyArray { return exprList; @@ -328,35 +334,35 @@ export default class LValParser extends NodeUtils { // Parses spread element. parseSpread( + this: Parser, refExpressionErrors?: ExpressionErrors | null, - refNeedsArrowPos?: Pos | null, ): SpreadElement { - const node = this.startNode(); + const node = this.startNode(); this.next(); node.argument = this.parseMaybeAssignAllowIn( refExpressionErrors, undefined, - refNeedsArrowPos, ); return this.finishNode(node, "SpreadElement"); } // https://tc39.es/ecma262/#prod-BindingRestProperty // https://tc39.es/ecma262/#prod-BindingRestElement - parseRestBinding(): RestElement { - const node = this.startNode(); + parseRestBinding(this: Parser): RestElement { + const node = this.startNode(); this.next(); // eat `...` node.argument = this.parseBindingAtom(); return this.finishNode(node, "RestElement"); } // Parses lvalue (assignable) atom. - parseBindingAtom(): Pattern { + parseBindingAtom(this: Parser): Pattern { // https://tc39.es/ecma262/#prod-BindingPattern switch (this.state.type) { case tt.bracketL: { - const node = this.startNode(); + const node = this.startNode(); this.next(); + // @ts-expect-error: Fixme: TSParameterProperty can not be assigned to node.elements node.elements = this.parseBindingList( tt.bracketR, charCodes.rightSquareBracket, @@ -375,11 +381,12 @@ export default class LValParser extends NodeUtils { // https://tc39.es/ecma262/#prod-BindingElementList parseBindingList( + this: Parser, close: TokenType, closeCharCode: typeof charCodes[keyof typeof charCodes], allowEmpty?: boolean, allowModifiers?: boolean, - ): ReadonlyArray { + ): Array { const elts: Array = []; let first = true; while (!this.eat(close)) { @@ -389,7 +396,6 @@ export default class LValParser extends NodeUtils { this.expect(tt.comma); } if (allowEmpty && this.match(tt.comma)) { - // $FlowFixMe This method returns `$ReadOnlyArray` if `allowEmpty` is set. elts.push(null); } else if (this.eat(close)) { break; @@ -417,7 +423,10 @@ export default class LValParser extends NodeUtils { } // https://tc39.es/ecma262/#prod-BindingRestProperty - parseBindingRestProperty(prop: RestElement): RestElement { + parseBindingRestProperty( + this: Parser, + prop: Undone, + ): RestElement { this.next(); // eat '...' // Don't use parseRestBinding() as we only allow Identifier here. prop.argument = this.parseIdentifier(); @@ -426,21 +435,21 @@ export default class LValParser extends NodeUtils { } // https://tc39.es/ecma262/#prod-BindingProperty - parseBindingProperty(): ObjectMember | RestElement { - const prop = this.startNode(); + parseBindingProperty(this: Parser): ObjectMember | RestElement { + const prop = this.startNode(); const { type, start: startPos, startLoc } = this.state; if (type === tt.ellipsis) { - return this.parseBindingRestProperty(prop); + return this.parseBindingRestProperty(prop as Undone); } else if (type === tt.privateName) { this.expectPlugin("destructuringPrivate", startLoc); this.classScope.usePrivateName(this.state.value, startLoc); - prop.key = this.parsePrivateName(); + (prop as Undone).key = this.parsePrivateName(); } else { - this.parsePropertyName(prop); + this.parsePropertyName(prop as Undone); } - prop.method = false; - this.parseObjPropValue( - prop, + (prop as Undone).method = false; + return this.parseObjPropValue( + prop as Undone, startPos, startLoc, false /* isGenerator */, @@ -448,11 +457,10 @@ export default class LValParser extends NodeUtils { true /* isPattern */, false /* isAccessor */, ); - - return prop; } parseAssignableListItem( + this: Parser, allowModifiers: boolean | undefined | null, decorators: Decorator[], ): Pattern | TSParameterProperty { @@ -473,17 +481,17 @@ export default class LValParser extends NodeUtils { // Parses assignment pattern around given atom if possible. // https://tc39.es/ecma262/#prod-BindingElement parseMaybeDefault( + this: Parser, startPos?: number | null, startLoc?: Position | null, left?: Pattern | null, ): Pattern { startLoc = startLoc ?? this.state.startLoc; startPos = startPos ?? this.state.start; - // $FlowIgnore left = left ?? this.parseBindingAtom(); if (!this.eat(tt.eq)) return left; - const node = this.startNodeAt(startPos, startLoc); + const node = this.startNodeAt(startPos, startLoc); node.left = left; node.right = this.parseMaybeAssignAllowIn(); return this.finishNode(node, "AssignmentPattern"); @@ -520,11 +528,11 @@ export default class LValParser extends NodeUtils { */ isValidLVal( type: string, - // eslint-disable-next-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars isUnparenthesizedInAssign: boolean, - // eslint-disable-next-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars binding: BindingTypes, - ) { + ): string | boolean { return getOwn( { AssignmentPattern: "left", @@ -534,6 +542,7 @@ export default class LValParser extends NodeUtils { ArrayPattern: "elements", ObjectPattern: "properties", }, + // @ts-expect-error refine string to enum type, ); } @@ -602,13 +611,13 @@ export default class LValParser extends NodeUtils { if (expression.type === "Identifier") { this.checkIdentifier( - expression, + expression as Identifier, binding, strictModeChanged, allowingSloppyLetBinding, ); - const { name } = expression; + const { name } = expression as Identifier; if (checkClashes) { if (checkClashes.has(name)) { @@ -629,7 +638,6 @@ export default class LValParser extends NodeUtils { ); if (validity === true) return; - if (validity === false) { const ParseErrorClass = binding === BIND_NONE ? Errors.InvalidLhs : Errors.InvalidLhsBinding; @@ -656,10 +664,11 @@ export default class LValParser extends NodeUtils { // Flow has difficulty tracking `key` and `expression`, but only if we use // null-proto objects. If we use normal objects, everything works fine. - // $FlowIgnore + // @ts-expect-error for (const child of [].concat(expression[key])) { if (child) { this.checkLVal(child, { + // @ts-expect-error: refine types in: nextAncestor, binding, checkClashes, diff --git a/packages/babel-parser/src/parser/node.ts b/packages/babel-parser/src/parser/node.ts index 5639a4bb963e..360ed707f6e0 100644 --- a/packages/babel-parser/src/parser/node.ts +++ b/packages/babel-parser/src/parser/node.ts @@ -29,9 +29,9 @@ class Node implements NodeBase { const NodePrototype = Node.prototype; if (!process.env.BABEL_8_BREAKING) { - // $FlowIgnore + // @ts-expect-error NodePrototype.__clone = function (): Node { - // $FlowIgnore + // @ts-expect-error const newNode: any = new Node(); const keys = Object.keys(this); for (let i = 0, length = keys.length; i < length; i++) { @@ -42,7 +42,9 @@ if (!process.env.BABEL_8_BREAKING) { key !== "trailingComments" && key !== "innerComments" ) { - newNode[key] = this[key]; + newNode[key] = + // @ts-expect-error: key must present in this + this[key]; } } @@ -94,43 +96,51 @@ export function cloneStringLiteral(node: any): any { return cloned; } +export type Undone = Omit; + export class NodeUtils extends UtilParser { - startNode(): T { - // $FlowIgnore + startNode(): Undone { + // @ts-expect-error return new Node(this, this.state.start, this.state.startLoc); } - startNodeAt(pos: number, loc: Position): T { - // $FlowIgnore + startNodeAt(pos: number, loc: Position): Undone { + // @ts-expect-error return new Node(this, pos, loc); } /** Start a new node with a previous node's location. */ - startNodeAtNode(type: NodeType): T { + startNodeAtNode(type: Undone): Undone { return this.startNodeAt(type.start, type.loc.start); } // Finish an AST node, adding `type` and `end` properties. - finishNode(node: T, type: string): T { + finishNode(node: Undone, type: T["type"]): T { return this.finishNodeAt(node, type, this.state.lastTokEndLoc); } // Finish node at given position - finishNodeAt(node: T, type: string, endLoc: Position): T { + finishNodeAt( + node: Omit, + type: T["type"], + endLoc: Position, + ): T { if (process.env.NODE_ENV !== "production" && node.end > 0) { throw new Error( "Do not call finishNode*() twice on the same node." + " Instead use resetEndLocation() or change type directly.", ); } + // @ts-expect-error migrate to Babel types AST typings node.type = type; + // @ts-expect-error migrate to Babel types AST typings node.end = endLoc.index; node.loc.end = endLoc; if (this.options.ranges) node.range[1] = endLoc.index; - if (this.options.attachComment) this.processComment(node); - return node; + if (this.options.attachComment) this.processComment(node as T); + return node as T; } resetStartLocation(node: NodeBase, start: number, startLoc: Position): void { diff --git a/packages/babel-parser/src/parser/statement.ts b/packages/babel-parser/src/parser/statement.ts index 0158ba6e637a..9ea9847be973 100644 --- a/packages/babel-parser/src/parser/statement.ts +++ b/packages/babel-parser/src/parser/statement.ts @@ -39,10 +39,11 @@ import { import type { SourceType } from "../options"; import { Token } from "../tokenizer"; import { Position, createPositionWithColumnOffset } from "../util/location"; -import { cloneStringLiteral, cloneIdentifier } from "./node"; +import { cloneStringLiteral, cloneIdentifier, type Undone } from "./node"; +import type Parser from "./index"; -const loopLabel = { kind: "loop" }, - switchLabel = { kind: "switch" }; +const loopLabel = { kind: "loop" } as const, + switchLabel = { kind: "switch" } as const; const FUNC_NO_FLAGS = 0b000, FUNC_STATEMENT = 0b001, @@ -63,7 +64,7 @@ const keywordRelationalOperator = /in(?:stanceof)?/y; * @param {*} tokens * @returns */ -function babel7CompatTokens(tokens, input) { +function babel7CompatTokens(tokens: (Token | N.Comment)[], input: string) { for (let i = 0; i < tokens.length; i++) { const token = tokens[i]; const { type } = token; @@ -76,8 +77,8 @@ function babel7CompatTokens(tokens, input) { tokens.splice( i, 1, - // $FlowIgnore: hacky way to create token new Token({ + // @ts-expect-error: hacky way to create token type: getExportedToken(tt.hash), value: "#", start: start, @@ -85,8 +86,8 @@ function babel7CompatTokens(tokens, input) { startLoc: loc.start, endLoc: hashEndLoc, }), - // $FlowIgnore: hacky way to create token new Token({ + // @ts-expect-error: hacky way to create token type: getExportedToken(tt.name), value: value, start: hashEndPos, @@ -105,8 +106,8 @@ function babel7CompatTokens(tokens, input) { const backquoteEndLoc = createPositionWithColumnOffset(loc.start, 1); let startToken; if (input.charCodeAt(start) === charCodes.graveAccent) { - // $FlowIgnore: hacky way to create token startToken = new Token({ + // @ts-expect-error: hacky way to create token type: getExportedToken(tt.backQuote), value: "`", start: start, @@ -115,8 +116,8 @@ function babel7CompatTokens(tokens, input) { endLoc: backquoteEndLoc, }); } else { - // $FlowIgnore: hacky way to create token startToken = new Token({ + // @ts-expect-error: hacky way to create token type: getExportedToken(tt.braceR), value: "}", start: start, @@ -134,8 +135,8 @@ function babel7CompatTokens(tokens, input) { templateElementEnd = end - 1; templateElementEndLoc = createPositionWithColumnOffset(loc.end, -1); templateValue = value === null ? null : value.slice(1, -1); - // $FlowIgnore: hacky way to create token endToken = new Token({ + // @ts-expect-error: hacky way to create token type: getExportedToken(tt.backQuote), value: "`", start: templateElementEnd, @@ -148,8 +149,8 @@ function babel7CompatTokens(tokens, input) { templateElementEnd = end - 2; templateElementEndLoc = createPositionWithColumnOffset(loc.end, -2); templateValue = value === null ? null : value.slice(1, -2); - // $FlowIgnore: hacky way to create token endToken = new Token({ + // @ts-expect-error: hacky way to create token type: getExportedToken(tt.dollarBraceL), value: "${", start: templateElementEnd, @@ -162,8 +163,8 @@ function babel7CompatTokens(tokens, input) { i, 1, startToken, - // $FlowIgnore: hacky way to create token new Token({ + // @ts-expect-error: hacky way to create token type: getExportedToken(tt.template), value: templateValue, start: backquoteEnd, @@ -177,7 +178,7 @@ function babel7CompatTokens(tokens, input) { continue; } } - // $FlowIgnore: we manipulate `token` for performance reasons + // @ts-expect-error: we manipulate `token` for performance reasons token.type = getExportedToken(type); } } @@ -191,7 +192,7 @@ export default class StatementParser extends ExpressionParser { // `program` argument. If present, the statements will be appended // to its body instead of creating a new node. - parseTopLevel(file: N.File, program: N.Program): N.File { + parseTopLevel(this: Parser, file: N.File, program: N.Program): N.File { file.program = this.parseProgram(program); file.comments = this.state.comments; @@ -203,7 +204,8 @@ export default class StatementParser extends ExpressionParser { } parseProgram( - program: N.Program, + this: Parser, + program: Undone, end: TokenType = tt.eof, sourceType: SourceType = this.options.sourceType, ): N.Program { @@ -219,7 +221,7 @@ export default class StatementParser extends ExpressionParser { this.raise(Errors.ModuleExportUndefined, { at, localName }); } } - return this.finishNode(program, "Program"); + return this.finishNode(program, "Program"); } // TODO @@ -256,7 +258,7 @@ export default class StatementParser extends ExpressionParser { return null; } - const node = this.startNode(); + const node = this.startNode(); node.value = this.state.value; this.next(); return this.finishNode(node, "InterpreterDirective"); @@ -320,7 +322,11 @@ export default class StatementParser extends ExpressionParser { // https://tc39.es/ecma262/#prod-Statement // ImportDeclaration and ExportDeclaration are also handled here so we can throw recoverable errors // when they are not at the top level - parseStatement(context?: string | null, topLevel?: boolean): N.Statement { + parseStatement( + this: Parser, + context?: string | null, + topLevel?: boolean, + ): N.Statement { if (this.match(tt.at)) { this.parseDecorators(true); } @@ -328,6 +334,7 @@ export default class StatementParser extends ExpressionParser { } parseStatementContent( + this: Parser, context?: string | null, topLevel?: boolean | null, ): N.Statement { @@ -350,11 +357,11 @@ export default class StatementParser extends ExpressionParser { case tt._continue: return this.parseBreakContinueStatement(node, /* isBreak */ false); case tt._debugger: - return this.parseDebuggerStatement(node); + return this.parseDebuggerStatement(node as Undone); case tt._do: - return this.parseDoStatement(node); + return this.parseDoStatement(node as Undone); case tt._for: - return this.parseForStatement(node); + return this.parseForStatement(node as Undone); case tt._function: if (this.lookaheadCharCode() === charCodes.dot) break; if (context) { @@ -364,22 +371,26 @@ export default class StatementParser extends ExpressionParser { this.raise(Errors.SloppyFunction, { at: this.state.startLoc }); } } - return this.parseFunctionStatement(node, false, !context); + return this.parseFunctionStatement( + node as Undone, + false, + !context, + ); case tt._class: if (context) this.unexpected(); - return this.parseClass(node, true); + return this.parseClass(node as Undone, true); case tt._if: - return this.parseIfStatement(node); + return this.parseIfStatement(node as Undone); case tt._return: - return this.parseReturnStatement(node); + return this.parseReturnStatement(node as Undone); case tt._switch: - return this.parseSwitchStatement(node); + return this.parseSwitchStatement(node as Undone); case tt._throw: - return this.parseThrowStatement(node); + return this.parseThrowStatement(node as Undone); case tt._try: - return this.parseTryStatement(node); + return this.parseTryStatement(node as Undone); case tt._const: case tt._var: @@ -389,16 +400,19 @@ export default class StatementParser extends ExpressionParser { at: this.state.startLoc, }); } - return this.parseVarStatement(node, kind); + return this.parseVarStatement( + node as Undone, + kind, + ); case tt._while: - return this.parseWhileStatement(node); + return this.parseWhileStatement(node as Undone); case tt._with: - return this.parseWithStatement(node); + return this.parseWithStatement(node as Undone); case tt.braceL: return this.parseBlock(); case tt.semi: - return this.parseEmptyStatement(node); + return this.parseEmptyStatement(node as Undone); case tt._import: { const nextTokenCharCode = this.lookaheadCharCode(); if ( @@ -420,7 +434,7 @@ export default class StatementParser extends ExpressionParser { let result; if (starttype === tt._import) { - result = this.parseImport(node); + result = this.parseImport(node as Undone); if ( result.type === "ImportDeclaration" && @@ -429,7 +443,13 @@ export default class StatementParser extends ExpressionParser { this.sawUnambiguousESM = true; } } else { - result = this.parseExport(node); + result = this.parseExport( + node as Undone< + | N.ExportAllDeclaration + | N.ExportDefaultDeclaration + | N.ExportDefaultDeclaration + >, + ); if ( (result.type === "ExportNamedDeclaration" && @@ -442,7 +462,7 @@ export default class StatementParser extends ExpressionParser { } } - this.assertModuleNodeAllowed(node); + this.assertModuleNodeAllowed(result); return result; } @@ -455,7 +475,11 @@ export default class StatementParser extends ExpressionParser { }); } this.next(); - return this.parseFunctionStatement(node, true, !context); + return this.parseFunctionStatement( + node as Undone, + true, + !context, + ); } } } @@ -473,9 +497,18 @@ export default class StatementParser extends ExpressionParser { expr.type === "Identifier" && this.eat(tt.colon) ) { - return this.parseLabeledStatement(node, maybeName, expr, context); + return this.parseLabeledStatement( + node as Undone, + maybeName, + // @ts-expect-error migrate to Babel types + expr, + context, + ); } else { - return this.parseExpressionStatement(node, expr); + return this.parseExpressionStatement( + node as Undone, + expr, + ); } } @@ -499,7 +532,7 @@ export default class StatementParser extends ExpressionParser { return this.match(tt._class); } - parseDecorators(allowExport?: boolean): void { + parseDecorators(this: Parser, allowExport?: boolean): void { const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; while (this.match(tt.at)) { @@ -525,10 +558,10 @@ export default class StatementParser extends ExpressionParser { } } - parseDecorator(): N.Decorator { + parseDecorator(this: Parser): N.Decorator { this.expectOnePlugin(["decorators", "decorators-legacy"]); - const node = this.startNode(); + const node = this.startNode(); this.next(); if (this.hasPlugin("decorators")) { @@ -567,7 +600,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "Decorator"); } - parseMaybeDecoratorArguments(expr: N.Expression): N.Expression { + parseMaybeDecoratorArguments(this: Parser, expr: N.Expression): N.Expression { if (this.eat(tt.parenL)) { const node = this.startNodeAtNode(expr); node.callee = expr; @@ -580,7 +613,15 @@ export default class StatementParser extends ExpressionParser { } parseBreakContinueStatement( - node: N.BreakStatement | N.ContinueStatement, + node: Undone, + isBreak: true, + ): N.BreakStatement; + parseBreakContinueStatement( + node: Undone, + isBreak: false, + ): N.ContinueStatement; + parseBreakContinueStatement( + node: Undone, isBreak: boolean, ): N.BreakStatement | N.ContinueStatement { this.next(); @@ -601,7 +642,7 @@ export default class StatementParser extends ExpressionParser { } verifyBreakContinue( - node: N.BreakStatement | N.ContinueStatement, + node: Undone, isBreak: boolean, ) { let i; @@ -618,20 +659,25 @@ export default class StatementParser extends ExpressionParser { } } - parseDebuggerStatement(node: N.DebuggerStatement): N.DebuggerStatement { + parseDebuggerStatement( + node: Undone, + ): N.DebuggerStatement { this.next(); this.semicolon(); return this.finishNode(node, "DebuggerStatement"); } - parseHeaderExpression(): N.Expression { + parseHeaderExpression(this: Parser): N.Expression { this.expect(tt.parenL); const val = this.parseExpression(); this.expect(tt.parenR); return val; } - parseDoStatement(node: N.DoWhileStatement): N.DoWhileStatement { + parseDoStatement( + this: Parser, + node: Undone, + ): N.DoWhileStatement { this.next(); this.state.labels.push(loopLabel); @@ -661,7 +707,10 @@ export default class StatementParser extends ExpressionParser { // part (semicolon immediately after the opening parenthesis), it // is a regular `for` loop. - parseForStatement(node: N.Node): N.ForLike { + parseForStatement( + this: Parser, + node: Undone, + ): N.ForLike { this.next(); this.state.labels.push(loopLabel); @@ -677,28 +726,28 @@ export default class StatementParser extends ExpressionParser { if (awaitAt !== null) { this.unexpected(awaitAt); } - return this.parseFor(node, null); + return this.parseFor(node as Undone, null); } const startsWithLet = this.isContextual(tt._let); const isLet = startsWithLet && this.isLetKeyword(); if (this.match(tt._var) || this.match(tt._const) || isLet) { - const init = this.startNode(); + const initNode = this.startNode(); const kind = isLet ? "let" : this.state.value; this.next(); - this.parseVar(init, true, kind); - this.finishNode(init, "VariableDeclaration"); + this.parseVar(initNode, true, kind); + const init = this.finishNode(initNode, "VariableDeclaration"); if ( (this.match(tt._in) || this.isContextual(tt._of)) && init.declarations.length === 1 ) { - return this.parseForIn(node, init, awaitAt); + return this.parseForIn(node as Undone, init, awaitAt); } if (awaitAt !== null) { this.unexpected(awaitAt); } - return this.parseFor(node, init); + return this.parseFor(node as Undone, init); } // Check whether the first token is possibly a contextual keyword, so that @@ -732,18 +781,24 @@ export default class StatementParser extends ExpressionParser { this.toAssignable(init, /* isLHS */ true); const type = isForOf ? "ForOfStatement" : "ForInStatement"; this.checkLVal(init, { in: { type } }); - return this.parseForIn(node, init, awaitAt); + return this.parseForIn( + node as Undone, + // @ts-expect-error init has been transformed to an assignable + init, + awaitAt, + ); } else { this.checkExpressionErrors(refExpressionErrors, true); } if (awaitAt !== null) { this.unexpected(awaitAt); } - return this.parseFor(node, init); + return this.parseFor(node as Undone, init); } parseFunctionStatement( - node: N.FunctionDeclaration, + this: Parser, + node: Undone, isAsync?: boolean, declarationPosition?: boolean, ): N.FunctionDeclaration { @@ -755,7 +810,7 @@ export default class StatementParser extends ExpressionParser { ); } - parseIfStatement(node: N.IfStatement): N.IfStatement { + parseIfStatement(this: Parser, node: Undone) { this.next(); node.test = this.parseHeaderExpression(); node.consequent = this.parseStatement("if"); @@ -763,7 +818,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "IfStatement"); } - parseReturnStatement(node: N.ReturnStatement): N.ReturnStatement { + parseReturnStatement(this: Parser, node: Undone) { if (!this.prodParam.hasReturn && !this.options.allowReturnOutsideFunction) { this.raise(Errors.IllegalReturn, { at: this.state.startLoc }); } @@ -784,10 +839,10 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ReturnStatement"); } - parseSwitchStatement(node: N.SwitchStatement): N.SwitchStatement { + parseSwitchStatement(this: Parser, node: Undone) { this.next(); node.discriminant = this.parseHeaderExpression(); - const cases = (node.cases = []); + const cases: N.SwitchStatement["cases"] = (node.cases = []); this.expect(tt.braceL); this.state.labels.push(switchLabel); this.scope.enter(SCOPE_OTHER); @@ -801,6 +856,7 @@ export default class StatementParser extends ExpressionParser { if (this.match(tt._case) || this.match(tt._default)) { const isCase = this.match(tt._case); if (cur) this.finishNode(cur, "SwitchCase"); + // @ts-expect-error Fixme cases.push((cur = this.startNode())); cur.consequent = []; this.next(); @@ -831,7 +887,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "SwitchStatement"); } - parseThrowStatement(node: N.ThrowStatement): N.ThrowStatement { + parseThrowStatement(this: Parser, node: Undone) { this.next(); if (this.hasPrecedingLineBreak()) { this.raise(Errors.NewlineAfterThrow, { at: this.state.lastTokEndLoc }); @@ -841,7 +897,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ThrowStatement"); } - parseCatchClauseParam(): N.Pattern { + parseCatchClauseParam(this: Parser): N.Pattern { const param = this.parseBindingAtom(); const simple = param.type === "Identifier"; @@ -855,14 +911,17 @@ export default class StatementParser extends ExpressionParser { return param; } - parseTryStatement(node: N.TryStatement): N.TryStatement { + parseTryStatement( + this: Parser, + node: Undone, + ): N.TryStatement { this.next(); node.block = this.parseBlock(); node.handler = null; if (this.match(tt._catch)) { - const clause = this.startNode(); + const clause = this.startNode(); this.next(); if (this.match(tt.parenL)) { this.expect(tt.parenL); @@ -896,7 +955,8 @@ export default class StatementParser extends ExpressionParser { } parseVarStatement( - node: N.VariableDeclaration, + this: Parser, + node: Undone, kind: "var" | "let" | "const", allowMissingInitializer: boolean = false, ): N.VariableDeclaration { @@ -906,7 +966,10 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "VariableDeclaration"); } - parseWhileStatement(node: N.WhileStatement): N.WhileStatement { + parseWhileStatement( + this: Parser, + node: Undone, + ): N.WhileStatement { this.next(); node.test = this.parseHeaderExpression(); this.state.labels.push(loopLabel); @@ -926,7 +989,10 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "WhileStatement"); } - parseWithStatement(node: N.WithStatement): N.WithStatement { + parseWithStatement( + this: Parser, + node: Undone, + ): N.WithStatement { if (this.state.strict) { this.raise(Errors.StrictWith, { at: this.state.startLoc }); } @@ -947,13 +1013,14 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "WithStatement"); } - parseEmptyStatement(node: N.EmptyStatement): N.EmptyStatement { + parseEmptyStatement(node: Undone): N.EmptyStatement { this.next(); return this.finishNode(node, "EmptyStatement"); } parseLabeledStatement( - node: N.LabeledStatement, + this: Parser, + node: Undone, maybeName: string, expr: N.Identifier, context?: string | null, @@ -1001,9 +1068,9 @@ export default class StatementParser extends ExpressionParser { } parseExpressionStatement( - node: N.ExpressionStatement, + node: Undone, expr: N.Expression, - ): N.Statement { + ) { node.expression = expr; this.semicolon(); return this.finishNode(node, "ExpressionStatement"); @@ -1014,11 +1081,12 @@ export default class StatementParser extends ExpressionParser { // function bodies). parseBlock( + this: Parser, allowDirectives: boolean = false, createNewLexicalScope: boolean = true, afterBlockParse?: (hasStrictModeDirective: boolean) => void, ): N.BlockStatement { - const node = this.startNode(); + const node = this.startNode(); if (allowDirectives) { this.state.strictErrors.clear(); } @@ -1048,14 +1116,16 @@ export default class StatementParser extends ExpressionParser { } parseBlockBody( - node: N.BlockStatementLike, + this: Parser, + node: Undone, allowDirectives: boolean | undefined | null, topLevel: boolean, end: TokenType, afterBlockParse?: (hasStrictModeDirective: boolean) => void, ): void { - const body = (node.body = []); - const directives = (node.directives = []); + const body: N.BlockStatementLike["body"] = (node.body = []); + const directives: N.BlockStatementLike["directives"] = (node.directives = + []); this.parseBlockOrModuleBlockBody( body, allowDirectives ? directives : undefined, @@ -1069,6 +1139,7 @@ export default class StatementParser extends ExpressionParser { // https://tc39.es/ecma262/#prod-Block // https://tc39.es/ecma262/#prod-ModuleBody parseBlockOrModuleBlockBody( + this: Parser, body: N.Statement[], directives: N.Directive[] | undefined | null, topLevel: boolean, @@ -1089,6 +1160,7 @@ export default class StatementParser extends ExpressionParser { if ( !hasStrictModeDirective && + // @ts-expect-error migrate to Babel types directive.value.value === "use strict" ) { hasStrictModeDirective = true; @@ -1120,7 +1192,8 @@ export default class StatementParser extends ExpressionParser { // expression. parseFor( - node: N.ForStatement, + this: Parser, + node: Undone, init?: N.VariableDeclaration | N.Expression | null, ): N.ForStatement { node.init = init; @@ -1150,7 +1223,8 @@ export default class StatementParser extends ExpressionParser { // same from parser's perspective. parseForIn( - node: N.ForInOf, + this: Parser, + node: Undone, init: N.VariableDeclaration | N.AssignmentPattern, awaitAt?: Position | null, ): N.ForInOf { @@ -1209,15 +1283,16 @@ export default class StatementParser extends ExpressionParser { // Parse a list of variable declarations. parseVar( - node: N.VariableDeclaration, + this: Parser, + node: Undone, isFor: boolean, kind: "var" | "let" | "const", allowMissingInitializer: boolean = false, - ): N.VariableDeclaration { - const declarations = (node.declarations = []); + ): Undone { + const declarations: N.VariableDeclarator[] = (node.declarations = []); node.kind = kind; for (;;) { - const decl = this.startNode(); + const decl = this.startNode(); this.parseVarId(decl, kind); decl.init = !this.eat(tt.eq) ? null @@ -1250,7 +1325,11 @@ export default class StatementParser extends ExpressionParser { return node; } - parseVarId(decl: N.VariableDeclarator, kind: "var" | "let" | "const"): void { + parseVarId( + this: Parser, + decl: Undone, + kind: "var" | "let" | "const", + ): void { decl.id = this.parseBindingAtom(); this.checkLVal(decl.id, { in: { type: "VariableDeclarator" }, @@ -1262,7 +1341,8 @@ export default class StatementParser extends ExpressionParser { // `isStatement` parameter). parseFunction( - node: T, + this: Parser, + node: Undone, statement: number = FUNC_NO_FLAGS, isAsync: boolean = false, ): T { @@ -1301,6 +1381,7 @@ export default class StatementParser extends ExpressionParser { // Parse the function body. this.parseFunctionBodyAndFinish( node, + // @ts-expect-error node must be one of types isStatement ? "FunctionDeclaration" : "FunctionExpression", ); }); @@ -1312,11 +1393,11 @@ export default class StatementParser extends ExpressionParser { // We need to register this _after_ parsing the function body // because of TypeScript body-less function declarations, // which shouldn't be added to the scope. - this.registerFunctionStatementId(node); + this.registerFunctionStatementId(node as T); } this.state.maybeInArrowParameters = oldMaybeInArrowParameters; - return node; + return node as T; } parseFunctionId(requireId?: boolean): N.Identifier | undefined | null { @@ -1325,7 +1406,11 @@ export default class StatementParser extends ExpressionParser { : null; } - parseFunctionParams(node: N.Function, allowModifiers?: boolean): void { + parseFunctionParams( + this: Parser, + node: Undone, + allowModifiers?: boolean, + ): void { this.expect(tt.parenL); this.expressionScope.enter(newParameterDeclarationScope()); node.params = this.parseBindingList( @@ -1360,7 +1445,8 @@ export default class StatementParser extends ExpressionParser { // `isStatement` parameter). parseClass( - node: T, + this: Parser, + node: Undone, isStatement: /* T === ClassDeclaration */ boolean, optionalId?: boolean, ): T { @@ -1400,7 +1486,11 @@ export default class StatementParser extends ExpressionParser { } // https://tc39.es/ecma262/#prod-ClassBody - parseClassBody(hadSuperClass: boolean, oldStrict: boolean): N.ClassBody { + parseClassBody( + this: Parser, + hadSuperClass: boolean, + oldStrict: boolean, + ): N.ClassBody { this.classScope.enter(); const state: N.ParseClassMemberState = { @@ -1408,7 +1498,7 @@ export default class StatementParser extends ExpressionParser { hadSuperClass, }; let decorators: N.Decorator[] = []; - const classBody: N.ClassBody = this.startNode(); + const classBody = this.startNode(); classBody.body = []; this.expect(tt.braceL); @@ -1432,10 +1522,11 @@ export default class StatementParser extends ExpressionParser { continue; } - const member = this.startNode(); + const member = this.startNode(); // steal the decorators if there are any if (decorators.length) { + // @ts-expect-error Fixme member.decorators = decorators; this.resetStartLocationFromNode(member, decorators[0]); decorators = []; @@ -1444,8 +1535,11 @@ export default class StatementParser extends ExpressionParser { this.parseClassMember(classBody, member, state); if ( + // @ts-expect-error Fixme member.kind === "constructor" && + // @ts-expect-error Fixme member.decorators && + // @ts-expect-error Fixme member.decorators.length > 0 ) { this.raise(Errors.DecoratorConstructor, { at: member }); @@ -1469,8 +1563,9 @@ export default class StatementParser extends ExpressionParser { // returns true if the current identifier is a method/field name, // false if it is a modifier parseClassMemberFromModifier( - classBody: N.ClassBody, - member: N.ClassMember, + this: Parser, + classBody: Undone, + member: Undone, ): boolean { const key = this.parseIdentifier(true); // eats the modifier @@ -1506,8 +1601,9 @@ export default class StatementParser extends ExpressionParser { } parseClassMember( - classBody: N.ClassBody, - member: N.ClassMember, + this: Parser, + classBody: Undone, + member: Undone, state: N.ParseClassMemberState, ): void { const isStatic = this.isContextual(tt._static); @@ -1527,15 +1623,21 @@ export default class StatementParser extends ExpressionParser { } parseClassMemberWithIsStatic( - classBody: N.ClassBody, - member: N.ClassMember, + this: Parser, + classBody: Undone, + member: Undone, state: N.ParseClassMemberState, isStatic: boolean, ) { + // @ts-expect-error: Fixme: convert $FlowSubtype to TS const publicMethod: $FlowSubtype = member; + // @ts-expect-error: Fixme: convert $FlowSubtype to TS const privateMethod: $FlowSubtype = member; + // @ts-expect-error: Fixme: convert $FlowSubtype to TS const publicProp: $FlowSubtype = member; + // @ts-expect-error: Fixme: convert $FlowSubtype to TS const privateProp: $FlowSubtype = member; + // @ts-expect-error: Fixme: convert $FlowSubtype to TS const accessorProp: $FlowSubtype = member; const method: typeof publicMethod | typeof privateMethod = publicMethod; @@ -1718,7 +1820,10 @@ export default class StatementParser extends ExpressionParser { } // https://tc39.es/ecma262/#prod-ClassElementName - parseClassElementName(member: N.ClassMember): N.Expression | N.Identifier { + parseClassElementName( + this: Parser, + member: Undone, + ): N.Expression | N.Identifier { const { type, value } = this.state; if ( (type === tt.name || type === tt.string) && @@ -1743,10 +1848,13 @@ export default class StatementParser extends ExpressionParser { } parseClassStaticBlock( - classBody: N.ClassBody, - member: N.StaticBlock & { - decorators?: Array; - }, + this: Parser, + classBody: Undone, + member: Undone< + N.StaticBlock & { + decorators?: Array; + } + >, ) { // Start a new lexical scope this.scope.enter(SCOPE_CLASS | SCOPE_STATIC_BLOCK | SCOPE_SUPER); @@ -1756,7 +1864,7 @@ export default class StatementParser extends ExpressionParser { // ClassStaticBlockStatementList: // StatementList[~Yield, ~Await, ~Return] opt this.prodParam.enter(PARAM); - const body = (member.body = []); + const body: N.Node[] = (member.body = []); this.parseBlockOrModuleBlockBody(body, undefined, false, tt.braceR); this.prodParam.exit(); this.scope.exit(); @@ -1767,7 +1875,11 @@ export default class StatementParser extends ExpressionParser { } } - pushClassProperty(classBody: N.ClassBody, prop: N.ClassProperty) { + pushClassProperty( + this: Parser, + classBody: Undone, + prop: N.ClassProperty, + ) { if ( !prop.computed && (prop.key.name === "constructor" || prop.key.value === "constructor") @@ -1781,8 +1893,9 @@ export default class StatementParser extends ExpressionParser { } pushClassPrivateProperty( - classBody: N.ClassBody, - prop: N.ClassPrivateProperty, + this: Parser, + classBody: Undone, + prop: Undone, ) { const node = this.parseClassPrivateProperty(prop); classBody.body.push(node); @@ -1795,7 +1908,8 @@ export default class StatementParser extends ExpressionParser { } pushClassAccessorProperty( - classBody: N.ClassBody, + this: Parser, + classBody: Undone, prop: N.ClassAccessorProperty, isPrivate: boolean, ) { @@ -1823,8 +1937,9 @@ export default class StatementParser extends ExpressionParser { } pushClassMethod( - classBody: N.ClassBody, - method: N.ClassMethod, + this: Parser, + classBody: Undone, + method: Undone, isGenerator: boolean, isAsync: boolean, isConstructor: boolean, @@ -1844,8 +1959,9 @@ export default class StatementParser extends ExpressionParser { } pushClassPrivateMethod( - classBody: N.ClassBody, - method: N.ClassPrivateMethod, + this: Parser, + classBody: Undone, + method: Undone, isGenerator: boolean, isAsync: boolean, ): void { @@ -1874,7 +1990,9 @@ export default class StatementParser extends ExpressionParser { } declareClassPrivateMethodInScope( - node: N.ClassPrivateMethod | N.EstreeMethodDefinition | N.TSDeclareMethod, + node: Undone< + N.ClassPrivateMethod | N.EstreeMethodDefinition | N.TSDeclareMethod + >, kind: number, ) { this.classScope.declarePrivateName( @@ -1886,13 +2004,14 @@ export default class StatementParser extends ExpressionParser { // Overridden in typescript.js parsePostMemberNameModifiers( - // eslint-disable-next-line no-unused-vars - methodOrProp: N.ClassMethod | N.ClassProperty, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + methodOrProp: Undone, ): void {} // https://tc39.es/ecma262/#prod-FieldDefinition parseClassPrivateProperty( - node: N.ClassPrivateProperty, + this: Parser, + node: Undone, ): N.ClassPrivateProperty { this.parseInitializer(node); this.semicolon(); @@ -1900,13 +2019,14 @@ export default class StatementParser extends ExpressionParser { } // https://tc39.es/ecma262/#prod-FieldDefinition - parseClassProperty(node: N.ClassProperty): N.ClassProperty { + parseClassProperty(this: Parser, node: N.ClassProperty): N.ClassProperty { this.parseInitializer(node); this.semicolon(); return this.finishNode(node, "ClassProperty"); } parseClassAccessorProperty( + this: Parser, node: N.ClassAccessorProperty, ): N.ClassAccessorProperty { this.parseInitializer(node); @@ -1916,7 +2036,10 @@ export default class StatementParser extends ExpressionParser { // https://tc39.es/ecma262/#prod-Initializer parseInitializer( - node: N.ClassProperty | N.ClassPrivateProperty | N.ClassAccessorProperty, + this: Parser, + node: Undone< + N.ClassProperty | N.ClassPrivateProperty | N.ClassAccessorProperty + >, ): void { this.scope.enter(SCOPE_CLASS | SCOPE_SUPER); this.expressionScope.enter(newExpressionScope()); @@ -1928,7 +2051,7 @@ export default class StatementParser extends ExpressionParser { } parseClassId( - node: N.Class, + node: Undone, isStatement: boolean, optionalId?: boolean | null, bindingType: BindingTypes = BIND_CLASS, @@ -1948,14 +2071,21 @@ export default class StatementParser extends ExpressionParser { } // https://tc39.es/ecma262/#prod-ClassHeritage - parseClassSuper(node: N.Class): void { + parseClassSuper(this: Parser, node: Undone): void { node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null; } // Parses module export declaration. // https://tc39.es/ecma262/#prod-ExportDeclaration - parseExport(node: N.Node): N.AnyExport { + parseExport( + this: Parser, + node: Undone< + | N.ExportDefaultDeclaration + | N.ExportAllDeclaration + | N.ExportNamedDeclaration + >, + ): N.AnyExport { const hasDefault = this.maybeParseExportDefaultSpecifier(node); const parseAfterDefault = !hasDefault || this.eat(tt.comma); const hasStar = parseAfterDefault && this.eatExportStar(node); @@ -1967,7 +2097,7 @@ export default class StatementParser extends ExpressionParser { if (hasStar && !hasNamespace) { if (hasDefault) this.unexpected(); - this.parseExportFrom(node, true); + this.parseExportFrom(node as Undone, true); return this.finishNode(node, "ExportAllDeclaration"); } @@ -1984,20 +2114,31 @@ export default class StatementParser extends ExpressionParser { let hasDeclaration; if (isFromRequired || hasSpecifiers) { hasDeclaration = false; - this.parseExportFrom(node, isFromRequired); + this.parseExportFrom( + node as Undone, + isFromRequired, + ); } else { - hasDeclaration = this.maybeParseExportDeclaration(node); + hasDeclaration = this.maybeParseExportDeclaration( + node as Undone, + ); } if (isFromRequired || hasSpecifiers || hasDeclaration) { - this.checkExport(node, true, false, !!node.source); + this.checkExport( + node as Undone, + true, + false, + !!(node as Undone).source, + ); return this.finishNode(node, "ExportNamedDeclaration"); } if (this.eat(tt._default)) { // export default ... - node.declaration = this.parseExportDefaultExpression(); - this.checkExport(node, true, true); + (node as Undone).declaration = + this.parseExportDefaultExpression(); + this.checkExport(node as Undone, true, true); return this.finishNode(node, "ExportDefaultDeclaration"); } @@ -2005,7 +2146,7 @@ export default class StatementParser extends ExpressionParser { throw this.unexpected(null, tt.braceL); } - // eslint-disable-next-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars eatExportStar(node: N.Node): boolean { return this.eat(tt.star); } @@ -2059,7 +2200,10 @@ export default class StatementParser extends ExpressionParser { return false; } - maybeParseExportDeclaration(node: N.Node): boolean { + maybeParseExportDeclaration( + this: Parser, + node: Undone, + ): boolean { if (this.shouldParseExportDeclaration()) { node.specifiers = []; node.source = null; @@ -2081,7 +2225,7 @@ export default class StatementParser extends ExpressionParser { ); } - parseExportDefaultExpression(): N.Expression | N.Declaration { + parseExportDefaultExpression(this: Parser): N.Expression | N.Declaration { const expr = this.startNode(); const isAsync = this.isAsyncFunction(); @@ -2093,14 +2237,14 @@ export default class StatementParser extends ExpressionParser { } return this.parseFunction( - expr, + expr as Undone, FUNC_STATEMENT | FUNC_NULLABLE_ID, isAsync, ); } if (this.match(tt._class)) { - return this.parseClass(expr, true, true); + return this.parseClass(expr as Undone, true, true); } if (this.match(tt.at)) { @@ -2111,7 +2255,7 @@ export default class StatementParser extends ExpressionParser { this.raise(Errors.DecoratorBeforeExport, { at: this.state.startLoc }); } this.parseDecorators(false); - return this.parseClass(expr, true, true); + return this.parseClass(expr as Undone, true, true); } if (this.match(tt._const) || this.match(tt._var) || this.isLet()) { @@ -2125,11 +2269,12 @@ export default class StatementParser extends ExpressionParser { return res; } - // eslint-disable-next-line no-unused-vars parseExportDeclaration( - node: N.ExportNamedDeclaration, + this: Parser, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + node: Undone, ): N.Declaration | undefined | null { - return this.parseStatement(null); + return this.parseStatement(null) as N.Declaration; } isExportDefaultSpecifier(): boolean { @@ -2180,7 +2325,11 @@ export default class StatementParser extends ExpressionParser { return false; } - parseExportFrom(node: N.ExportNamedDeclaration, expect?: boolean): void { + parseExportFrom( + this: Parser, + node: Undone, + expect?: boolean, + ): void { if (this.eatContextual(tt._from)) { node.source = this.parseImportSource(); this.checkExport(node); @@ -2222,7 +2371,7 @@ export default class StatementParser extends ExpressionParser { } checkExport( - node: N.ExportNamedDeclaration, + node: Undone, checkNames?: boolean, isDefault?: boolean, isFrom?: boolean, @@ -2237,6 +2386,7 @@ export default class StatementParser extends ExpressionParser { .declaration; if ( declaration.type === "Identifier" && + // @ts-expect-error migrate to Babel types declaration.name === "from" && declaration.end - declaration.start === 4 && // does not contain escape !declaration.extra?.parenthesized @@ -2246,14 +2396,15 @@ export default class StatementParser extends ExpressionParser { }); } } + // @ts-expect-error node.specifiers may not exist } else if (node.specifiers && node.specifiers.length) { // Named exports + // @ts-expect-error node.specifiers may not exist for (const specifier of node.specifiers) { const { exported } = specifier; const exportName = exported.type === "Identifier" ? exported.name : exported.value; this.checkDuplicateExports(specifier, exportName); - // $FlowIgnore if (!isFrom && specifier.local) { const { local } = specifier; if (local.type !== "Identifier") { @@ -2276,11 +2427,13 @@ export default class StatementParser extends ExpressionParser { node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration" ) { + // @ts-expect-error migrate to Babel types const id = node.declaration.id; if (!id) throw new Error("Assertion failure"); this.checkDuplicateExports(node, id.name); } else if (node.declaration.type === "VariableDeclaration") { + // @ts-expect-error migrate to Babel types for (const declaration of node.declaration.declarations) { this.checkDeclaration(declaration.id); } @@ -2311,6 +2464,7 @@ export default class StatementParser extends ExpressionParser { } } } else if (node.type === "ObjectProperty") { + // @ts-expect-error migrate to Babel types this.checkDeclaration(node.value); } else if (node.type === "RestElement") { this.checkDeclaration(node.argument); @@ -2320,12 +2474,13 @@ export default class StatementParser extends ExpressionParser { } checkDuplicateExports( - node: + node: Undone< | N.Identifier | N.StringLiteral | N.ExportNamedDeclaration | N.ExportSpecifier - | N.ExportDefaultSpecifier, + | N.ExportDefaultSpecifier + >, exportName: string, ): void { if (this.exportedIdentifiers.has(exportName)) { @@ -2374,10 +2529,10 @@ export default class StatementParser extends ExpressionParser { parseExportSpecifier( node: any, isString: boolean, - /* eslint-disable no-unused-vars -- used in TypeScript parser */ + /* eslint-disable @typescript-eslint/no-unused-vars -- used in TypeScript parser */ isInTypeExport: boolean, isMaybeTypeOnly: boolean, - /* eslint-enable no-unused-vars */ + /* eslint-enable @typescript-eslint/no-unused-vars */ ): N.ExportSpecifier { if (this.eatContextual(tt._as)) { node.exported = this.parseModuleExportName(); @@ -2406,10 +2561,9 @@ export default class StatementParser extends ExpressionParser { } isJSONModuleImport( - node: - | N.ExportAllDeclaration - | N.ExportNamedDeclaration - | N.ImportDeclaration, + node: Undone< + N.ExportAllDeclaration | N.ExportNamedDeclaration | N.ImportDeclaration + >, ): boolean { if (node.assertions != null) { return node.assertions.some(({ key, value }) => { @@ -2425,14 +2579,17 @@ export default class StatementParser extends ExpressionParser { } checkJSONModuleImport( - node: - | N.ExportAllDeclaration - | N.ExportNamedDeclaration - | N.ImportDeclaration, + node: Undone< + N.ExportAllDeclaration | N.ExportNamedDeclaration | N.ImportDeclaration + >, ) { + // @ts-expect-error Fixme: node.type must be undefined because they are undone if (this.isJSONModuleImport(node) && node.type !== "ExportAllDeclaration") { + // @ts-expect-error const { specifiers } = node; + // @ts-expect-error if (node.specifiers != null) { + // @ts-expect-error refine specifier types const nonDefaultNamedSpecifier = specifiers.find(specifier => { let imported; if (specifier.type === "ExportSpecifier") { @@ -2458,7 +2615,7 @@ export default class StatementParser extends ExpressionParser { // Parses import declaration. // https://tc39.es/ecma262/#prod-ImportDeclaration - parseImport(node: N.Node): N.AnyImport { + parseImport(this: Parser, node: Undone): N.AnyImport { // import '...' node.specifiers = []; if (!this.match(tt.string)) { @@ -2490,6 +2647,7 @@ export default class StatementParser extends ExpressionParser { } else if (!process.env.BABEL_8_BREAKING) { const attributes = this.maybeParseModuleAttributes(); if (attributes) { + // @ts-expect-error attributes have been deprecated node.attributes = attributes; } } @@ -2499,27 +2657,38 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ImportDeclaration"); } - parseImportSource(): N.StringLiteral { + parseImportSource(this: Parser): N.StringLiteral { if (!this.match(tt.string)) this.unexpected(); - return this.parseExprAtom(); + return this.parseExprAtom() as N.StringLiteral; } - // eslint-disable-next-line no-unused-vars - shouldParseDefaultImport(node: N.ImportDeclaration): boolean { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + shouldParseDefaultImport(node: Undone): boolean { return tokenIsIdentifier(this.state.type); } - parseImportSpecifierLocal( - node: N.ImportDeclaration, - specifier: N.Node, - type: string, + parseImportSpecifierLocal< + T extends + | N.ImportSpecifier + | N.ImportDefaultSpecifier + | N.ImportNamespaceSpecifier, + >( + node: Undone, + specifier: Undone, + type: T["type"], ): void { specifier.local = this.parseIdentifier(); node.specifiers.push(this.finishImportSpecifier(specifier, type)); } - finishImportSpecifier(specifier: N.Node, type: string) { + finishImportSpecifier< + T extends + | N.ImportSpecifier + | N.ImportDefaultSpecifier + | N.ImportNamespaceSpecifier, + >(specifier: Undone, type: T["type"]) { this.checkLVal(specifier.local, { + // @ts-expect-error refine types in: specifier, binding: BIND_LEXICAL, }); @@ -2569,8 +2738,7 @@ export default class StatementParser extends ExpressionParser { }); } node.value = this.parseStringLiteral(this.state.value); - this.finishNode(node, "ImportAttribute"); - attrs.push(node); + attrs.push(this.finishNode(node, "ImportAttribute")); } while (this.eat(tt.comma)); return attrs; @@ -2640,12 +2808,12 @@ export default class StatementParser extends ExpressionParser { return attrs; } - maybeParseDefaultImportSpecifier(node: N.ImportDeclaration): boolean { + maybeParseDefaultImportSpecifier(node: Undone): boolean { if (this.shouldParseDefaultImport(node)) { // import defaultObj, { x, y as z } from '...' this.parseImportSpecifierLocal( node, - this.startNode(), + this.startNode(), "ImportDefaultSpecifier", ); return true; @@ -2653,9 +2821,9 @@ export default class StatementParser extends ExpressionParser { return false; } - maybeParseStarImportSpecifier(node: N.ImportDeclaration): boolean { + maybeParseStarImportSpecifier(node: Undone): boolean { if (this.match(tt.star)) { - const specifier = this.startNode(); + const specifier = this.startNode(); this.next(); this.expectContextual(tt._as); @@ -2669,7 +2837,7 @@ export default class StatementParser extends ExpressionParser { return false; } - parseNamedImportSpecifiers(node: N.ImportDeclaration) { + parseNamedImportSpecifiers(node: Undone) { let first = true; this.expect(tt.braceL); while (!this.eat(tt.braceR)) { @@ -2687,7 +2855,7 @@ export default class StatementParser extends ExpressionParser { if (this.eat(tt.braceR)) break; } - const specifier = this.startNode(); + const specifier = this.startNode(); const importedIsString = this.match(tt.string); const isMaybeTypeOnly = this.isContextual(tt._type); specifier.imported = this.parseModuleExportName(); @@ -2703,12 +2871,12 @@ export default class StatementParser extends ExpressionParser { // https://tc39.es/ecma262/#prod-ImportSpecifier parseImportSpecifier( - specifier: any, + specifier: Undone, importedIsString: boolean, - /* eslint-disable no-unused-vars -- used in TypeScript and Flow parser */ + /* eslint-disable @typescript-eslint/no-unused-vars -- used in TypeScript and Flow parser */ isInTypeOnlyImport: boolean, isMaybeTypeOnly: boolean, - /* eslint-enable no-unused-vars */ + /* eslint-enable @typescript-eslint/no-unused-vars */ ): N.ImportSpecifier { if (this.eatContextual(tt._as)) { specifier.local = this.parseIdentifier(); @@ -2717,10 +2885,15 @@ export default class StatementParser extends ExpressionParser { if (importedIsString) { throw this.raise(Errors.ImportBindingIsString, { at: specifier, - importName: imported.value, + importName: (imported as N.StringLiteral).value, }); } - this.checkReservedWord(imported.name, specifier.loc.start, true, true); + this.checkReservedWord( + (imported as N.Identifier).name, + specifier.loc.start, + true, + true, + ); if (!specifier.local) { specifier.local = cloneIdentifier(imported); } diff --git a/packages/babel-parser/src/parser/util.ts b/packages/babel-parser/src/parser/util.ts index 6f53fc57b3c8..50688232af4f 100644 --- a/packages/babel-parser/src/parser/util.ts +++ b/packages/babel-parser/src/parser/util.ts @@ -6,7 +6,7 @@ import { } from "../tokenizer/types"; import Tokenizer from "../tokenizer"; import State from "../tokenizer/state"; -import type { Node } from "../types"; +import type { EstreePropertyDefinition, Node, ObjectProperty } from "../types"; import { lineBreak, skipWhiteSpaceToLineBreak } from "../util/whitespace"; import { isIdentifierChar } from "../util/identifier"; import ClassScopeHandler from "../util/class-scope"; @@ -21,6 +21,7 @@ import { type ParseError, type ParseErrorConstructor, } from "../parse-error"; +import type Parser from "."; /*:: import type ScopeHandler from "../util/scope"; @@ -196,6 +197,7 @@ export default class UtilParser extends Tokenizer { const failState = this.state; this.state = oldState; if (error instanceof SyntaxError) { + // @ts-expect-error casting general syntax error to parse error return { node: null, error, thrown: true, aborted: false, failState }; } if (error === abortSignal) { @@ -303,7 +305,9 @@ export default class UtilParser extends Tokenizer { ); } - isObjectProperty(node: Node): boolean { + isObjectProperty( + node: Node, + ): node is ObjectProperty | EstreePropertyDefinition { return node.type === "ObjectProperty"; } @@ -312,6 +316,7 @@ export default class UtilParser extends Tokenizer { } initializeScopes( + this: Parser, inModule: boolean = this.options.sourceType === "module", ): () => void { // Initialize state diff --git a/packages/babel-parser/src/plugin-utils.ts b/packages/babel-parser/src/plugin-utils.ts index 3054d5f99fc7..b2d1cc17bf9c 100644 --- a/packages/babel-parser/src/plugin-utils.ts +++ b/packages/babel-parser/src/plugin-utils.ts @@ -1,5 +1,5 @@ import type Parser from "./parser"; -import type { PluginConfig } from "./parser/base"; +import type { PluginConfig } from "./typings"; export type Plugin = PluginConfig; @@ -37,6 +37,7 @@ export function hasPlugin( return false; } for (const key of expectedKeys) { + // @ts-expect-error key may not exist in plugin options if (pluginOptions[key] !== expectedOptions[key]) { return false; } @@ -60,6 +61,7 @@ export function getPluginOption( }); if (plugin && Array.isArray(plugin)) { + // @ts-expect-error Fixme: should check whether option is defined return plugin[1][option]; } @@ -202,7 +204,7 @@ export function validatePlugins(plugins: PluginList) { const error = new Error( "'asyncDoExpressions' requires 'doExpressions', please add 'doExpressions' to parser plugins.", ); - // $FlowIgnore + // @ts-expect-error error.missingPlugins = "doExpressions"; // so @babel/core can provide better error message throw error; } @@ -229,5 +231,6 @@ export const mixinPlugins: { placeholders, }; -export const mixinPluginNames: ReadonlyArray = - Object.keys(mixinPlugins); +export const mixinPluginNames = Object.keys(mixinPlugins) as ReadonlyArray< + "estree" | "jsx" | "flow" | "typescript" | "v8intrinsic" | "placeholders" +>; diff --git a/packages/babel-parser/src/tokenizer/index.ts b/packages/babel-parser/src/tokenizer/index.ts index d7fd1bb34897..5cbda4602559 100644 --- a/packages/babel-parser/src/tokenizer/index.ts +++ b/packages/babel-parser/src/tokenizer/index.ts @@ -6,7 +6,7 @@ import { SourceLocation, createPositionWithColumnOffset, } from "../util/location"; -import CommentsParser from "../parser/comments"; +import CommentsParser, { type CommentWhitespace } from "../parser/comments"; import * as N from "../types"; import * as charCodes from "charcodes"; import { isIdentifierStart, isIdentifierChar } from "../util/identifier"; @@ -44,6 +44,8 @@ import { type StringContentsErrorHandlers, } from "@babel/helper-string-parser"; +import type { Plugin } from "../typings"; + const VALID_REGEX_FLAGS = new Set([ charCodes.lowercaseG, charCodes.lowercaseM, @@ -180,7 +182,7 @@ export default class Tokenizer extends CommentsParser { lookahead(): LookaheadState { const old = this.state; // For performance we use a simplified tokenizer state structure - // $FlowIgnore + // @ts-expect-error this.state = this.createLookaheadState(old); this.isLookahead = true; @@ -282,7 +284,7 @@ export default class Tokenizer extends CommentsParser { if (this.isLookahead) return; /*:: invariant(startLoc) */ - const comment = { + const comment: N.CommentBlock = { type: "CommentBlock", value: this.input.slice(start + 2, end), start, @@ -312,7 +314,7 @@ export default class Tokenizer extends CommentsParser { const end = this.state.pos; const value = this.input.slice(start + startSkip, end); - const comment = { + const comment: N.CommentLine = { type: "CommentLine", value, start, @@ -357,6 +359,7 @@ export default class Tokenizer extends CommentsParser { case charCodes.asterisk: { const comment = this.skipBlockComment(); if (comment !== undefined) { + // @ts-expect-error strictNullCheck is not enabled this.addComment(comment); if (this.options.attachComment) comments.push(comment); } @@ -366,6 +369,7 @@ export default class Tokenizer extends CommentsParser { case charCodes.slash: { const comment = this.skipLineComment(2); if (comment !== undefined) { + // @ts-expect-error strictNullCheck is not enabled this.addComment(comment); if (this.options.attachComment) comments.push(comment); } @@ -390,6 +394,7 @@ export default class Tokenizer extends CommentsParser { // A `-->` line comment const comment = this.skipLineComment(3); if (comment !== undefined) { + // @ts-expect-error strictNullCheck is not enabled this.addComment(comment); if (this.options.attachComment) comments.push(comment); } @@ -406,6 +411,7 @@ export default class Tokenizer extends CommentsParser { // `