Improve @babel/parser error types (#17531)

* improve

* `yarn gulp bundle-dts`

* improve

---------

Co-authored-by: Nicolò Ribaudo <[email protected]>
This commit is contained in:
liuxingbaoyu
2026-01-30 20:22:03 +01:00
committed by GitHub
co-authored by Nicolò Ribaudo
parent 512d2ac59f
commit 65f2df4c14
19 changed files with 750 additions and 184 deletions
+12 -3
View File
@@ -22,6 +22,7 @@ import rollupTerser from "@rollup/plugin-terser";
import rollupDts from "rollup-plugin-dts";
import { Worker as JestWorker } from "jest-worker";
import { Glob } from "glob";
import { patchErrorInfo } from "./packages/babel-parser/scripts/build-error-info.ts";
// @ts-expect-error no types
import rollupBabelSource from "./scripts/rollup-plugin-babel-source.js";
@@ -629,7 +630,7 @@ function buildRollup(packages: PackageInfo[], buildStandalone?: boolean) {
);
}
function buildRollupDts(packages: string[]) {
async function buildRollupDts(packages: string[]) {
async function build(
input: string,
output: string,
@@ -701,10 +702,12 @@ function buildRollupDts(packages: string[]) {
await build(input, output, "", packageName);
});
const parserDts = "packages/babel-parser/typings/babel-parser.d.ts";
tasks.push(
build(
"packages/babel-parser/typings/babel-parser.source.d.ts",
"packages/babel-parser/typings/babel-parser.d.ts",
parserDts,
"// This file is auto-generated! Do not modify it directly.\n" +
"// Run `yarn gulp bundle-dts` to re-generate it.\n" +
// @typescript-eslint/no-redundant-type-constituents can be removed once we drop the IF_BABEL_7 type
@@ -713,7 +716,13 @@ function buildRollupDts(packages: string[]) {
)
);
return Promise.all(tasks);
await Promise.all(tasks);
patchErrorInfo(parserDts);
await build(parserDts, parserDts, "", "packages/babel-parser");
fs.writeFileSync(
parserDts,
await formatCode(fs.readFileSync(parserDts, "utf8"), parserDts)
);
}
function* packagesIterator(exclude: Set<string>) {
@@ -0,0 +1,56 @@
import { readFileSync, writeFileSync } from "node:fs";
// eslint-disable-next-line import/no-extraneous-dependencies
import ts from "typescript";
function extractErrorInfo(filename: string) {
const program = ts.createProgram([filename], {});
const checker = program.getTypeChecker();
const sourceFile = program.getSourceFile(filename)!;
let info = "{";
ts.forEachChild(sourceFile, node => {
if (ts.isTypeAliasDeclaration(node) && node.name.text === "__ExtractMe") {
const type = checker.getTypeAtLocation(node);
const properties = type.getProperties();
properties.forEach(prop => {
const propType = checker.getTypeOfSymbolAtLocation(prop, node);
if (propType.flags & ts.TypeFlags.String) {
info += `${prop.name}:[],`;
} else if (propType.flags & ts.TypeFlags.Object) {
const code = propType.getProperty("code")!;
if (code) {
const codeType = checker.getTypeOfSymbolAtLocation(
code,
code.valueDeclaration!
) as ts.StringLiteralType;
info += `${prop.name}:[object,${JSON.stringify(codeType.value)}],`;
} else {
const signatures = propType.getCallSignatures();
const param = signatures[0].getParameters()[0];
const paramType = checker.getTypeOfSymbolAtLocation(
param,
param.valueDeclaration!
);
info += `${prop.name}:[${checker.typeToString(paramType, undefined, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.InTypeAlias)}],`;
}
}
});
}
});
info += "}";
return info;
}
export function patchErrorInfo(filename: string) {
const info = extractErrorInfo(filename);
let file = readFileSync(filename, "utf8");
file = file.replaceAll("__PatchMe = never &", `__PatchMe =`);
file = file.replaceAll(
"ErrorInfoCompressed = {}",
`ErrorInfoCompressed = ${info}`
);
file = file.replace("ErrorsObjects[keyof ErrorsObjects]", "never");
writeFileSync(filename, file);
}
+3 -3
View File
@@ -11,7 +11,8 @@ export type {
TypeScriptPluginOptions,
} from "./typings.ts";
import Parser, { type PluginsMap } from "./parser/index.ts";
import type { ParseError as ParseErrorGeneric } from "./parse-error.ts";
import type { ParseError } from "./parse-error.ts";
export type { ParseError };
import type { ExportedTokenType } from "./tokenizer/types.ts";
import {
@@ -28,10 +29,9 @@ export type { Expression, File };
export type ParserOptions = Partial<Options>;
export type ParseError = ParseErrorGeneric<object>;
export type ParseResult<Result extends File | Expression = File> = Result & {
comments: File["comments"];
errors: null | ParseError[];
errors: ParseError[];
tokens?: File["tokens"];
};
+74 -5
View File
@@ -36,9 +36,15 @@ interface ParseErrorSpecification<ErrorDetails> {
pos: number;
}
export type ParseError<ErrorDetails> = SyntaxError &
export type ParseErrorGeneric<ErrorDetails> = SyntaxError &
ParseErrorSpecification<ErrorDetails>;
export type ParseError = SyntaxError & {
missingPlugin?: string | string[];
loc: Position;
pos: number;
} & ErrorInfo;
// By `ParseErrorConstructor`, we mean something like the new-less style
// `ErrorConstructor`[1], since `ParseError`'s are not themselves actually
// separate classes from `SyntaxError`'s.
@@ -47,7 +53,7 @@ export type ParseError<ErrorDetails> = SyntaxError &
export type ParseErrorConstructor<ErrorDetails> = (
loc: Position,
details: ErrorDetails,
) => ParseError<ErrorDetails>;
) => ParseError;
type ToMessage<ErrorDetails> = (self: ErrorDetails) => string;
@@ -76,7 +82,7 @@ function toParseErrorConstructor<ErrorDetails extends object>({
reasonCode === "MissingPlugin" || reasonCode === "MissingOneOfPlugins";
return function constructor(loc: Position, details: ErrorDetails) {
const error: ParseError<ErrorDetails> = new SyntaxError() as any;
const error = new SyntaxError() as ParseErrorGeneric<ErrorDetails>;
error.code = code as ParseErrorCode;
error.reasonCode = reasonCode;
@@ -104,7 +110,7 @@ function toParseErrorConstructor<ErrorDetails extends object>({
Object.defineProperty(error, "message", {
configurable: true,
get(this: ParseError<ErrorDetails>): string {
get(this: ParseErrorGeneric<ErrorDetails>): string {
const message = `${toMessage(details)} (${loc.line}:${loc.column})`;
this.message = message;
return message;
@@ -114,7 +120,7 @@ function toParseErrorConstructor<ErrorDetails extends object>({
},
});
return error;
return error as ParseError;
};
}
@@ -225,6 +231,10 @@ import StandardErrors from "./parse-error/standard-errors.ts";
import StrictModeErrors from "./parse-error/strict-mode-errors.ts";
import ParseExpressionErrors from "./parse-error/parse-expression-errors.ts";
import PipelineOperatorErrors from "./parse-error/pipeline-operator-errors.ts";
import type { TSErrorTemplates } from "./plugins/typescript/index.ts";
import type { FlowErrorTemplates } from "./plugins/flow/index.ts";
import type { JsxErrorTemplates } from "./plugins/jsx/index.ts";
import type { PlaceholderErrorTemplates } from "./plugins/placeholders.ts";
export const Errors = {
...ParseErrorEnum(ModuleErrors),
@@ -234,4 +244,63 @@ export const Errors = {
...ParseErrorEnum`pipelineOperator`(PipelineOperatorErrors),
};
type ErrorToObject<T> = {
[K in keyof T]: {
code: T[K] extends { code: string }
? T[K]["code"]
: "BABEL_PARSER_SYNTAX_ERROR";
reasonCode: K;
details: T[K] extends { message: string | ToMessage<any> }
? T[K]["message"] extends ToMessage<any>
? Parameters<T[K]["message"]>[0]
: object
: T[K] extends ToMessage<any>
? Parameters<T[K]>[0]
: object;
};
};
type __ExtractMe = typeof ModuleErrors &
typeof StandardErrors &
typeof StrictModeErrors &
typeof ParseExpressionErrors &
typeof PipelineOperatorErrors &
typeof TSErrorTemplates &
typeof FlowErrorTemplates &
typeof JsxErrorTemplates &
typeof PlaceholderErrorTemplates;
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
type __PatchMe = never & Decompress<ErrorInfoCompressed>;
type ErrorsObjects = ErrorToObject<__ExtractMe>;
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
type ErrorInfo = __PatchMe | ErrorsObjects[keyof ErrorsObjects];
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
type ErrorInfoCompressed = {};
type Decompress<T extends object> = {
[K in keyof T]: T[K] extends [infer Param, infer Code]
? {
code: Code;
reasonCode: K;
details: Param;
}
: T[K] extends [infer Param]
? {
code: "BABEL_PARSER_SYNTAX_ERROR";
reasonCode: K;
details: Param;
}
: T[K] extends []
? {
code: "BABEL_PARSER_SYNTAX_ERROR";
reasonCode: K;
details: object;
}
: never;
};
export type { LValAncestor } from "./parse-error/standard-errors.ts";
+1 -2
View File
@@ -78,8 +78,7 @@ export default class Parser extends StatementParser {
const file = this.startNode<N.File>();
const program = this.startNode<N.Program>();
this.nextToken();
// @ts-expect-error define later
file.errors = null;
file.errors = [];
const result = this.parseTopLevel(file, program);
result.errors = this.state.errors;
result.comments.length = this.state.commentsLen;
+1 -1
View File
@@ -165,7 +165,7 @@ export default abstract class UtilParser extends Tokenizer {
oldState: State = this.state.clone(),
):
| TryParse<T, null, false, false, null>
| TryParse<T | null, ParseError<any>, boolean, false, State>
| TryParse<T | null, ParseError, boolean, false, State>
| TryParse<T | null, null, false, true, State> {
const abortSignal: {
node: T | null;
@@ -20,7 +20,11 @@ import FlowScopeHandler from "./scope.ts";
import { BindingFlag, ScopeFlag } from "../../util/scopeflags.ts";
import type { ExpressionErrors } from "../../parser/util.ts";
import type { ParseStatementFlag } from "../../parser/statement.ts";
import { Errors, ParseErrorEnum } from "../../parse-error.ts";
import {
Errors,
ParseErrorEnum,
type ParseErrorTemplates,
} from "../../parse-error.ts";
import type { Undone } from "../../parser/node.ts";
import type { ClassWithMixin, IJSXParserMixin } from "../jsx/index.ts";
@@ -45,7 +49,7 @@ const reservedTypes = new Set([
/* eslint sort-keys: "error" */
// The Errors key follows https://github.com/facebook/flow/blob/master/src/parser/parse_error.ml unless it does not exist
const FlowErrors = ParseErrorEnum`flow`({
export const FlowErrorTemplates = {
AmbiguousConditionalArrow:
"Ambiguous expression: wrap the arrow functions in parentheses to disambiguate.",
AmbiguousDeclareModuleKind:
@@ -217,9 +221,11 @@ const FlowErrors = ParseErrorEnum`flow`({
UnsupportedStatementInDeclareModule:
"Only declares and type imports are allowed inside declare module.",
UnterminatedFlowComment: "Unterminated flow-comment.",
});
} satisfies ParseErrorTemplates;
/* eslint-disable sort-keys */
const FlowErrors = ParseErrorEnum`flow`(FlowErrorTemplates);
function isEsModuleType(bodyElement: N.Node): boolean {
return (
bodyElement.type === "DeclareExportAllDeclaration" ||
@@ -16,11 +16,15 @@ import type * as N from "../../types.ts";
import { isIdentifierChar, isIdentifierStart } from "../../util/identifier.ts";
import type { Position } from "../../util/location.ts";
import { isNewLine } from "../../util/whitespace.ts";
import { Errors, ParseErrorEnum } from "../../parse-error.ts";
import {
Errors,
ParseErrorEnum,
type ParseErrorTemplates,
} from "../../parse-error.ts";
import type { Undone } from "../../parser/node.ts";
/* eslint sort-keys: "error" */
const JsxErrors = ParseErrorEnum`jsx`({
export const JsxErrorTemplates = {
AttributeIsEmpty:
"JSX attributes must only be assigned a non-empty expression.",
MissingClosingTagElement: ({ openingTagName }: { openingTagName: string }) =>
@@ -42,10 +46,11 @@ const JsxErrors = ParseErrorEnum`jsx`({
UnterminatedJsxContent: "Unterminated JSX contents.",
UnwrappedAdjacentJSXElements:
"Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?",
});
} satisfies ParseErrorTemplates;
/* eslint-disable sort-keys */
const JsxErrors = ParseErrorEnum`jsx`(JsxErrorTemplates);
function isFragment(object?: N.JSXTag | null): object is N.JSXFragmentTag {
return object
? object.type === "JSXOpeningFragment" ||
@@ -3,7 +3,7 @@ import * as charCodes from "charcodes";
import { tokenLabelName, tt } from "../tokenizer/types.ts";
import type Parser from "../parser/index.ts";
import type * as N from "../types.ts";
import { ParseErrorEnum } from "../parse-error.ts";
import { ParseErrorEnum, type ParseErrorTemplates } from "../parse-error.ts";
import type { Undone } from "../parser/node.ts";
import type { ExpressionErrors } from "../parser/util.ts";
import type { BindingFlag } from "../util/scopeflags.ts";
@@ -30,10 +30,14 @@ type NodeOf<T extends keyof PossiblePlaceholders> = PossiblePlaceholders[T];
type MaybePlaceholder<T extends PlaceholderTypes> = NodeOf<T>; // | Placeholder<T>
/* eslint sort-keys: "error" */
const PlaceholderErrors = ParseErrorEnum`placeholders`({
export const PlaceholderErrorTemplates = {
ClassNameIsRequired: "A class name is required.",
UnexpectedSpace: "Unexpected space in placeholder.",
});
} satisfies ParseErrorTemplates;
const PlaceholderErrors = ParseErrorEnum`placeholders`(
PlaceholderErrorTemplates,
);
export default (superClass: typeof Parser) =>
class PlaceholdersParserMixin extends superClass implements Parser {
@@ -21,7 +21,11 @@ import * as charCodes from "charcodes";
import type { ExpressionErrors } from "../../parser/util.ts";
import type { ParseStatementFlag } from "../../parser/statement.ts";
import { ParamKind } from "../../util/production-parameter.ts";
import { Errors, ParseErrorEnum } from "../../parse-error.ts";
import {
Errors,
ParseErrorEnum,
type ParseErrorTemplates,
} from "../../parse-error.ts";
import type { Undone } from "../../parser/node.ts";
import type { ClassWithMixin, IJSXParserMixin } from "../jsx/index.ts";
import { ParseBindingListFlags } from "../../parser/lval.ts";
@@ -65,7 +69,7 @@ type ModifierBase = {
} & Partial<Record<TsModifier, boolean | undefined | null>>;
/* eslint sort-keys: "error" */
const TSErrors = ParseErrorEnum`typescript`({
export const TSErrorTemplates = {
AbstractMethodHasImplementation: ({ methodName }: { methodName: string }) =>
`Method '${methodName}' cannot have an implementation because it is marked abstract.`,
AbstractPropertyHasInitializer: ({
@@ -223,10 +227,11 @@ const TSErrors = ParseErrorEnum`typescript`({
`Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got ${type}.`,
UsingDeclarationInAmbientContext: (kind: "using" | "await using") =>
`'${kind}' declarations are not allowed in ambient contexts.`,
});
} satisfies ParseErrorTemplates;
/* eslint-disable sort-keys */
const TSErrors = ParseErrorEnum`typescript`(TSErrorTemplates);
// Doesn't handle "void" or "null" because those are keywords, not identifiers.
// It also doesn't handle "intrinsic", since usually it's not a keyword.
function keywordTypeFromName(value: string): N.TsKeywordTypeType | undefined {
+4 -7
View File
@@ -19,11 +19,8 @@ import {
type TokenType,
} from "./types.ts";
import type { TokContext } from "./context.ts";
import {
Errors,
type ParseError,
type ParseErrorConstructor,
} from "../parse-error.ts";
import type { ParseError } from "../parse-error.ts";
import { Errors, type ParseErrorConstructor } from "../parse-error.ts";
import {
lineBreakG,
isNewLine,
@@ -1390,7 +1387,7 @@ export default abstract class Tokenizer extends CommentsParser {
toParseError: ParseErrorConstructor<ErrorDetails>,
at: Position | Undone<Node>,
details: ErrorDetails = {} as ErrorDetails,
): ParseError<ErrorDetails> {
): ParseError {
const loc = at instanceof Position ? at : at.loc.start;
const error = toParseError(loc, details);
@@ -1410,7 +1407,7 @@ export default abstract class Tokenizer extends CommentsParser {
toParseError: ParseErrorConstructor<ErrorDetails>,
at: Position | Undone<Node>,
details: ErrorDetails = {} as ErrorDetails,
): ParseError<ErrorDetails> | never {
): ParseError {
const loc = at instanceof Position ? at : at.loc.start;
const pos = loc.index;
const errors = this.state.errors;
+2 -3
View File
@@ -4,8 +4,7 @@ import { Position } from "../util/location.ts";
import { types as ct, type TokContext } from "./context.ts";
import { tt, type TokenType } from "./types.ts";
import type { Errors } from "../parse-error.ts";
import type { ParseError } from "../parse-error.ts";
import type { Errors, ParseError } from "../parse-error.ts";
export type DeferredStrictError =
| typeof Errors.StrictNumericEscape
@@ -68,7 +67,7 @@ export default class State {
);
}
errors: ParseError<any>[] = [];
errors: ParseError[] = [];
// Used to signify the start of a potential arrow function
potentialArrowAt: number = -1;
+1 -1
View File
@@ -254,7 +254,7 @@ export type ExportedToken = Omit<Token, "type"> & { type: ExportedTokenType };
export interface ParserOutput {
comments: Comment[];
errors: ParseError<any>[];
errors: ParseError[];
tokens?: (ExportedToken | Comment)[];
}
// Programs
+11
View File
@@ -0,0 +1,11 @@
import { expect, it } from "tstyche";
import type { ParseError } from "../src/index.ts";
it("errors", () => {
const e = {} as ParseError;
if (e.reasonCode === "AccessorIsGenerator") {
expect(e.code).type.toBe<"BABEL_PARSER_SYNTAX_ERROR">();
expect(e.details.kind).type.toBe<"get" | "set">();
}
});
+1
View File
@@ -8,6 +8,7 @@
"include": [
"./src/**/*.ts",
"./src/**/*.cts",
"./scripts/**/*.ts",
"../../lib/globals.d.ts",
"../../scripts/repo-utils/*.d.ts"
],
+528 -142
View File
@@ -1,27 +1,43 @@
import { File, Expression } from "@babel/types";
// This file is auto-generated! Do not modify it directly.
// Run `yarn gulp bundle-dts` to re-generate it.
/* eslint-disable @typescript-eslint/consistent-type-imports, @typescript-eslint/no-redundant-type-constituents */
import { File, Expression } from '@babel/types';
declare class Position {
line: number;
column: number;
index: number;
constructor(line: number, col: number, index: number);
line: number;
column: number;
index: number;
constructor(line: number, col: number, index: number);
}
//# sourceMappingURL=module-errors.d.ts.map
type SyntaxPlugin = "flow" | "typescript" | "jsx" | "pipelineOperator" | "placeholders";
type ParseErrorCode = "BABEL_PARSER_SYNTAX_ERROR" | "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED";
interface ParseErrorSpecification<ErrorDetails> {
code: ParseErrorCode;
reasonCode: string;
syntaxPlugin?: SyntaxPlugin;
missingPlugin?: string | string[];
loc: Position;
details: ErrorDetails;
pos: number;
}
type ParseError$1<ErrorDetails> = SyntaxError & ParseErrorSpecification<ErrorDetails>;
type LValAncestor =
| {
type: "UpdateExpression";
prefix: boolean;
}
| {
type:
| "ArrayPattern"
| "AssignmentExpression"
| "CatchClause"
| "ForOfStatement"
| "FormalParameters"
| "ForInStatement"
| "ForStatement"
| "ImportSpecifier"
| "ImportNamespaceSpecifier"
| "ImportDefaultSpecifier"
| "ParenthesizedExpression"
| "ObjectPattern"
| "RestElement"
| "VariableDeclarator";
};
//# sourceMappingURL=parse-expression-errors.d.ts.map
type Accessibility = "public" | "protected" | "private";
type VarianceAnnotations = "in" | "out";
type BABEL_8_BREAKING = true;
type IF_BABEL_7<V> = false extends BABEL_8_BREAKING ? V : never;
@@ -106,146 +122,516 @@ interface TypeScriptPluginOptions {
disallowAmbiguousJSXLike?: boolean;
}
type TsModifier =
| "readonly"
| "abstract"
| "declare"
| "static"
| "override"
| "const"
| Accessibility
| VarianceAnnotations;
type EnumExplicitType = null | "boolean" | "number" | "string" | "symbol";
type ParseError = SyntaxError & {
missingPlugin?: string | string[];
loc: Position;
pos: number;
} & ErrorInfo;
type __PatchMe = Decompress<ErrorInfoCompressed>;
type ErrorInfo = __PatchMe | never;
type ErrorInfoCompressed = {
ImportMetaOutsideModule: [object, "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED"];
ImportOutsideModule: [object, "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED"];
AccessorIsGenerator: [{ kind: "get" | "set" }];
ArgumentsInClass: [];
AsyncFunctionInSingleStatementContext: [];
AwaitBindingIdentifier: [];
AwaitBindingIdentifierInStaticBlock: [];
AwaitExpressionFormalParameter: [];
AwaitUsingNotInAsyncContext: [];
AwaitNotInAsyncContext: [];
BadGetterArity: [];
BadSetterArity: [];
BadSetterRestParameter: [];
ConstructorClassField: [];
ConstructorClassPrivateField: [];
ConstructorIsAccessor: [];
ConstructorIsAsync: [];
ConstructorIsGenerator: [];
DeclarationMissingInitializer: [
{ kind: "await using" | "const" | "destructuring" | "using" },
];
DecoratorArgumentsOutsideParentheses: [];
DecoratorsBeforeAfterExport: [];
DecoratorConstructor: [];
DecoratorSemicolon: [];
DecoratorStaticBlock: [];
DeferImportRequiresNamespace: [];
DeletePrivateField: [];
DestructureNamedImport: [];
DuplicateConstructor: [];
DuplicateDefaultExport: [];
DuplicateExport: [{ exportName: string }];
DuplicateProto: [];
DuplicateRegExpFlags: [];
ElementAfterRest: [];
EscapedCharNotAnIdentifier: [];
ExportBindingIsString: [{ localName: string; exportName: string }];
ExportDefaultFromAsIdentifier: [];
ForInOfLoopInitializer: [{ type: "ForInStatement" | "ForOfStatement" }];
ForInUsing: [];
ForOfAsync: [];
ForOfLet: [];
GeneratorInSingleStatementContext: [];
IllegalBreakContinue: [{ type: "BreakStatement" | "ContinueStatement" }];
IllegalLanguageModeDirective: [];
IllegalReturn: [];
ImportBindingIsString: [{ importName: string }];
ImportCallArity: [];
ImportCallNotNewExpression: [];
ImportCallSpreadArgument: [];
IncompatibleRegExpUVFlags: [];
InvalidBigIntLiteral: [];
InvalidCodePoint: [];
InvalidCoverDiscardElement: [];
InvalidCoverInitializedName: [];
InvalidDigit: [{ radix: number }];
InvalidEscapeSequence: [];
InvalidEscapeSequenceTemplate: [];
InvalidEscapedReservedWord: [{ reservedWord: string }];
InvalidIdentifier: [{ identifierName: string }];
InvalidLhs: [{ ancestor: LValAncestor }];
InvalidLhsBinding: [{ ancestor: LValAncestor }];
InvalidLhsOptionalChaining: [{ ancestor: LValAncestor }];
InvalidNumber: [];
InvalidOrMissingExponent: [];
InvalidOrUnexpectedToken: [{ unexpected: string }];
InvalidParenthesizedAssignment: [];
InvalidPrivateFieldResolution: [{ identifierName: string }];
InvalidPropertyBindingPattern: [];
InvalidRestAssignmentPattern: [];
LabelRedeclaration: [{ labelName: string }];
LetInLexicalBinding: [];
LineTerminatorBeforeArrow: [];
MalformedRegExpFlags: [];
MissingClassName: [];
MissingEqInAssignment: [];
MissingSemicolon: [];
MissingPlugin: [{ missingPlugin: [string] }];
MissingOneOfPlugins: [{ missingPlugin: string[] }];
MissingUnicodeEscape: [];
MixingCoalesceWithLogical: [];
ModuleAttributeInvalidValue: [];
ModuleAttributesWithDuplicateKeys: [{ key: string }];
ModuleExportNameHasLoneSurrogate: [{ surrogateCharCode: number }];
ModuleExportUndefined: [{ localName: string }];
MultipleDefaultsInSwitch: [];
NewlineAfterThrow: [];
NoCatchOrFinally: [];
NumberIdentifier: [];
NumericSeparatorInEscapeSequence: [];
ObsoleteAwaitStar: [];
OptionalChainingNoNew: [];
OptionalChainingNoTemplate: [];
OverrideOnConstructor: [];
ParamDupe: [];
PatternHasAccessor: [];
PatternHasMethod: [];
PrivateInExpectedIn: [{ identifierName: string }];
PrivateNameRedeclaration: [{ identifierName: string }];
RestTrailingComma: [];
SloppyFunction: [];
SloppyFunctionAnnexB: [];
SourcePhaseImportRequiresDefault: [];
StaticPrototype: [];
SuperNotAllowed: [];
SuperPrivateField: [];
TrailingDecorator: [];
UnexpectedArgumentPlaceholder: [];
UnexpectedDigitAfterHash: [];
UnexpectedImportExport: [];
UnexpectedKeyword: [{ keyword: string }];
UnexpectedLeadingDecorator: [];
UnexpectedLexicalDeclaration: [];
UnexpectedNewTarget: [];
UnexpectedNumericSeparator: [];
UnexpectedPrivateField: [];
UnexpectedReservedWord: [{ reservedWord: string }];
UnexpectedSuper: [];
UnexpectedTokenUnaryExponentiation: [];
UnexpectedUsingDeclaration: [];
UnexpectedVoidPattern: [];
UnsupportedBind: [];
UnsupportedDecoratorExport: [];
UnsupportedDefaultExport: [];
UnsupportedImport: [];
UnsupportedMetaProperty: [{ target: string; onlyValidPropertyName: string }];
UnsupportedParameterDecorator: [];
UnsupportedPropertyDecorator: [];
UnsupportedSuper: [];
UnterminatedComment: [];
UnterminatedRegExp: [];
UnterminatedString: [];
UnterminatedTemplate: [];
UsingDeclarationExport: [];
UsingDeclarationHasBindingPattern: [];
VarRedeclaration: [{ identifierName: string }];
VoidPatternCatchClauseParam: [];
VoidPatternInitializer: [];
YieldBindingIdentifier: [];
YieldInParameter: [];
YieldNotInGeneratorFunction: [];
ZeroDigitNumericSeparator: [];
StrictDelete: [];
StrictEvalArguments: [{ referenceName: string }];
StrictEvalArgumentsBinding: [{ bindingName: string }];
StrictFunction: [];
StrictNumericEscape: [];
StrictOctalLiteral: [];
StrictWith: [];
ParseExpressionEmptyInput: [];
ParseExpressionExpectsEOF: [{ unexpected: number }];
PipeBodyIsTighter: [];
PipeTopicRequiresHackPipes: [];
PipeTopicUnbound: [];
PipeTopicUnconfiguredToken: [{ token: string }];
PipeTopicUnused: [];
PipeUnparenthesizedBody: [
{
type:
| "AssignmentExpression"
| "ArrowFunctionExpression"
| "ConditionalExpression"
| "YieldExpression";
},
];
AbstractMethodHasImplementation: [{ methodName: string }];
AbstractPropertyHasInitializer: [{ propertyName: string }];
AccessorCannotBeOptional: [];
AccessorCannotDeclareThisParameter: [];
AccessorCannotHaveTypeParameters: [];
ClassMethodHasDeclare: [];
ClassMethodHasReadonly: [];
ConstInitializerMustBeStringOrNumericLiteralOrLiteralEnumReference: [];
ConstructorHasTypeParameters: [];
DeclareAccessor: [{ kind: "get" | "set" }];
DeclareClassFieldHasInitializer: [];
DeclareFunctionHasImplementation: [];
DuplicateAccessibilityModifier: [{ modifier: Accessibility }];
DuplicateModifier: [{ modifier: TsModifier }];
EmptyHeritageClauseType: [{ token: "extends" | "implements" }];
EmptyTypeArguments: [];
EmptyTypeParameters: [];
ExpectedAmbientAfterExportDeclare: [];
ImportAliasHasImportType: [];
IncompatibleModifiers: [{ modifiers: [TsModifier, TsModifier] }];
IndexSignatureHasAbstract: [];
IndexSignatureHasAccessibility: [{ modifier: Accessibility }];
IndexSignatureHasDeclare: [];
IndexSignatureHasOverride: [];
IndexSignatureHasStatic: [];
InitializerNotAllowedInAmbientContext: [];
InlineModuleDeclarationMustUseString: [];
InvalidHeritageClauseType: [{ token: "extends" | "implements" }];
InvalidModifierOnAwaitUsingDeclaration: [
| "const"
| Accessibility
| "readonly"
| "abstract"
| "declare"
| "static"
| "override"
| VarianceAnnotations,
];
InvalidModifierOnTypeMember: [{ modifier: TsModifier }];
InvalidModifierOnTypeParameter: [{ modifier: TsModifier }];
InvalidModifierOnTypeParameterPositions: [{ modifier: TsModifier }];
InvalidModifierOnUsingDeclaration: [
| "const"
| Accessibility
| "readonly"
| "abstract"
| "declare"
| "static"
| "override"
| VarianceAnnotations,
];
InvalidModifiersOrder: [{ orderedModifiers: [TsModifier, TsModifier] }];
InvalidPropertyAccessAfterInstantiationExpression: [];
InvalidTupleMemberLabel: [];
MissingInterfaceName: [];
NonAbstractClassHasAbstractMethod: [];
NonClassMethodPropertyHasAbstractModifier: [];
OptionalTypeBeforeRequired: [];
OverrideNotInSubClass: [];
PrivateElementHasAbstract: [];
PrivateElementHasAccessibility: [{ modifier: Accessibility }];
ReadonlyForMethodSignature: [];
ReservedArrowTypeParam: [];
ReservedTypeAssertion: [];
SetAccessorCannotHaveOptionalParameter: [];
SetAccessorCannotHaveRestParameter: [];
SetAccessorCannotHaveReturnType: [];
SingleTypeParameterWithoutTrailingComma: [{ typeParameterName: string }];
StaticBlockCannotHaveModifier: [];
TupleOptionalAfterType: [];
TypeAnnotationAfterAssign: [];
TypeImportCannotSpecifyDefaultAndNamed: [];
TypeModifierIsUsedInTypeExports: [];
TypeModifierIsUsedInTypeImports: [];
UnexpectedParameterModifier: [];
UnexpectedReadonly: [];
UnexpectedTypeAnnotation: [];
UnexpectedTypeCastInParameter: [];
UnsupportedImportTypeArgument: [];
UnsupportedParameterPropertyKind: [];
UnsupportedSignatureParameterKind: [{ type: string }];
UsingDeclarationInAmbientContext: ["await using" | "using"];
AmbiguousConditionalArrow: [];
AmbiguousDeclareModuleKind: [];
AssignReservedType: [{ reservedType: string }];
DeclareClassElement: [];
DeclareClassFieldInitializer: [];
DuplicateDeclareModuleExports: [];
EnumBooleanMemberNotInitialized: [{ memberName: string; enumName: string }];
EnumDuplicateMemberName: [{ memberName: string; enumName: string }];
EnumInconsistentMemberValues: [{ enumName: string }];
EnumInvalidExplicitType: [{ invalidEnumType: string; enumName: string }];
EnumInvalidExplicitTypeUnknownSupplied: [{ enumName: string }];
EnumInvalidMemberInitializerPrimaryType: [
{ enumName: string; memberName: string; explicitType: EnumExplicitType },
];
EnumInvalidMemberInitializerSymbolType: [
{ enumName: string; memberName: string; explicitType: EnumExplicitType },
];
EnumInvalidMemberInitializerUnknownType: [
{ enumName: string; memberName: string; explicitType: EnumExplicitType },
];
EnumInvalidMemberName: [
{ enumName: string; memberName: string; suggestion: string },
];
EnumNumberMemberNotInitialized: [{ enumName: string; memberName: string }];
EnumStringMemberInconsistentlyInitialized: [{ enumName: string }];
GetterMayNotHaveThisParam: [];
ImportTypeShorthandOnlyInPureImport: [];
InexactInsideExact: [];
InexactInsideNonObject: [];
InexactVariance: [];
InvalidNonTypeImportInDeclareModule: [];
MissingTypeParamDefault: [];
NestedDeclareModule: [];
NestedFlowComment: [];
SetterMayNotHaveThisParam: [];
SpreadVariance: [];
ThisParamAnnotationRequired: [];
ThisParamBannedInConstructor: [];
ThisParamMayNotBeOptional: [];
ThisParamMustBeFirst: [];
ThisParamNoDefault: [];
TypeBeforeInitializer: [];
TypeCastInPattern: [];
UnexpectedExplicitInexactInObject: [];
UnexpectedReservedType: [{ reservedType: string }];
UnexpectedReservedUnderscore: [];
UnexpectedSpaceBetweenModuloChecks: [];
UnexpectedSpreadType: [];
UnexpectedSubtractionOperand: [];
UnexpectedTokenAfterTypeParameter: [];
UnexpectedTypeParameterBeforeAsyncArrowFunction: [];
UnsupportedDeclareExportKind: [
{ unsupportedExportKind: string; suggestion: string },
];
UnsupportedStatementInDeclareModule: [];
UnterminatedFlowComment: [];
AttributeIsEmpty: [];
MissingClosingTagElement: [{ openingTagName: string }];
MissingClosingTagFragment: [];
UnexpectedSequenceExpression: [];
UnsupportedJsxValue: [];
UnterminatedJsxContent: [];
UnwrappedAdjacentJSXElements: [];
ClassNameIsRequired: [];
UnexpectedSpace: [];
};
type Decompress<T extends object> = {
[K in keyof T]: T[K] extends [infer Param, infer Code]
? {
code: Code;
reasonCode: K;
details: Param;
}
: T[K] extends [infer Param]
? {
code: "BABEL_PARSER_SYNTAX_ERROR";
reasonCode: K;
details: Param;
}
: T[K] extends []
? {
code: "BABEL_PARSER_SYNTAX_ERROR";
reasonCode: K;
details: object;
}
: never;
};
type Plugin = PluginConfig;
type SourceType = "script" | "commonjs" | "module" | "unambiguous";
interface Options {
/**
* By default, import and export declarations can only appear at a program's top level.
* Setting this option to true allows them anywhere where a statement is allowed.
*/
allowImportExportEverywhere?: boolean;
/**
* By default, await use is not allowed outside of an async function.
* Set this to true to accept such code.
*/
allowAwaitOutsideFunction?: boolean;
/**
* By default, a return statement at the top level raises an error.
* Set this to true to accept such code.
*/
allowReturnOutsideFunction?: boolean;
/**
* By default, new.target use is not allowed outside of a function or class.
* Set this to true to accept such code.
*/
allowNewTargetOutsideFunction?: boolean;
/**
* By default, super calls are not allowed outside of a method.
* Set this to true to accept such code.
*/
allowSuperOutsideMethod?: boolean;
/**
* By default, exported identifiers must refer to a declared variable.
* Set this to true to allow export statements to reference undeclared variables.
*/
allowUndeclaredExports?: boolean;
/**
* By default, yield use is not allowed outside of a generator function.
* Set this to true to accept such code.
*/
allowYieldOutsideFunction?: boolean;
/**
* By default, Babel parser JavaScript code according to Annex B syntax.
* Set this to `false` to disable such behavior.
*/
annexB?: boolean;
/**
* By default, Babel attaches comments to adjacent AST nodes.
* When this option is set to false, comments are not attached.
* It can provide up to 30% performance improvement when the input code has many comments.
* @babel/eslint-parser will set it for you.
* It is not recommended to use attachComment: false with Babel transform,
* as doing so removes all the comments in output code, and renders annotations such as
* /* istanbul ignore next *\/ nonfunctional.
*/
attachComment?: boolean;
/**
* By default, Babel always throws an error when it finds some invalid code.
* When this option is set to true, it will store the parsing error and
* try to continue parsing the invalid input file.
*/
errorRecovery?: boolean;
/**
* Indicate the mode the code should be parsed in.
* Can be one of "script", "commonjs", "module", or "unambiguous". Defaults to "script".
* "unambiguous" will make @babel/parser attempt to guess, based on the presence
* of ES6 import or export statements.
* Files with ES6 imports and exports are considered "module" and are otherwise "script".
*
* Use "commonjs" to parse code that is intended to be run in a CommonJS environment such as Node.js.
*/
sourceType?: SourceType;
/**
* Correlate output AST nodes with their source filename.
* Useful when generating code and source maps from the ASTs of multiple input files.
*/
sourceFilename?: string;
/**
* By default, all source indexes start from 0.
* You can provide a start index to alternatively start with.
* Useful for integration with other source tools.
*/
startIndex?: number;
/**
* By default, the first line of code parsed is treated as line 1.
* You can provide a line number to alternatively start with.
* Useful for integration with other source tools.
*/
startLine?: number;
/**
* By default, the parsed code is treated as if it starts from line 1, column 0.
* You can provide a column number to alternatively start with.
* Useful for integration with other source tools.
*/
startColumn?: number;
/**
* Array containing the plugins that you want to enable.
*/
plugins?: Plugin[];
/**
* Should the parser work in strict mode.
* Defaults to true if sourceType === 'module'. Otherwise, false.
*/
strictMode?: boolean;
/**
* Adds a ranges property to each node: [node.start, node.end]
*/
ranges?: boolean;
/**
* Adds all parsed tokens to a tokens property on the File node.
*/
tokens?: boolean;
/**
* By default, the parser adds information about parentheses by setting
* `extra.parenthesized` to `true` as needed.
* When this option is `true` the parser creates `ParenthesizedExpression`
* AST nodes instead of using the `extra` property.
*/
createParenthesizedExpressions?: boolean;
/**
* By default, the parser parses import expressions as an `ImportExpression` node.
* Set this to false to parse it as `CallExpression(Import, [Identifier(foo)])`.
*/
createImportExpressions?: boolean;
/**
* By default, import and export declarations can only appear at a program's top level.
* Setting this option to true allows them anywhere where a statement is allowed.
*/
allowImportExportEverywhere?: boolean;
/**
* By default, await use is not allowed outside of an async function.
* Set this to true to accept such code.
*/
allowAwaitOutsideFunction?: boolean;
/**
* By default, a return statement at the top level raises an error.
* Set this to true to accept such code.
*/
allowReturnOutsideFunction?: boolean;
/**
* By default, new.target use is not allowed outside of a function or class.
* Set this to true to accept such code.
*/
allowNewTargetOutsideFunction?: boolean;
/**
* By default, super calls are not allowed outside of a method.
* Set this to true to accept such code.
*/
allowSuperOutsideMethod?: boolean;
/**
* By default, exported identifiers must refer to a declared variable.
* Set this to true to allow export statements to reference undeclared variables.
*/
allowUndeclaredExports?: boolean;
/**
* By default, yield use is not allowed outside of a generator function.
* Set this to true to accept such code.
*/
allowYieldOutsideFunction?: boolean;
/**
* By default, Babel parser JavaScript code according to Annex B syntax.
* Set this to `false` to disable such behavior.
*/
annexB?: boolean;
/**
* By default, Babel attaches comments to adjacent AST nodes.
* When this option is set to false, comments are not attached.
* It can provide up to 30% performance improvement when the input code has many comments.
* @babel/eslint-parser will set it for you.
* It is not recommended to use attachComment: false with Babel transform,
* as doing so removes all the comments in output code, and renders annotations such as
* /* istanbul ignore next *\/ nonfunctional.
*/
attachComment?: boolean;
/**
* By default, Babel always throws an error when it finds some invalid code.
* When this option is set to true, it will store the parsing error and
* try to continue parsing the invalid input file.
*/
errorRecovery?: boolean;
/**
* Indicate the mode the code should be parsed in.
* Can be one of "script", "commonjs", "module", or "unambiguous". Defaults to "script".
* "unambiguous" will make @babel/parser attempt to guess, based on the presence
* of ES6 import or export statements.
* Files with ES6 imports and exports are considered "module" and are otherwise "script".
*
* Use "commonjs" to parse code that is intended to be run in a CommonJS environment such as Node.js.
*/
sourceType?: SourceType;
/**
* Correlate output AST nodes with their source filename.
* Useful when generating code and source maps from the ASTs of multiple input files.
*/
sourceFilename?: string;
/**
* By default, all source indexes start from 0.
* You can provide a start index to alternatively start with.
* Useful for integration with other source tools.
*/
startIndex?: number;
/**
* By default, the first line of code parsed is treated as line 1.
* You can provide a line number to alternatively start with.
* Useful for integration with other source tools.
*/
startLine?: number;
/**
* By default, the parsed code is treated as if it starts from line 1, column 0.
* You can provide a column number to alternatively start with.
* Useful for integration with other source tools.
*/
startColumn?: number;
/**
* Array containing the plugins that you want to enable.
*/
plugins?: Plugin[];
/**
* Should the parser work in strict mode.
* Defaults to true if sourceType === 'module'. Otherwise, false.
*/
strictMode?: boolean;
/**
* Adds a ranges property to each node: [node.start, node.end]
*/
ranges?: boolean;
/**
* Adds all parsed tokens to a tokens property on the File node.
*/
tokens?: boolean;
/**
* By default, the parser adds information about parentheses by setting
* `extra.parenthesized` to `true` as needed.
* When this option is `true` the parser creates `ParenthesizedExpression`
* AST nodes instead of using the `extra` property.
*/
createParenthesizedExpressions?: boolean;
/**
* By default, the parser parses import expressions as an `ImportExpression` node.
* Set this to false to parse it as `CallExpression(Import, [Identifier(foo)])`.
*/
createImportExpressions?: boolean;
}
type ParserOptions = Partial<Options>;
type ParseError = ParseError$1<object>;
type ParseResult<Result extends File | Expression = File> = Result & {
comments: File["comments"];
errors: null | ParseError[];
tokens?: File["tokens"];
comments: File["comments"];
errors: ParseError[];
tokens?: File["tokens"];
};
/**
* Parse the provided code as an entire ECMAScript program.
*/
declare function parse(input: string, options?: ParserOptions): ParseResult<File>;
declare function parseExpression(input: string, options?: ParserOptions): ParseResult<Expression>;
declare function parse(
input: string,
options?: ParserOptions
): ParseResult<File>;
declare function parseExpression(
input: string,
options?: ParserOptions
): ParseResult<Expression>;
declare const tokTypes: {
// todo(flow->ts) real token type
[name: string]: any;
};
export { type FlowPluginOptions, type ParseError, type ParseResult, type ParserOptions, type PluginConfig as ParserPlugin, type PipelineOperatorPluginOptions, type TypeScriptPluginOptions, parse, parseExpression, tokTypes };
export {
type FlowPluginOptions,
type ParseError,
type ParseResult,
type ParserOptions,
type PluginConfig as ParserPlugin,
type PipelineOperatorPluginOptions,
type TypeScriptPluginOptions,
parse,
parseExpression,
tokTypes,
};
+1
View File
@@ -38,6 +38,7 @@ const dependencyAliases = new Map([
]);
const packagesHaveScripts = new Set([
"@babel/parser",
"@babel/types",
"@babel/traverse",
"@babel/plugin-transform-runtime",
+8 -3
View File
@@ -22,7 +22,12 @@
"stripInternal": true
},
"exclude": ["./packages/babel-helpers/src/helpers/**/*"],
"references": [{
"path": "./packages/babel-helpers/src/helpers/**/tsconfig.json"
}]
"references": [
{
"path": "./packages/babel-helpers/src/helpers/**/tsconfig.json"
},
{
"path": "./tsconfig.tstyche.json"
}
]
}
+13
View File
@@ -0,0 +1,13 @@
{
"extends": [
"./tsconfig.base.json",
"./tsconfig.paths.json"
],
"compilerOptions": {
"skipLibCheck": false,
"strict": true
},
"include": [
"packages/*/test/*.tst.ts"
]
}