convert @babel/generator to TypeScript (#12487)

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
Bogdan Savluk 2021-01-27 19:21:07 +01:00 committed by GitHub
parent 45fdde0ce2
commit 9ac36b136a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 982 additions and 513 deletions

View File

@ -172,3 +172,8 @@ declare module "@babel/helper-split-export-declaration" {
declare module "@babel/traverse" {
declare module.exports: any;
}
declare module "@babel/generator" {
declare module.exports: any;
}

View File

@ -25,6 +25,9 @@
},
"devDependencies": {
"@babel/helper-fixtures": "workspace:*",
"@babel/parser": "workspace:*"
"@babel/parser": "workspace:*",
"@types/jsesc": "^2.5.0",
"@types/lodash": "^4.14.150",
"@types/source-map": "^0.5.0"
}
}

View File

@ -1,4 +1,5 @@
import type SourceMap from "./source-map";
import type * as t from "@babel/types";
const SPACES_RE = /^[ \t]+$/;
@ -10,32 +11,41 @@ const SPACES_RE = /^[ \t]+$/;
*/
export default class Buffer {
constructor(map: ?SourceMap) {
constructor(map?: SourceMap | null) {
this._map = map;
}
_map: SourceMap = null;
_buf: Array = [];
_buf: Array<any> = [];
_last: string = "";
_queue: Array = [];
_queue: Array<
[
str: string,
line: number,
column: number,
identifierName: string | null,
filename: string | null | undefined,
force: boolean | undefined,
]
> = [];
_position: Object = {
_position: any = {
line: 1,
column: 0,
};
_sourcePosition: Object = {
_sourcePosition: any = {
identifierName: null,
line: null,
column: null,
filename: null,
};
_disallowedPop: Object | null = null;
_disallowedPop: any | null = null;
/**
* Get the final string output from the buffer, along with the sourcemap if one exists.
*/
get(): Object {
get(): any {
this._flush();
const map = this._map;
@ -104,16 +114,25 @@ export default class Buffer {
}
_flush(): void {
let item;
while ((item = this._queue.pop())) this._append(...item);
let item: [
string,
number,
number,
string | null | undefined,
string | null | undefined,
boolean | undefined,
];
while ((item = this._queue.pop())) {
this._append(...item);
}
}
_append(
str: string,
line: number,
column: number,
identifierName: ?string,
filename: ?string,
identifierName?: string | null,
filename?: string | null,
force?: boolean,
): void {
this._buf.push(str);
@ -151,8 +170,8 @@ export default class Buffer {
_mark(
line: number,
column: number,
identifierName: ?string,
filename: ?string,
identifierName?: string | null,
filename?: string | null,
force?: boolean,
): void {
this._map?.mark(
@ -230,7 +249,7 @@ export default class Buffer {
* With this line, there will be one mapping range over "mod" and another
* over "();", where previously it would have been a single mapping.
*/
exactSource(loc: Object, cb: () => void) {
exactSource(loc: any, cb: () => void) {
// In cases where parent expressions start at the same locations as the
// identifier itself, the current active location could already be the
// start of this range. We use 'force' here to explicitly start a new
@ -255,7 +274,7 @@ export default class Buffer {
* will be given this position in the sourcemap.
*/
source(prop: string, loc: Location, force?: boolean): void {
source(prop: string, loc: t.SourceLocation, force?: boolean): void {
if (prop && !loc) return;
// Since this is called extremely often, we re-use the same _sourcePosition
@ -267,7 +286,7 @@ export default class Buffer {
* Call a callback with a specific source location and restore on completion.
*/
withSource(prop: string, loc: Location, cb: () => void): void {
withSource(prop: string, loc: t.SourceLocation, cb: () => void): void {
if (!this._map) return cb();
// Use the call stack to manage a stack of "source location" data because
@ -309,18 +328,13 @@ export default class Buffer {
* sourcemap output, so that certain printers can be sure that the
* "end" location that they set is actually treated as the end position.
*/
_disallowPop(prop: string, loc: Location) {
_disallowPop(prop: string, loc: t.SourceLocation) {
if (prop && !loc) return;
this._disallowedPop = this._normalizePosition(prop, loc);
}
_normalizePosition(
prop: string,
loc: Object,
targetObj: Object,
force?: boolean,
) {
_normalizePosition(prop: string, loc: any, targetObj?: any, force?: boolean) {
const pos = loc ? loc[prop] : null;
if (targetObj === undefined) {

View File

@ -1,4 +1,7 @@
export function File(node: Object) {
import type Printer from "../printer";
import * as t from "@babel/types";
export function File(this: Printer, node: t.File) {
if (node.program) {
// Print this here to ensure that Program node 'leadingComments' still
// get printed after the hashbang.
@ -8,7 +11,7 @@ export function File(node: Object) {
this.print(node.program, node);
}
export function Program(node: Object) {
export function Program(this: Printer, node: t.Program) {
this.printInnerComments(node, false);
this.printSequence(node.directives, node);
@ -17,7 +20,7 @@ export function Program(node: Object) {
this.printSequence(node.body, node);
}
export function BlockStatement(node: Object) {
export function BlockStatement(this: Printer, node: t.BlockStatement) {
this.token("{");
this.printInnerComments(node);
@ -43,9 +46,9 @@ export function BlockStatement(node: Object) {
}
}
export function Noop() {}
export function Noop(this: Printer) {}
export function Directive(node: Object) {
export function Directive(this: Printer, node: t.Directive) {
this.print(node.value, node);
this.semicolon();
}
@ -54,7 +57,7 @@ export function Directive(node: Object) {
const unescapedSingleQuoteRE = /(?:^|[^\\])(?:\\\\)*'/;
const unescapedDoubleQuoteRE = /(?:^|[^\\])(?:\\\\)*"/;
export function DirectiveLiteral(node: Object) {
export function DirectiveLiteral(this: Printer, node: t.DirectiveLiteral) {
const raw = this.getPossibleRaw(node);
if (raw != null) {
this.token(raw);
@ -79,11 +82,14 @@ export function DirectiveLiteral(node: Object) {
}
}
export function InterpreterDirective(node: Object) {
export function InterpreterDirective(
this: Printer,
node: t.InterpreterDirective,
) {
this.token(`#!${node.value}\n`);
}
export function Placeholder(node: Object) {
export function Placeholder(this: Printer, node: t.Placeholder) {
this.token("%%");
this.print(node.name);
this.token("%%");

View File

@ -1,6 +1,11 @@
import type Printer from "../printer";
import * as t from "@babel/types";
export function ClassDeclaration(node: Object, parent: Object) {
export function ClassDeclaration(
this: Printer,
node: t.ClassDeclaration,
parent: any,
) {
if (
!this.format.decoratorsBeforeExport ||
(!t.isExportDefaultDeclaration(parent) &&
@ -51,7 +56,7 @@ export function ClassDeclaration(node: Object, parent: Object) {
export { ClassDeclaration as ClassExpression };
export function ClassBody(node: Object) {
export function ClassBody(this: Printer, node: t.ClassBody) {
this.token("{");
this.printInnerComments(node);
if (node.body.length === 0) {
@ -69,7 +74,7 @@ export function ClassBody(node: Object) {
}
}
export function ClassProperty(node: Object) {
export function ClassProperty(this: Printer, node: t.ClassProperty) {
this.printJoin(node.decorators, node);
// catch up to property key, avoid line break
@ -105,7 +110,10 @@ export function ClassProperty(node: Object) {
this.semicolon();
}
export function ClassPrivateProperty(node: Object) {
export function ClassPrivateProperty(
this: Printer,
node: t.ClassPrivateProperty,
) {
this.printJoin(node.decorators, node);
if (node.static) {
this.word("static");
@ -122,19 +130,19 @@ export function ClassPrivateProperty(node: Object) {
this.semicolon();
}
export function ClassMethod(node: Object) {
export function ClassMethod(this: Printer, node: t.ClassMethod) {
this._classMethodHead(node);
this.space();
this.print(node.body, node);
}
export function ClassPrivateMethod(node: Object) {
export function ClassPrivateMethod(this: Printer, node: t.ClassPrivateMethod) {
this._classMethodHead(node);
this.space();
this.print(node.body, node);
}
export function _classMethodHead(node) {
export function _classMethodHead(this: Printer, node) {
this.printJoin(node.decorators, node);
// catch up to method key, avoid line break
// between member modifiers/method heads and the method key.
@ -143,7 +151,7 @@ export function _classMethodHead(node) {
this._methodHead(node);
}
export function StaticBlock(node) {
export function StaticBlock(node: t.StaticBlock) {
this.word("static");
this.space();
this.token("{");

View File

@ -1,7 +1,8 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import * as n from "../node";
export function UnaryExpression(node: Object) {
export function UnaryExpression(this: Printer, node: t.UnaryExpression) {
if (
node.operator === "void" ||
node.operator === "delete" ||
@ -18,19 +19,22 @@ export function UnaryExpression(node: Object) {
this.print(node.argument, node);
}
export function DoExpression(node: Object) {
export function DoExpression(this: Printer, node: t.DoExpression) {
this.word("do");
this.space();
this.print(node.body, node);
}
export function ParenthesizedExpression(node: Object) {
export function ParenthesizedExpression(
this: Printer,
node: t.ParenthesizedExpression,
) {
this.token("(");
this.print(node.expression, node);
this.token(")");
}
export function UpdateExpression(node: Object) {
export function UpdateExpression(this: Printer, node: t.UpdateExpression) {
if (node.prefix) {
this.token(node.operator);
this.print(node.argument, node);
@ -42,7 +46,10 @@ export function UpdateExpression(node: Object) {
}
}
export function ConditionalExpression(node: Object) {
export function ConditionalExpression(
this: Printer,
node: t.ConditionalExpression,
) {
this.print(node.test, node);
this.space();
this.token("?");
@ -54,7 +61,11 @@ export function ConditionalExpression(node: Object) {
this.print(node.alternate, node);
}
export function NewExpression(node: Object, parent: Object) {
export function NewExpression(
this: Printer,
node: t.NewExpression,
parent: any,
) {
this.word("new");
this.space();
this.print(node.callee, node);
@ -80,25 +91,28 @@ export function NewExpression(node: Object, parent: Object) {
this.token(")");
}
export function SequenceExpression(node: Object) {
export function SequenceExpression(this: Printer, node: t.SequenceExpression) {
this.printList(node.expressions, node);
}
export function ThisExpression() {
export function ThisExpression(this: Printer) {
this.word("this");
}
export function Super() {
export function Super(this: Printer) {
this.word("super");
}
export function Decorator(node: Object) {
export function Decorator(this: Printer, node: t.Decorator) {
this.token("@");
this.print(node.expression, node);
this.newline();
}
export function OptionalMemberExpression(node: Object) {
export function OptionalMemberExpression(
this: Printer,
node: t.OptionalMemberExpression,
) {
this.print(node.object, node);
if (!node.computed && t.isMemberExpression(node.property)) {
@ -106,6 +120,7 @@ export function OptionalMemberExpression(node: Object) {
}
let computed = node.computed;
// @ts-expect-error todo(flow->ts) maybe instead of typeof check specific literal types?
if (t.isLiteral(node.property) && typeof node.property.value === "number") {
computed = true;
}
@ -125,7 +140,10 @@ export function OptionalMemberExpression(node: Object) {
}
}
export function OptionalCallExpression(node: Object) {
export function OptionalCallExpression(
this: Printer,
node: t.OptionalCallExpression,
) {
this.print(node.callee, node);
this.print(node.typeArguments, node); // Flow
@ -139,7 +157,7 @@ export function OptionalCallExpression(node: Object) {
this.token(")");
}
export function CallExpression(node: Object) {
export function CallExpression(this: Printer, node: t.CallExpression) {
this.print(node.callee, node);
this.print(node.typeArguments, node); // Flow
@ -149,12 +167,12 @@ export function CallExpression(node: Object) {
this.token(")");
}
export function Import() {
export function Import(this: Printer) {
this.word("import");
}
function buildYieldAwait(keyword: string) {
return function (node: Object) {
return function (node: any) {
this.word(keyword);
if (node.delegate) {
@ -173,18 +191,23 @@ function buildYieldAwait(keyword: string) {
export const YieldExpression = buildYieldAwait("yield");
export const AwaitExpression = buildYieldAwait("await");
export function EmptyStatement() {
export function EmptyStatement(this: Printer) {
this.semicolon(true /* force */);
}
export function ExpressionStatement(node: Object) {
export function ExpressionStatement(
this: Printer,
node: t.ExpressionStatement,
) {
this.print(node.expression, node);
this.semicolon();
}
export function AssignmentPattern(node: Object) {
export function AssignmentPattern(this: Printer, node: t.AssignmentPattern) {
this.print(node.left, node);
// @ts-expect-error todo(flow->ts) property present on some of the types in union but not all
if (node.left.optional) this.token("?");
// @ts-expect-error todo(flow->ts) property present on some of the types in union but not all
this.print(node.left.typeAnnotation, node);
this.space();
this.token("=");
@ -192,7 +215,11 @@ export function AssignmentPattern(node: Object) {
this.print(node.right, node);
}
export function AssignmentExpression(node: Object, parent: Object) {
export function AssignmentExpression(
this: Printer,
node: t.AssignmentExpression,
parent: any,
) {
// Somewhere inside a for statement `init` node but doesn't usually
// needs a paren except for `in` expressions: `for (a in b ? a : b;;)`
const parens =
@ -221,7 +248,7 @@ export function AssignmentExpression(node: Object, parent: Object) {
}
}
export function BindExpression(node: Object) {
export function BindExpression(this: Printer, node: t.BindExpression) {
this.print(node.object, node);
this.token("::");
this.print(node.callee, node);
@ -232,7 +259,7 @@ export {
AssignmentExpression as LogicalExpression,
};
export function MemberExpression(node: Object) {
export function MemberExpression(this: Printer, node: t.MemberExpression) {
this.print(node.object, node);
if (!node.computed && t.isMemberExpression(node.property)) {
@ -240,6 +267,7 @@ export function MemberExpression(node: Object) {
}
let computed = node.computed;
// @ts-expect-error todo(flow->ts) maybe use specific literal types
if (t.isLiteral(node.property) && typeof node.property.value === "number") {
computed = true;
}
@ -254,18 +282,21 @@ export function MemberExpression(node: Object) {
}
}
export function MetaProperty(node: Object) {
export function MetaProperty(this: Printer, node: t.MetaProperty) {
this.print(node.meta, node);
this.token(".");
this.print(node.property, node);
}
export function PrivateName(node: Object) {
export function PrivateName(this: Printer, node: t.PrivateName) {
this.token("#");
this.print(node.id, node);
}
export function V8IntrinsicIdentifier(node: Object) {
export function V8IntrinsicIdentifier(
this: Printer,
node: t.V8IntrinsicIdentifier,
) {
this.token("%");
this.word(node.name);
}

View File

@ -1,29 +1,40 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import { ExportAllDeclaration } from "./modules";
export function AnyTypeAnnotation() {
export function AnyTypeAnnotation(this: Printer) {
this.word("any");
}
export function ArrayTypeAnnotation(node: Object) {
export function ArrayTypeAnnotation(
this: Printer,
node: t.ArrayTypeAnnotation,
) {
this.print(node.elementType, node);
this.token("[");
this.token("]");
}
export function BooleanTypeAnnotation() {
export function BooleanTypeAnnotation(this: Printer) {
this.word("boolean");
}
export function BooleanLiteralTypeAnnotation(node: Object) {
export function BooleanLiteralTypeAnnotation(
this: Printer,
node: t.BooleanLiteralTypeAnnotation,
) {
this.word(node.value ? "true" : "false");
}
export function NullLiteralTypeAnnotation() {
export function NullLiteralTypeAnnotation(this: Printer) {
this.word("null");
}
export function DeclareClass(node: Object, parent: Object) {
export function DeclareClass(
this: Printer,
node: t.DeclareClass,
parent: t.Node,
) {
if (!t.isDeclareExportDeclaration(parent)) {
this.word("declare");
this.space();
@ -33,7 +44,11 @@ export function DeclareClass(node: Object, parent: Object) {
this._interfaceish(node);
}
export function DeclareFunction(node: Object, parent: Object) {
export function DeclareFunction(
this: Printer,
node: t.DeclareFunction,
parent: any,
) {
if (!t.isDeclareExportDeclaration(parent)) {
this.word("declare");
this.space();
@ -41,6 +56,7 @@ export function DeclareFunction(node: Object, parent: Object) {
this.word("function");
this.space();
this.print(node.id, node);
// @ts-expect-error todo(flow->ts) typeAnnotation does not exist on Noop
this.print(node.id.typeAnnotation.typeAnnotation, node);
if (node.predicate) {
@ -56,7 +72,7 @@ export function InferredPredicate(/*node: Object*/) {
this.word("checks");
}
export function DeclaredPredicate(node: Object) {
export function DeclaredPredicate(this: Printer, node: t.DeclaredPredicate) {
this.token("%");
this.word("checks");
this.token("(");
@ -64,13 +80,13 @@ export function DeclaredPredicate(node: Object) {
this.token(")");
}
export function DeclareInterface(node: Object) {
export function DeclareInterface(this: Printer, node: t.DeclareInterface) {
this.word("declare");
this.space();
this.InterfaceDeclaration(node);
}
export function DeclareModule(node: Object) {
export function DeclareModule(this: Printer, node: t.DeclareModule) {
this.word("declare");
this.space();
this.word("module");
@ -80,7 +96,10 @@ export function DeclareModule(node: Object) {
this.print(node.body, node);
}
export function DeclareModuleExports(node: Object) {
export function DeclareModuleExports(
this: Printer,
node: t.DeclareModuleExports,
) {
this.word("declare");
this.space();
this.word("module");
@ -89,13 +108,17 @@ export function DeclareModuleExports(node: Object) {
this.print(node.typeAnnotation, node);
}
export function DeclareTypeAlias(node: Object) {
export function DeclareTypeAlias(this: Printer, node: t.DeclareTypeAlias) {
this.word("declare");
this.space();
this.TypeAlias(node);
}
export function DeclareOpaqueType(node: Object, parent: Object) {
export function DeclareOpaqueType(
this: Printer,
node: t.DeclareOpaqueType,
parent: any,
) {
if (!t.isDeclareExportDeclaration(parent)) {
this.word("declare");
this.space();
@ -103,7 +126,11 @@ export function DeclareOpaqueType(node: Object, parent: Object) {
this.OpaqueType(node);
}
export function DeclareVariable(node: Object, parent: Object) {
export function DeclareVariable(
this: Printer,
node: t.DeclareVariable,
parent: any,
) {
if (!t.isDeclareExportDeclaration(parent)) {
this.word("declare");
this.space();
@ -115,7 +142,10 @@ export function DeclareVariable(node: Object, parent: Object) {
this.semicolon();
}
export function DeclareExportDeclaration(node: Object) {
export function DeclareExportDeclaration(
this: Printer,
node: t.DeclareExportDeclaration,
) {
this.word("declare");
this.space();
this.word("export");
@ -134,7 +164,7 @@ export function DeclareExportAllDeclaration(/*node: Object*/) {
ExportAllDeclaration.apply(this, arguments);
}
export function EnumDeclaration(node: Object) {
export function EnumDeclaration(this: Printer, node: t.EnumDeclaration) {
const { id, body } = node;
this.word("enum");
this.space();
@ -143,7 +173,7 @@ export function EnumDeclaration(node: Object) {
}
function enumExplicitType(
context: Object,
context: any,
name: string,
hasExplicitType: boolean,
) {
@ -156,7 +186,7 @@ function enumExplicitType(
context.space();
}
function enumBody(context: Object, node: Object) {
function enumBody(context: any, node: any) {
const { members } = node;
context.token("{");
context.indent();
@ -169,36 +199,39 @@ function enumBody(context: Object, node: Object) {
context.token("}");
}
export function EnumBooleanBody(node: Object) {
export function EnumBooleanBody(this: Printer, node: t.EnumBooleanBody) {
const { explicitType } = node;
enumExplicitType(this, "boolean", explicitType);
enumBody(this, node);
}
export function EnumNumberBody(node: Object) {
export function EnumNumberBody(this: Printer, node: t.EnumNumberBody) {
const { explicitType } = node;
enumExplicitType(this, "number", explicitType);
enumBody(this, node);
}
export function EnumStringBody(node: Object) {
export function EnumStringBody(this: Printer, node: t.EnumStringBody) {
const { explicitType } = node;
enumExplicitType(this, "string", explicitType);
enumBody(this, node);
}
export function EnumSymbolBody(node: Object) {
export function EnumSymbolBody(this: Printer, node: t.EnumSymbolBody) {
enumExplicitType(this, "symbol", true);
enumBody(this, node);
}
export function EnumDefaultedMember(node: Object) {
export function EnumDefaultedMember(
this: Printer,
node: t.EnumDefaultedMember,
) {
const { id } = node;
this.print(id, node);
this.token(",");
}
function enumInitializedMember(context: Object, node: Object) {
function enumInitializedMember(context: any, node: any) {
const { id, init } = node;
context.print(id, node);
context.space();
@ -208,19 +241,19 @@ function enumInitializedMember(context: Object, node: Object) {
context.token(",");
}
export function EnumBooleanMember(node: Object) {
export function EnumBooleanMember(this: Printer, node: t.EnumBooleanMember) {
enumInitializedMember(this, node);
}
export function EnumNumberMember(node: Object) {
export function EnumNumberMember(this: Printer, node: t.EnumNumberMember) {
enumInitializedMember(this, node);
}
export function EnumStringMember(node: Object) {
export function EnumStringMember(this: Printer, node: t.EnumStringMember) {
enumInitializedMember(this, node);
}
function FlowExportDeclaration(node: Object) {
function FlowExportDeclaration(node: any) {
if (node.declaration) {
const declar = node.declaration;
this.print(declar, node);
@ -245,11 +278,15 @@ function FlowExportDeclaration(node: Object) {
}
}
export function ExistsTypeAnnotation() {
export function ExistsTypeAnnotation(this: Printer) {
this.token("*");
}
export function FunctionTypeAnnotation(node: Object, parent: Object) {
export function FunctionTypeAnnotation(
this: Printer,
node: t.FunctionTypeAnnotation,
parent: any,
) {
this.print(node.typeParameters, node);
this.token("(");
this.printList(node.params, node);
@ -281,7 +318,7 @@ export function FunctionTypeAnnotation(node: Object, parent: Object) {
this.print(node.returnType, node);
}
export function FunctionTypeParam(node: Object) {
export function FunctionTypeParam(this: Printer, node: t.FunctionTypeParam) {
this.print(node.name, node);
if (node.optional) this.token("?");
if (node.name) {
@ -291,7 +328,7 @@ export function FunctionTypeParam(node: Object) {
this.print(node.typeAnnotation, node);
}
export function InterfaceExtends(node: Object) {
export function InterfaceExtends(this: Printer, node: t.InterfaceExtends) {
this.print(node.id, node);
this.print(node.typeParameters, node);
}
@ -301,7 +338,10 @@ export {
InterfaceExtends as GenericTypeAnnotation,
};
export function _interfaceish(node: Object) {
export function _interfaceish(
this: Printer,
node: t.InterfaceDeclaration | t.DeclareInterface | t.DeclareClass,
) {
this.print(node.id, node);
this.print(node.typeParameters, node);
if (node.extends.length) {
@ -326,7 +366,7 @@ export function _interfaceish(node: Object) {
this.print(node.body, node);
}
export function _variance(node) {
export function _variance(this: Printer, node) {
if (node.variance) {
if (node.variance.kind === "plus") {
this.token("+");
@ -336,7 +376,10 @@ export function _variance(node) {
}
}
export function InterfaceDeclaration(node: Object) {
export function InterfaceDeclaration(
this: Printer,
node: t.InterfaceDeclaration | t.DeclareInterface,
) {
this.word("interface");
this.space();
this._interfaceish(node);
@ -348,7 +391,10 @@ function andSeparator() {
this.space();
}
export function InterfaceTypeAnnotation(node: Object) {
export function InterfaceTypeAnnotation(
this: Printer,
node: t.InterfaceTypeAnnotation,
) {
this.word("interface");
if (node.extends && node.extends.length) {
this.space();
@ -360,19 +406,25 @@ export function InterfaceTypeAnnotation(node: Object) {
this.print(node.body, node);
}
export function IntersectionTypeAnnotation(node: Object) {
export function IntersectionTypeAnnotation(
this: Printer,
node: t.IntersectionTypeAnnotation,
) {
this.printJoin(node.types, node, { separator: andSeparator });
}
export function MixedTypeAnnotation() {
export function MixedTypeAnnotation(this: Printer) {
this.word("mixed");
}
export function EmptyTypeAnnotation() {
export function EmptyTypeAnnotation(this: Printer) {
this.word("empty");
}
export function NullableTypeAnnotation(node: Object) {
export function NullableTypeAnnotation(
this: Printer,
node: t.NullableTypeAnnotation,
) {
this.token("?");
this.print(node.typeAnnotation, node);
}
@ -382,31 +434,40 @@ export {
StringLiteral as StringLiteralTypeAnnotation,
} from "./types";
export function NumberTypeAnnotation() {
export function NumberTypeAnnotation(this: Printer) {
this.word("number");
}
export function StringTypeAnnotation() {
export function StringTypeAnnotation(this: Printer) {
this.word("string");
}
export function ThisTypeAnnotation() {
export function ThisTypeAnnotation(this: Printer) {
this.word("this");
}
export function TupleTypeAnnotation(node: Object) {
export function TupleTypeAnnotation(
this: Printer,
node: t.TupleTypeAnnotation,
) {
this.token("[");
this.printList(node.types, node);
this.token("]");
}
export function TypeofTypeAnnotation(node: Object) {
export function TypeofTypeAnnotation(
this: Printer,
node: t.TypeofTypeAnnotation,
) {
this.word("typeof");
this.space();
this.print(node.argument, node);
}
export function TypeAlias(node: Object) {
export function TypeAlias(
this: Printer,
node: t.TypeAlias | t.DeclareTypeAlias,
) {
this.word("type");
this.space();
this.print(node.id, node);
@ -418,14 +479,18 @@ export function TypeAlias(node: Object) {
this.semicolon();
}
export function TypeAnnotation(node) {
export function TypeAnnotation(this: Printer, node: t.TypeAnnotation) {
this.token(":");
this.space();
// @ts-expect-error todo(flow->ts) can this be removed? `.optional` looks to be not existing property
if (node.optional) this.token("?");
this.print(node.typeAnnotation, node);
}
export function TypeParameterInstantiation(node): void {
export function TypeParameterInstantiation(
this: Printer,
node: t.TypeParameterInstantiation,
): void {
this.token("<");
this.printList(node.params, node, {});
this.token(">");
@ -433,7 +498,7 @@ export function TypeParameterInstantiation(node): void {
export { TypeParameterInstantiation as TypeParameterDeclaration };
export function TypeParameter(node) {
export function TypeParameter(this: Printer, node: t.TypeParameter) {
this._variance(node);
this.word(node.name);
@ -450,7 +515,10 @@ export function TypeParameter(node) {
}
}
export function OpaqueType(node: Object) {
export function OpaqueType(
this: Printer,
node: t.OpaqueType | t.DeclareOpaqueType,
) {
this.word("opaque");
this.space();
this.word("type");
@ -462,16 +530,22 @@ export function OpaqueType(node: Object) {
this.space();
this.print(node.supertype, node);
}
// @ts-expect-error todo(flow->ts) `.impltype` does not exist on t.DeclareOpaqueType
if (node.impltype) {
this.space();
this.token("=");
this.space();
// @ts-expect-error todo(flow->ts) `.impltype` does not exist on t.DeclareOpaqueType
this.print(node.impltype, node);
}
this.semicolon();
}
export function ObjectTypeAnnotation(node: Object) {
export function ObjectTypeAnnotation(
this: Printer,
node: t.ObjectTypeAnnotation,
) {
if (node.exact) {
this.token("{|");
} else {
@ -479,11 +553,12 @@ export function ObjectTypeAnnotation(node: Object) {
}
// TODO: remove the array fallbacks and instead enforce the types to require an array
const props = node.properties.concat(
node.callProperties || [],
node.indexers || [],
node.internalSlots || [],
);
const props = [
...node.properties,
...(node.callProperties || []),
...(node.indexers || []),
...(node.internalSlots || []),
];
if (props.length) {
this.space();
@ -521,7 +596,10 @@ export function ObjectTypeAnnotation(node: Object) {
}
}
export function ObjectTypeInternalSlot(node: Object) {
export function ObjectTypeInternalSlot(
this: Printer,
node: t.ObjectTypeInternalSlot,
) {
if (node.static) {
this.word("static");
this.space();
@ -539,7 +617,10 @@ export function ObjectTypeInternalSlot(node: Object) {
this.print(node.value, node);
}
export function ObjectTypeCallProperty(node: Object) {
export function ObjectTypeCallProperty(
this: Printer,
node: t.ObjectTypeCallProperty,
) {
if (node.static) {
this.word("static");
this.space();
@ -547,7 +628,7 @@ export function ObjectTypeCallProperty(node: Object) {
this.print(node.value, node);
}
export function ObjectTypeIndexer(node: Object) {
export function ObjectTypeIndexer(this: Printer, node: t.ObjectTypeIndexer) {
if (node.static) {
this.word("static");
this.space();
@ -566,7 +647,7 @@ export function ObjectTypeIndexer(node: Object) {
this.print(node.value, node);
}
export function ObjectTypeProperty(node: Object) {
export function ObjectTypeProperty(this: Printer, node: t.ObjectTypeProperty) {
if (node.proto) {
this.word("proto");
this.space();
@ -589,18 +670,24 @@ export function ObjectTypeProperty(node: Object) {
this.print(node.value, node);
}
export function ObjectTypeSpreadProperty(node: Object) {
export function ObjectTypeSpreadProperty(
this: Printer,
node: t.ObjectTypeSpreadProperty,
) {
this.token("...");
this.print(node.argument, node);
}
export function QualifiedTypeIdentifier(node: Object) {
export function QualifiedTypeIdentifier(
this: Printer,
node: t.QualifiedTypeIdentifier,
) {
this.print(node.qualification, node);
this.token(".");
this.print(node.id, node);
}
export function SymbolTypeAnnotation() {
export function SymbolTypeAnnotation(this: Printer) {
this.word("symbol");
}
@ -610,18 +697,21 @@ function orSeparator() {
this.space();
}
export function UnionTypeAnnotation(node: Object) {
export function UnionTypeAnnotation(
this: Printer,
node: t.UnionTypeAnnotation,
) {
this.printJoin(node.types, node, { separator: orSeparator });
}
export function TypeCastExpression(node: Object) {
export function TypeCastExpression(this: Printer, node: t.TypeCastExpression) {
this.token("(");
this.print(node.expression, node);
this.print(node.typeAnnotation, node);
this.token(")");
}
export function Variance(node: Object) {
export function Variance(this: Printer, node: t.Variance) {
if (node.kind === "plus") {
this.token("+");
} else {
@ -629,6 +719,6 @@ export function Variance(node: Object) {
}
}
export function VoidTypeAnnotation() {
export function VoidTypeAnnotation(this: Printer) {
this.word("void");
}

View File

@ -1,4 +1,7 @@
export function JSXAttribute(node: Object) {
import type Printer from "../printer";
import * as t from "@babel/types";
export function JSXAttribute(this: Printer, node: t.JSXAttribute) {
this.print(node.name, node);
if (node.value) {
this.token("=");
@ -6,43 +9,49 @@ export function JSXAttribute(node: Object) {
}
}
export function JSXIdentifier(node: Object) {
export function JSXIdentifier(this: Printer, node: t.JSXIdentifier) {
this.word(node.name);
}
export function JSXNamespacedName(node: Object) {
export function JSXNamespacedName(this: Printer, node: t.JSXNamespacedName) {
this.print(node.namespace, node);
this.token(":");
this.print(node.name, node);
}
export function JSXMemberExpression(node: Object) {
export function JSXMemberExpression(
this: Printer,
node: t.JSXMemberExpression,
) {
this.print(node.object, node);
this.token(".");
this.print(node.property, node);
}
export function JSXSpreadAttribute(node: Object) {
export function JSXSpreadAttribute(this: Printer, node: t.JSXSpreadAttribute) {
this.token("{");
this.token("...");
this.print(node.argument, node);
this.token("}");
}
export function JSXExpressionContainer(node: Object) {
export function JSXExpressionContainer(
this: Printer,
node: t.JSXExpressionContainer,
) {
this.token("{");
this.print(node.expression, node);
this.token("}");
}
export function JSXSpreadChild(node: Object) {
export function JSXSpreadChild(this: Printer, node: t.JSXSpreadChild) {
this.token("{");
this.token("...");
this.print(node.expression, node);
this.token("}");
}
export function JSXText(node: Object) {
export function JSXText(this: Printer, node: t.JSXText) {
const raw = this.getPossibleRaw(node);
if (raw != null) {
@ -52,13 +61,13 @@ export function JSXText(node: Object) {
}
}
export function JSXElement(node: Object) {
export function JSXElement(this: Printer, node: t.JSXElement) {
const open = node.openingElement;
this.print(open, node);
if (open.selfClosing) return;
this.indent();
for (const child of (node.children: Array<Object>)) {
for (const child of node.children as Array<any>) {
this.print(child, node);
}
this.dedent();
@ -70,7 +79,7 @@ function spaceSeparator() {
this.space();
}
export function JSXOpeningElement(node: Object) {
export function JSXOpeningElement(this: Printer, node: t.JSXOpeningElement) {
this.token("<");
this.print(node.name, node);
this.print(node.typeParameters, node); // TS
@ -86,21 +95,21 @@ export function JSXOpeningElement(node: Object) {
}
}
export function JSXClosingElement(node: Object) {
export function JSXClosingElement(this: Printer, node: t.JSXClosingElement) {
this.token("</");
this.print(node.name, node);
this.token(">");
}
export function JSXEmptyExpression(node: Object) {
export function JSXEmptyExpression(this: Printer, node: t.JSXEmptyExpression) {
this.printInnerComments(node);
}
export function JSXFragment(node: Object) {
export function JSXFragment(this: Printer, node: t.JSXFragment) {
this.print(node.openingFragment, node);
this.indent();
for (const child of (node.children: Array<Object>)) {
for (const child of node.children as Array<any>) {
this.print(child, node);
}
this.dedent();
@ -108,12 +117,12 @@ export function JSXFragment(node: Object) {
this.print(node.closingFragment, node);
}
export function JSXOpeningFragment() {
export function JSXOpeningFragment(this: Printer) {
this.token("<");
this.token(">");
}
export function JSXClosingFragment() {
export function JSXClosingFragment(this: Printer) {
this.token("</");
this.token(">");
}

View File

@ -1,6 +1,7 @@
import type Printer from "../printer";
import * as t from "@babel/types";
export function _params(node: Object) {
export function _params(this: Printer, node: any) {
this.print(node.typeParameters, node);
this.token("(");
this._parameters(node.params, node);
@ -9,7 +10,7 @@ export function _params(node: Object) {
this.print(node.returnType, node);
}
export function _parameters(parameters, parent) {
export function _parameters(this: Printer, parameters, parent) {
for (let i = 0; i < parameters.length; i++) {
this._param(parameters[i], parent);
@ -20,14 +21,14 @@ export function _parameters(parameters, parent) {
}
}
export function _param(parameter, parent) {
export function _param(this: Printer, parameter, parent?) {
this.printJoin(parameter.decorators, parameter);
this.print(parameter, parent);
if (parameter.optional) this.token("?"); // TS / flow
this.print(parameter.typeAnnotation, parameter); // TS / flow
}
export function _methodHead(node: Object) {
export function _methodHead(this: Printer, node: any) {
const kind = node.kind;
const key = node.key;
@ -65,7 +66,7 @@ export function _methodHead(node: Object) {
this._params(node);
}
export function _predicate(node: Object) {
export function _predicate(this: Printer, node: any) {
if (node.predicate) {
if (!node.returnType) {
this.token(":");
@ -75,7 +76,7 @@ export function _predicate(node: Object) {
}
}
export function _functionHead(node: Object) {
export function _functionHead(this: Printer, node: any) {
if (node.async) {
this.word("async");
this.space();
@ -92,7 +93,7 @@ export function _functionHead(node: Object) {
this._predicate(node);
}
export function FunctionExpression(node: Object) {
export function FunctionExpression(this: Printer, node: t.FunctionExpression) {
this._functionHead(node);
this.space();
this.print(node.body, node);
@ -100,7 +101,10 @@ export function FunctionExpression(node: Object) {
export { FunctionExpression as FunctionDeclaration };
export function ArrowFunctionExpression(node: Object) {
export function ArrowFunctionExpression(
this: Printer,
node: t.ArrowFunctionExpression,
) {
if (node.async) {
this.word("async");
this.space();

View File

@ -1,12 +1,14 @@
import type Printer from "../printer";
import * as t from "@babel/types";
export function ImportSpecifier(node: Object) {
export function ImportSpecifier(this: Printer, node: t.ImportSpecifier) {
if (node.importKind === "type" || node.importKind === "typeof") {
this.word(node.importKind);
this.space();
}
this.print(node.imported, node);
// @ts-expect-error todo(flow-ts) maybe check node type instead of relying on name to be undefined on t.StringLiteral
if (node.local && node.local.name !== node.imported.name) {
this.space();
this.word("as");
@ -15,16 +17,23 @@ export function ImportSpecifier(node: Object) {
}
}
export function ImportDefaultSpecifier(node: Object) {
export function ImportDefaultSpecifier(
this: Printer,
node: t.ImportDefaultSpecifier,
) {
this.print(node.local, node);
}
export function ExportDefaultSpecifier(node: Object) {
export function ExportDefaultSpecifier(
this: Printer,
node: t.ExportDefaultSpecifier,
) {
this.print(node.exported, node);
}
export function ExportSpecifier(node: Object) {
export function ExportSpecifier(this: Printer, node: t.ExportSpecifier) {
this.print(node.local, node);
// @ts-expect-error todo(flow-ts) maybe check node type instead of relying on name to be undefined on t.StringLiteral
if (node.exported && node.local.name !== node.exported.name) {
this.space();
this.word("as");
@ -33,7 +42,10 @@ export function ExportSpecifier(node: Object) {
}
}
export function ExportNamespaceSpecifier(node: Object) {
export function ExportNamespaceSpecifier(
this: Printer,
node: t.ExportNamespaceSpecifier,
) {
this.token("*");
this.space();
this.word("as");
@ -41,7 +53,10 @@ export function ExportNamespaceSpecifier(node: Object) {
this.print(node.exported, node);
}
export function ExportAllDeclaration(node: Object) {
export function ExportAllDeclaration(
this: Printer,
node: t.ExportAllDeclaration,
) {
this.word("export");
this.space();
if (node.exportKind === "type") {
@ -57,7 +72,10 @@ export function ExportAllDeclaration(node: Object) {
this.semicolon();
}
export function ExportNamedDeclaration(node: Object) {
export function ExportNamedDeclaration(
this: Printer,
node: t.ExportNamedDeclaration,
) {
if (
this.format.decoratorsBeforeExport &&
t.isClassDeclaration(node.declaration)
@ -70,7 +88,10 @@ export function ExportNamedDeclaration(node: Object) {
ExportDeclaration.apply(this, arguments);
}
export function ExportDefaultDeclaration(node: Object) {
export function ExportDefaultDeclaration(
this: Printer,
node: t.ExportDefaultDeclaration,
) {
if (
this.format.decoratorsBeforeExport &&
t.isClassDeclaration(node.declaration)
@ -85,7 +106,7 @@ export function ExportDefaultDeclaration(node: Object) {
ExportDeclaration.apply(this, arguments);
}
function ExportDeclaration(node: Object) {
function ExportDeclaration(node: any) {
if (node.declaration) {
const declar = node.declaration;
this.print(declar, node);
@ -139,7 +160,7 @@ function ExportDeclaration(node: Object) {
}
}
export function ImportDeclaration(node: Object) {
export function ImportDeclaration(this: Printer, node: t.ImportDeclaration) {
this.word("import");
this.space();
@ -185,24 +206,29 @@ export function ImportDeclaration(node: Object) {
this.printAssertions(node);
// todo(Babel 8): remove this if branch
// `module-attributes` support is discontinued, use `import-assertions` instead.
// @ts-expect-error
if (node.attributes?.length) {
this.space();
this.word("with");
this.space();
// @ts-expect-error
this.printList(node.attributes, node);
}
this.semicolon();
}
export function ImportAttribute(node: Object) {
export function ImportAttribute(this: Printer, node: t.ImportAttribute) {
this.print(node.key);
this.token(":");
this.space();
this.print(node.value);
}
export function ImportNamespaceSpecifier(node: Object) {
export function ImportNamespaceSpecifier(
this: Printer,
node: t.ImportNamespaceSpecifier,
) {
this.token("*");
this.space();
this.word("as");

View File

@ -1,6 +1,7 @@
import type Printer from "../printer";
import * as t from "@babel/types";
export function WithStatement(node: Object) {
export function WithStatement(this: Printer, node: t.WithStatement) {
this.word("with");
this.space();
this.token("(");
@ -9,7 +10,7 @@ export function WithStatement(node: Object) {
this.printBlock(node);
}
export function IfStatement(node: Object) {
export function IfStatement(this: Printer, node: t.IfStatement) {
this.word("if");
this.space();
this.token("(");
@ -47,7 +48,7 @@ function getLastStatement(statement) {
return getLastStatement(statement.body);
}
export function ForStatement(node: Object) {
export function ForStatement(this: Printer, node: t.ForStatement) {
this.word("for");
this.space();
this.token("(");
@ -72,7 +73,7 @@ export function ForStatement(node: Object) {
this.printBlock(node);
}
export function WhileStatement(node: Object) {
export function WhileStatement(this: Printer, node: t.WhileStatement) {
this.word("while");
this.space();
this.token("(");
@ -82,7 +83,7 @@ export function WhileStatement(node: Object) {
}
const buildForXStatement = function (op) {
return function (node: Object) {
return function (node: any) {
this.word("for");
this.space();
if (op === "of" && node.await) {
@ -103,7 +104,7 @@ const buildForXStatement = function (op) {
export const ForInStatement = buildForXStatement("in");
export const ForOfStatement = buildForXStatement("of");
export function DoWhileStatement(node: Object) {
export function DoWhileStatement(this: Printer, node: t.DoWhileStatement) {
this.word("do");
this.space();
this.print(node.body, node);
@ -117,7 +118,7 @@ export function DoWhileStatement(node: Object) {
}
function buildLabelStatement(prefix, key = "label") {
return function (node: Object) {
return function (node: any) {
this.word(prefix);
const label = node[key];
@ -138,14 +139,14 @@ export const ReturnStatement = buildLabelStatement("return", "argument");
export const BreakStatement = buildLabelStatement("break");
export const ThrowStatement = buildLabelStatement("throw", "argument");
export function LabeledStatement(node: Object) {
export function LabeledStatement(this: Printer, node: t.LabeledStatement) {
this.print(node.label, node);
this.token(":");
this.space();
this.print(node.body, node);
}
export function TryStatement(node: Object) {
export function TryStatement(this: Printer, node: t.TryStatement) {
this.word("try");
this.space();
this.print(node.block, node);
@ -154,7 +155,9 @@ export function TryStatement(node: Object) {
// Esprima bug puts the catch clause in a `handlers` array.
// see https://code.google.com/p/esprima/issues/detail?id=433
// We run into this from regenerator generated ast.
// @ts-expect-error todo(flow->ts) should ast node type be updated to support this?
if (node.handlers) {
// @ts-expect-error todo(flow->ts) should ast node type be updated to support this?
this.print(node.handlers[0], node);
} else {
this.print(node.handler, node);
@ -168,7 +171,7 @@ export function TryStatement(node: Object) {
}
}
export function CatchClause(node: Object) {
export function CatchClause(this: Printer, node: t.CatchClause) {
this.word("catch");
this.space();
if (node.param) {
@ -181,7 +184,7 @@ export function CatchClause(node: Object) {
this.print(node.body, node);
}
export function SwitchStatement(node: Object) {
export function SwitchStatement(this: Printer, node: t.SwitchStatement) {
this.word("switch");
this.space();
this.token("(");
@ -200,7 +203,7 @@ export function SwitchStatement(node: Object) {
this.token("}");
}
export function SwitchCase(node: Object) {
export function SwitchCase(this: Printer, node: t.SwitchCase) {
if (node.test) {
this.word("case");
this.space();
@ -217,7 +220,7 @@ export function SwitchCase(node: Object) {
}
}
export function DebuggerStatement() {
export function DebuggerStatement(this: Printer) {
this.word("debugger");
this.semicolon();
}
@ -236,7 +239,11 @@ function constDeclarationIndent() {
if (this.endsWith("\n")) for (let i = 0; i < 6; i++) this.space(true);
}
export function VariableDeclaration(node: Object, parent: Object) {
export function VariableDeclaration(
this: Printer,
node: t.VariableDeclaration,
parent: t.Node,
) {
if (node.declare) {
// TS
this.word("declare");
@ -249,7 +256,7 @@ export function VariableDeclaration(node: Object, parent: Object) {
let hasInits = false;
// don't add whitespace to loop heads
if (!t.isFor(parent)) {
for (const declar of (node.declarations: Array<Object>)) {
for (const declar of node.declarations as Array<any>) {
if (declar.init) {
// has an init so let's split it up over multiple lines
hasInits = true;
@ -283,15 +290,20 @@ export function VariableDeclaration(node: Object, parent: Object) {
if (t.isFor(parent)) {
// don't give semicolons to these nodes since they'll be inserted in the parent generator
if (parent.left === node || parent.init === node) return;
if (t.isForStatement(parent)) {
if (parent.init === node) return;
} else {
if (parent.left === node) return;
}
}
this.semicolon();
}
export function VariableDeclarator(node: Object) {
export function VariableDeclarator(this: Printer, node: t.VariableDeclarator) {
this.print(node.id, node);
if (node.definite) this.token("!"); // TS
// @ts-expect-error todo(flow-ts) Property 'typeAnnotation' does not exist on type 'MemberExpression'.
this.print(node.id.typeAnnotation, node);
if (node.init) {
this.space();

View File

@ -1,10 +1,20 @@
export function TaggedTemplateExpression(node: Object) {
import type Printer from "../printer";
import * as t from "@babel/types";
export function TaggedTemplateExpression(
this: Printer,
node: t.TaggedTemplateExpression,
) {
this.print(node.tag, node);
this.print(node.typeParameters, node); // TS
this.print(node.quasi, node);
}
export function TemplateElement(node: Object, parent: Object) {
export function TemplateElement(
this: Printer,
node: t.TemplateElement,
parent: any,
) {
const isFirst = parent.quasis[0] === node;
const isLast = parent.quasis[parent.quasis.length - 1] === node;
@ -13,7 +23,7 @@ export function TemplateElement(node: Object, parent: Object) {
this.token(value);
}
export function TemplateLiteral(node: Object) {
export function TemplateLiteral(this: Printer, node: t.TemplateLiteral) {
const quasis = node.quasis;
for (let i = 0; i < quasis.length; i++) {

View File

@ -1,24 +1,25 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import jsesc from "jsesc";
export function Identifier(node: Object) {
export function Identifier(this: Printer, node: t.Identifier) {
this.exactSource(node.loc, () => {
this.word(node.name);
});
}
export function ArgumentPlaceholder() {
export function ArgumentPlaceholder(this: Printer) {
this.token("?");
}
export function RestElement(node: Object) {
export function RestElement(this: Printer, node: t.RestElement) {
this.token("...");
this.print(node.argument, node);
}
export { RestElement as SpreadElement };
export function ObjectExpression(node: Object) {
export function ObjectExpression(this: Printer, node: t.ObjectExpression) {
const props = node.properties;
this.token("{");
@ -35,14 +36,14 @@ export function ObjectExpression(node: Object) {
export { ObjectExpression as ObjectPattern };
export function ObjectMethod(node: Object) {
export function ObjectMethod(this: Printer, node: t.ObjectMethod) {
this.printJoin(node.decorators, node);
this._methodHead(node);
this.space();
this.print(node.body, node);
}
export function ObjectProperty(node: Object) {
export function ObjectProperty(this: Printer, node: t.ObjectProperty) {
this.printJoin(node.decorators, node);
if (node.computed) {
@ -54,6 +55,7 @@ export function ObjectProperty(node: Object) {
if (
t.isAssignmentPattern(node.value) &&
t.isIdentifier(node.key) &&
// @ts-expect-error todo(flow->ts) `.name` does not exist on some types in union
node.key.name === node.value.left.name
) {
this.print(node.value, node);
@ -78,7 +80,7 @@ export function ObjectProperty(node: Object) {
this.print(node.value, node);
}
export function ArrayExpression(node: Object) {
export function ArrayExpression(this: Printer, node: t.ArrayExpression) {
const elems = node.elements;
const len = elems.length;
@ -106,7 +108,7 @@ export function ArrayExpression(node: Object) {
export { ArrayExpression as ArrayPattern };
export function RecordExpression(node: Object) {
export function RecordExpression(this: Printer, node: t.RecordExpression) {
const props = node.properties;
let startToken;
@ -136,7 +138,7 @@ export function RecordExpression(node: Object) {
this.token(endToken);
}
export function TupleExpression(node: Object) {
export function TupleExpression(this: Printer, node: t.TupleExpression) {
const elems = node.elements;
const len = elems.length;
@ -169,19 +171,19 @@ export function TupleExpression(node: Object) {
this.token(endToken);
}
export function RegExpLiteral(node: Object) {
export function RegExpLiteral(this: Printer, node: t.RegExpLiteral) {
this.word(`/${node.pattern}/${node.flags}`);
}
export function BooleanLiteral(node: Object) {
export function BooleanLiteral(this: Printer, node: t.BooleanLiteral) {
this.word(node.value ? "true" : "false");
}
export function NullLiteral() {
export function NullLiteral(this: Printer) {
this.word("null");
}
export function NumericLiteral(node: Object) {
export function NumericLiteral(this: Printer, node: t.NumericLiteral) {
const raw = this.getPossibleRaw(node);
const opts = this.format.jsescOption;
const value = node.value + "";
@ -196,7 +198,7 @@ export function NumericLiteral(node: Object) {
}
}
export function StringLiteral(node: Object) {
export function StringLiteral(this: Printer, node: t.StringLiteral) {
const raw = this.getPossibleRaw(node);
if (!this.format.minified && raw != null) {
this.token(raw);
@ -216,7 +218,7 @@ export function StringLiteral(node: Object) {
return this.token(val);
}
export function BigIntLiteral(node: Object) {
export function BigIntLiteral(this: Printer, node: t.BigIntLiteral) {
const raw = this.getPossibleRaw(node);
if (!this.format.minified && raw != null) {
this.word(raw);
@ -225,7 +227,7 @@ export function BigIntLiteral(node: Object) {
this.word(node.value + "n");
}
export function DecimalLiteral(node: Object) {
export function DecimalLiteral(this: Printer, node: t.DecimalLiteral) {
const raw = this.getPossibleRaw(node);
if (!this.format.minified && raw != null) {
this.word(raw);
@ -234,14 +236,20 @@ export function DecimalLiteral(node: Object) {
this.word(node.value + "m");
}
export function PipelineTopicExpression(node: Object) {
export function PipelineTopicExpression(
this: Printer,
node: t.PipelineTopicExpression,
) {
this.print(node.expression, node);
}
export function PipelineBareFunction(node: Object) {
export function PipelineBareFunction(
this: Printer,
node: t.PipelineBareFunction,
) {
this.print(node.callee, node);
}
export function PipelinePrimaryTopicReference() {
export function PipelinePrimaryTopicReference(this: Printer) {
this.token("#");
}

View File

@ -1,11 +1,18 @@
export function TSTypeAnnotation(node) {
import type Printer from "../printer";
import * as t from "@babel/types";
export function TSTypeAnnotation(this: Printer, node: t.TSTypeAnnotation) {
this.token(":");
this.space();
// @ts-expect-error todo(flow->ts) can this be removed? `.optional` looks to be not existing property
if (node.optional) this.token("?");
this.print(node.typeAnnotation, node);
}
export function TSTypeParameterInstantiation(node): void {
export function TSTypeParameterInstantiation(
this: Printer,
node: t.TSTypeParameterInstantiation,
): void {
this.token("<");
this.printList(node.params, node, {});
this.token(">");
@ -13,7 +20,7 @@ export function TSTypeParameterInstantiation(node): void {
export { TSTypeParameterInstantiation as TSTypeParameterDeclaration };
export function TSTypeParameter(node) {
export function TSTypeParameter(this: Printer, node: t.TSTypeParameter) {
this.word(node.name);
if (node.constraint) {
@ -31,7 +38,10 @@ export function TSTypeParameter(node) {
}
}
export function TSParameterProperty(node) {
export function TSParameterProperty(
this: Printer,
node: t.TSParameterProperty,
) {
if (node.accessibility) {
this.word(node.accessibility);
this.space();
@ -45,7 +55,7 @@ export function TSParameterProperty(node) {
this._param(node.parameter);
}
export function TSDeclareFunction(node) {
export function TSDeclareFunction(this: Printer, node: t.TSDeclareFunction) {
if (node.declare) {
this.word("declare");
this.space();
@ -54,30 +64,39 @@ export function TSDeclareFunction(node) {
this.token(";");
}
export function TSDeclareMethod(node) {
export function TSDeclareMethod(this: Printer, node: t.TSDeclareMethod) {
this._classMethodHead(node);
this.token(";");
}
export function TSQualifiedName(node) {
export function TSQualifiedName(this: Printer, node: t.TSQualifiedName) {
this.print(node.left, node);
this.token(".");
this.print(node.right, node);
}
export function TSCallSignatureDeclaration(node) {
export function TSCallSignatureDeclaration(
this: Printer,
node: t.TSCallSignatureDeclaration,
) {
this.tsPrintSignatureDeclarationBase(node);
this.token(";");
}
export function TSConstructSignatureDeclaration(node) {
export function TSConstructSignatureDeclaration(
this: Printer,
node: t.TSConstructSignatureDeclaration,
) {
this.word("new");
this.space();
this.tsPrintSignatureDeclarationBase(node);
this.token(";");
}
export function TSPropertySignature(node) {
export function TSPropertySignature(
this: Printer,
node: t.TSPropertySignature,
) {
const { readonly, initializer } = node;
if (readonly) {
this.word("readonly");
@ -94,7 +113,7 @@ export function TSPropertySignature(node) {
this.token(";");
}
export function tsPrintPropertyOrMethodName(node) {
export function tsPrintPropertyOrMethodName(this: Printer, node) {
if (node.computed) {
this.token("[");
}
@ -107,13 +126,13 @@ export function tsPrintPropertyOrMethodName(node) {
}
}
export function TSMethodSignature(node) {
export function TSMethodSignature(this: Printer, node: t.TSMethodSignature) {
this.tsPrintPropertyOrMethodName(node);
this.tsPrintSignatureDeclarationBase(node);
this.token(";");
}
export function TSIndexSignature(node) {
export function TSIndexSignature(this: Printer, node: t.TSIndexSignature) {
const { readonly } = node;
if (readonly) {
this.word("readonly");
@ -126,62 +145,64 @@ export function TSIndexSignature(node) {
this.token(";");
}
export function TSAnyKeyword() {
export function TSAnyKeyword(this: Printer) {
this.word("any");
}
export function TSBigIntKeyword() {
export function TSBigIntKeyword(this: Printer) {
this.word("bigint");
}
export function TSUnknownKeyword() {
export function TSUnknownKeyword(this: Printer) {
this.word("unknown");
}
export function TSNumberKeyword() {
export function TSNumberKeyword(this: Printer) {
this.word("number");
}
export function TSObjectKeyword() {
export function TSObjectKeyword(this: Printer) {
this.word("object");
}
export function TSBooleanKeyword() {
export function TSBooleanKeyword(this: Printer) {
this.word("boolean");
}
export function TSStringKeyword() {
export function TSStringKeyword(this: Printer) {
this.word("string");
}
export function TSSymbolKeyword() {
export function TSSymbolKeyword(this: Printer) {
this.word("symbol");
}
export function TSVoidKeyword() {
export function TSVoidKeyword(this: Printer) {
this.word("void");
}
export function TSUndefinedKeyword() {
export function TSUndefinedKeyword(this: Printer) {
this.word("undefined");
}
export function TSNullKeyword() {
export function TSNullKeyword(this: Printer) {
this.word("null");
}
export function TSNeverKeyword() {
export function TSNeverKeyword(this: Printer) {
this.word("never");
}
export function TSIntrinsicKeyword() {
this.word("intrinsic");
}
export function TSThisType() {
export function TSThisType(this: Printer) {
this.word("this");
}
export function TSFunctionType(node) {
export function TSFunctionType(this: Printer, node: t.TSFunctionType) {
this.tsPrintFunctionOrConstructorType(node);
}
export function TSConstructorType(node) {
export function TSConstructorType(this: Printer, node: t.TSConstructorType) {
this.word("new");
this.space();
this.tsPrintFunctionOrConstructorType(node);
}
export function tsPrintFunctionOrConstructorType(
node: FunctionOrConstructorType,
this: Printer,
// todo: missing type FunctionOrConstructorType
node: any,
) {
const { typeParameters, parameters } = node;
this.print(typeParameters, node);
@ -194,12 +215,12 @@ export function tsPrintFunctionOrConstructorType(
this.print(node.typeAnnotation.typeAnnotation, node);
}
export function TSTypeReference(node) {
export function TSTypeReference(this: Printer, node: t.TSTypeReference) {
this.print(node.typeName, node);
this.print(node.typeParameters, node);
}
export function TSTypePredicate(node) {
export function TSTypePredicate(this: Printer, node: t.TSTypePredicate) {
if (node.asserts) {
this.word("asserts");
this.space();
@ -213,21 +234,25 @@ export function TSTypePredicate(node) {
}
}
export function TSTypeQuery(node) {
export function TSTypeQuery(this: Printer, node: t.TSTypeQuery) {
this.word("typeof");
this.space();
this.print(node.exprName);
}
export function TSTypeLiteral(node) {
export function TSTypeLiteral(this: Printer, node: t.TSTypeLiteral) {
this.tsPrintTypeLiteralOrInterfaceBody(node.members, node);
}
export function tsPrintTypeLiteralOrInterfaceBody(members, node) {
export function tsPrintTypeLiteralOrInterfaceBody(
this: Printer,
members,
node,
) {
this.tsPrintBraced(members, node);
}
export function tsPrintBraced(members, node) {
export function tsPrintBraced(this: Printer, members, node) {
this.token("{");
if (members.length) {
this.indent();
@ -244,28 +269,28 @@ export function tsPrintBraced(members, node) {
}
}
export function TSArrayType(node) {
export function TSArrayType(this: Printer, node: t.TSArrayType) {
this.print(node.elementType, node);
this.token("[]");
}
export function TSTupleType(node) {
export function TSTupleType(this: Printer, node: t.TSTupleType) {
this.token("[");
this.printList(node.elementTypes, node);
this.token("]");
}
export function TSOptionalType(node) {
export function TSOptionalType(this: Printer, node: t.TSOptionalType) {
this.print(node.typeAnnotation, node);
this.token("?");
}
export function TSRestType(node) {
export function TSRestType(this: Printer, node: t.TSRestType) {
this.token("...");
this.print(node.typeAnnotation, node);
}
export function TSNamedTupleMember(node) {
export function TSNamedTupleMember(this: Printer, node: t.TSNamedTupleMember) {
this.print(node.label, node);
if (node.optional) this.token("?");
this.token(":");
@ -273,15 +298,15 @@ export function TSNamedTupleMember(node) {
this.print(node.elementType, node);
}
export function TSUnionType(node) {
export function TSUnionType(this: Printer, node: t.TSUnionType) {
this.tsPrintUnionOrIntersectionType(node, "|");
}
export function TSIntersectionType(node) {
export function TSIntersectionType(this: Printer, node: t.TSIntersectionType) {
this.tsPrintUnionOrIntersectionType(node, "&");
}
export function tsPrintUnionOrIntersectionType(node, sep) {
export function tsPrintUnionOrIntersectionType(this: Printer, node: any, sep) {
this.printJoin(node.types, node, {
separator() {
this.space();
@ -291,7 +316,7 @@ export function tsPrintUnionOrIntersectionType(node, sep) {
});
}
export function TSConditionalType(node) {
export function TSConditionalType(this: Printer, node: t.TSConditionalType) {
this.print(node.checkType);
this.space();
this.word("extends");
@ -307,32 +332,38 @@ export function TSConditionalType(node) {
this.print(node.falseType);
}
export function TSInferType(node) {
export function TSInferType(this: Printer, node: t.TSInferType) {
this.token("infer");
this.space();
this.print(node.typeParameter);
}
export function TSParenthesizedType(node) {
export function TSParenthesizedType(
this: Printer,
node: t.TSParenthesizedType,
) {
this.token("(");
this.print(node.typeAnnotation, node);
this.token(")");
}
export function TSTypeOperator(node) {
export function TSTypeOperator(this: Printer, node: t.TSTypeOperator) {
this.word(node.operator);
this.space();
this.print(node.typeAnnotation, node);
}
export function TSIndexedAccessType(node) {
export function TSIndexedAccessType(
this: Printer,
node: t.TSIndexedAccessType,
) {
this.print(node.objectType, node);
this.token("[");
this.print(node.indexType, node);
this.token("]");
}
export function TSMappedType(node) {
export function TSMappedType(this: Printer, node: t.TSMappedType) {
const { nameType, optional, readonly, typeParameter } = node;
this.token("{");
this.space();
@ -375,16 +406,22 @@ function tokenIfPlusMinus(self, tok) {
}
}
export function TSLiteralType(node) {
export function TSLiteralType(this: Printer, node: t.TSLiteralType) {
this.print(node.literal, node);
}
export function TSExpressionWithTypeArguments(node) {
export function TSExpressionWithTypeArguments(
this: Printer,
node: t.TSExpressionWithTypeArguments,
) {
this.print(node.expression, node);
this.print(node.typeParameters, node);
}
export function TSInterfaceDeclaration(node) {
export function TSInterfaceDeclaration(
this: Printer,
node: t.TSInterfaceDeclaration,
) {
const { declare, id, typeParameters, extends: extendz, body } = node;
if (declare) {
this.word("declare");
@ -404,11 +441,14 @@ export function TSInterfaceDeclaration(node) {
this.print(body, node);
}
export function TSInterfaceBody(node) {
export function TSInterfaceBody(this: Printer, node: t.TSInterfaceBody) {
this.tsPrintTypeLiteralOrInterfaceBody(node.body, node);
}
export function TSTypeAliasDeclaration(node) {
export function TSTypeAliasDeclaration(
this: Printer,
node: t.TSTypeAliasDeclaration,
) {
const { declare, id, typeParameters, typeAnnotation } = node;
if (declare) {
this.word("declare");
@ -425,7 +465,7 @@ export function TSTypeAliasDeclaration(node) {
this.token(";");
}
export function TSAsExpression(node) {
export function TSAsExpression(this: Printer, node: t.TSAsExpression) {
const { expression, typeAnnotation } = node;
this.print(expression, node);
this.space();
@ -434,7 +474,7 @@ export function TSAsExpression(node) {
this.print(typeAnnotation, node);
}
export function TSTypeAssertion(node) {
export function TSTypeAssertion(this: Printer, node: t.TSTypeAssertion) {
const { typeAnnotation, expression } = node;
this.token("<");
this.print(typeAnnotation, node);
@ -443,7 +483,7 @@ export function TSTypeAssertion(node) {
this.print(expression, node);
}
export function TSEnumDeclaration(node) {
export function TSEnumDeclaration(this: Printer, node: t.TSEnumDeclaration) {
const { declare, const: isConst, id, members } = node;
if (declare) {
this.word("declare");
@ -460,7 +500,7 @@ export function TSEnumDeclaration(node) {
this.tsPrintBraced(members, node);
}
export function TSEnumMember(node) {
export function TSEnumMember(this: Printer, node: t.TSEnumMember) {
const { id, initializer } = node;
this.print(id, node);
if (initializer) {
@ -472,7 +512,10 @@ export function TSEnumMember(node) {
this.token(",");
}
export function TSModuleDeclaration(node) {
export function TSModuleDeclaration(
this: Printer,
node: t.TSModuleDeclaration,
) {
const { declare, id } = node;
if (declare) {
@ -502,11 +545,11 @@ export function TSModuleDeclaration(node) {
this.print(body, node);
}
export function TSModuleBlock(node) {
export function TSModuleBlock(this: Printer, node: t.TSModuleBlock) {
this.tsPrintBraced(node.body, node);
}
export function TSImportType(node) {
export function TSImportType(this: Printer, node: t.TSImportType) {
const { argument, qualifier, typeParameters } = node;
this.word("import");
this.token("(");
@ -521,7 +564,10 @@ export function TSImportType(node) {
}
}
export function TSImportEqualsDeclaration(node) {
export function TSImportEqualsDeclaration(
this: Printer,
node: t.TSImportEqualsDeclaration,
) {
const { isExport, id, moduleReference } = node;
if (isExport) {
this.word("export");
@ -537,18 +583,24 @@ export function TSImportEqualsDeclaration(node) {
this.token(";");
}
export function TSExternalModuleReference(node) {
export function TSExternalModuleReference(
this: Printer,
node: t.TSExternalModuleReference,
) {
this.token("require(");
this.print(node.expression, node);
this.token(")");
}
export function TSNonNullExpression(node) {
export function TSNonNullExpression(
this: Printer,
node: t.TSNonNullExpression,
) {
this.print(node.expression, node);
this.token("!");
}
export function TSExportAssignment(node) {
export function TSExportAssignment(this: Printer, node: t.TSExportAssignment) {
this.word("export");
this.space();
this.token("=");
@ -557,7 +609,10 @@ export function TSExportAssignment(node) {
this.token(";");
}
export function TSNamespaceExportDeclaration(node) {
export function TSNamespaceExportDeclaration(
this: Printer,
node: t.TSNamespaceExportDeclaration,
) {
this.word("export");
this.space();
this.word("as");
@ -567,7 +622,7 @@ export function TSNamespaceExportDeclaration(node) {
this.print(node.id, node);
}
export function tsPrintSignatureDeclarationBase(node) {
export function tsPrintSignatureDeclarationBase(this: Printer, node: any) {
const { typeParameters, parameters } = node;
this.print(typeParameters, node);
this.token("(");
@ -576,7 +631,7 @@ export function tsPrintSignatureDeclarationBase(node) {
this.print(node.typeAnnotation, node);
}
export function tsPrintClassMemberModifiers(node, isField) {
export function tsPrintClassMemberModifiers(this: Printer, node: any, isField) {
if (isField && node.declare) {
this.word("declare");
this.space();

View File

@ -1,119 +0,0 @@
import SourceMap from "./source-map";
import Printer, { type Format } from "./printer";
/**
* Babel's code generator, turns an ast into code, maintaining sourcemaps,
* user preferences, and valid output.
*/
class Generator extends Printer {
constructor(ast, opts = {}, code) {
const format = normalizeOptions(code, opts);
const map = opts.sourceMaps ? new SourceMap(opts, code) : null;
super(format, map);
this.ast = ast;
}
ast: Object;
/**
* Generate code and sourcemap from ast.
*
* Appends comments that weren't attached to any node to the end of the generated output.
*/
generate() {
return super.generate(this.ast);
}
}
/**
* Normalize generator options, setting defaults.
*
* - Detects code indentation.
* - If `opts.compact = "auto"` and the code is over 500KB, `compact` will be set to `true`.
*/
function normalizeOptions(code, opts): Format {
const format = {
auxiliaryCommentBefore: opts.auxiliaryCommentBefore,
auxiliaryCommentAfter: opts.auxiliaryCommentAfter,
shouldPrintComment: opts.shouldPrintComment,
retainLines: opts.retainLines,
retainFunctionParens: opts.retainFunctionParens,
comments: opts.comments == null || opts.comments,
compact: opts.compact,
minified: opts.minified,
concise: opts.concise,
indent: {
adjustMultilineComment: true,
style: " ",
base: 0,
},
decoratorsBeforeExport: !!opts.decoratorsBeforeExport,
jsescOption: {
quotes: "double",
wrap: true,
minimal: true,
...opts.jsescOption,
},
recordAndTupleSyntaxType: opts.recordAndTupleSyntaxType,
};
if (!process.env.BABEL_8_BREAKING) {
format.jsonCompatibleStrings = opts.jsonCompatibleStrings;
delete format.jsescOption.minimal;
}
if (format.minified) {
format.compact = true;
format.shouldPrintComment =
format.shouldPrintComment || (() => format.comments);
} else {
format.shouldPrintComment =
format.shouldPrintComment ||
(value =>
format.comments ||
value.indexOf("@license") >= 0 ||
value.indexOf("@preserve") >= 0);
}
if (format.compact === "auto") {
format.compact = code.length > 500_000; // 500KB
if (format.compact) {
console.error(
"[BABEL] Note: The code generator has deoptimised the styling of " +
`${opts.filename} as it exceeds the max of ${"500KB"}.`,
);
}
}
if (format.compact) {
format.indent.adjustMultilineComment = false;
}
return format;
}
/**
* We originally exported the Generator class above, but to make it extra clear that it is a private API,
* we have moved that to an internal class instance and simplified the interface to the two public methods
* that we wish to support.
*/
export class CodeGenerator {
constructor(ast, opts, code) {
this._generator = new Generator(ast, opts, code);
}
generate() {
return this._generator.generate();
}
}
export default function (ast: Object, opts: Object, code: string): Object {
const gen = new Generator(ast, opts, code);
return gen.generate();
}

View File

@ -0,0 +1,246 @@
import SourceMap from "./source-map";
import Printer from "./printer";
import type * as t from "@babel/types";
import type { Format } from "./printer";
/**
* Babel's code generator, turns an ast into code, maintaining sourcemaps,
* user preferences, and valid output.
*/
class Generator extends Printer {
constructor(ast: t.Node, opts: { sourceMaps?: boolean } = {}, code) {
const format = normalizeOptions(code, opts);
const map = opts.sourceMaps ? new SourceMap(opts, code) : null;
super(format, map);
this.ast = ast;
}
ast: t.Node;
/**
* Generate code and sourcemap from ast.
*
* Appends comments that weren't attached to any node to the end of the generated output.
*/
generate() {
return super.generate(this.ast);
}
}
/**
* Normalize generator options, setting defaults.
*
* - Detects code indentation.
* - If `opts.compact = "auto"` and the code is over 500KB, `compact` will be set to `true`.
*/
function normalizeOptions(code, opts): Format {
const format: Format = {
auxiliaryCommentBefore: opts.auxiliaryCommentBefore,
auxiliaryCommentAfter: opts.auxiliaryCommentAfter,
shouldPrintComment: opts.shouldPrintComment,
retainLines: opts.retainLines,
retainFunctionParens: opts.retainFunctionParens,
comments: opts.comments == null || opts.comments,
compact: opts.compact,
minified: opts.minified,
concise: opts.concise,
indent: {
adjustMultilineComment: true,
style: " ",
base: 0,
},
decoratorsBeforeExport: !!opts.decoratorsBeforeExport,
jsescOption: {
quotes: "double",
wrap: true,
minimal: true,
...opts.jsescOption,
},
recordAndTupleSyntaxType: opts.recordAndTupleSyntaxType,
};
if (!process.env.BABEL_8_BREAKING) {
format.jsonCompatibleStrings = opts.jsonCompatibleStrings;
delete format.jsescOption.minimal;
}
if (format.minified) {
format.compact = true;
format.shouldPrintComment =
format.shouldPrintComment || (() => format.comments);
} else {
format.shouldPrintComment =
format.shouldPrintComment ||
(value =>
format.comments ||
value.indexOf("@license") >= 0 ||
value.indexOf("@preserve") >= 0);
}
if (format.compact === "auto") {
format.compact = code.length > 500_000; // 500KB
if (format.compact) {
console.error(
"[BABEL] Note: The code generator has deoptimised the styling of " +
`${opts.filename} as it exceeds the max of ${"500KB"}.`,
);
}
}
if (format.compact) {
format.indent.adjustMultilineComment = false;
}
return format;
}
export interface GeneratorOptions {
/**
* Optional string to add as a block comment at the start of the output file.
*/
auxiliaryCommentBefore?: string;
/**
* Optional string to add as a block comment at the end of the output file.
*/
auxiliaryCommentAfter?: string;
/**
* Function that takes a comment (as a string) and returns true if the comment should be included in the output.
* By default, comments are included if `opts.comments` is `true` or if `opts.minifed` is `false` and the comment
* contains `@preserve` or `@license`.
*/
shouldPrintComment?(comment: string): boolean;
/**
* Attempt to use the same line numbers in the output code as in the source code (helps preserve stack traces).
* Defaults to `false`.
*/
retainLines?: boolean;
/**
* Retain parens around function expressions (could be used to change engine parsing behavior)
* Defaults to `false`.
*/
retainFunctionParens?: boolean;
/**
* Should comments be included in output? Defaults to `true`.
*/
comments?: boolean;
/**
* Set to true to avoid adding whitespace for formatting. Defaults to the value of `opts.minified`.
*/
compact?: boolean | "auto";
/**
* Should the output be minified. Defaults to `false`.
*/
minified?: boolean;
/**
* Set to true to reduce whitespace (but not as much as opts.compact). Defaults to `false`.
*/
concise?: boolean;
/**
* Used in warning messages
*/
filename?: string;
/**
* Enable generating source maps. Defaults to `false`.
*/
sourceMaps?: boolean;
/**
* A root for all relative URLs in the source map.
*/
sourceRoot?: string;
/**
* The filename for the source code (i.e. the code in the `code` argument).
* This will only be used if `code` is a string.
*/
sourceFileName?: string;
/**
* Set to true to run jsesc with "json": true to print "\u00A9" vs. "©";
*/
jsonCompatibleStrings?: boolean;
/**
* Set to true to enable support for experimental decorators syntax before module exports.
* Defaults to `false`.
*/
decoratorsBeforeExport?: boolean;
/**
* Options for outputting jsesc representation.
*/
jsescOption?: {
/**
* The type of quote to use in the output. If omitted, autodetects based on `ast.tokens`.
*/
quotes?: "single" | "double";
/**
* When enabled, the output is a valid JavaScript string literal wrapped in quotes. The type of quotes can be specified through the quotes setting.
* Defaults to `true`.
*/
wrap?: boolean;
};
}
export interface GeneratorResult {
code: string;
map: {
version: number;
sources: string[];
names: string[];
sourceRoot?: string;
sourcesContent?: string[];
mappings: string;
file: string;
} | null;
}
/**
* We originally exported the Generator class above, but to make it extra clear that it is a private API,
* we have moved that to an internal class instance and simplified the interface to the two public methods
* that we wish to support.
*/
export class CodeGenerator {
private _generator: Generator;
constructor(ast: t.Node, opts?: GeneratorOptions, code?: string) {
this._generator = new Generator(ast, opts, code);
}
generate(): GeneratorResult {
return this._generator.generate();
}
}
/**
* Turns an AST into code, maintaining sourcemaps, user preferences, and valid output.
* @param ast - the abstract syntax tree from which to generate output code.
* @param opts - used for specifying options for code generation.
* @param code - the original source code, used for source maps.
* @returns - an object containing the output code and source map.
*/
export default function generate(
ast: t.Node,
opts?: GeneratorOptions,
code?: string | { [filename: string]: string },
): any {
const gen = new Generator(ast, opts, code);
return gen.generate();
}

View File

@ -36,7 +36,7 @@ const expandedParens = expandAliases(parens);
const expandedWhitespaceNodes = expandAliases(whitespace.nodes);
const expandedWhitespaceList = expandAliases(whitespace.list);
function find(obj, node, parent, printStack) {
function find(obj, node, parent, printStack?) {
const fn = obj[node.type];
return fn ? fn(node, parent, printStack) : null;
}
@ -83,7 +83,7 @@ export function needsWhitespaceAfter(node, parent) {
return needsWhitespace(node, parent, "after");
}
export function needsParens(node, parent, printStack) {
export function needsParens(node, parent, printStack?) {
if (!parent) return false;
if (t.isNewExpression(parent) && parent.callee === node) {

View File

@ -28,11 +28,11 @@ const PRECEDENCE = {
"**": 10,
};
const isClassExtendsClause = (node: Object, parent: Object): boolean =>
const isClassExtendsClause = (node: any, parent: any): boolean =>
(t.isClassDeclaration(parent) || t.isClassExpression(parent)) &&
parent.superClass === node;
const hasPostfixPart = (node: Object, parent: Object) =>
const hasPostfixPart = (node: any, parent: any) =>
((t.isMemberExpression(parent) || t.isOptionalMemberExpression(parent)) &&
parent.object === node) ||
((t.isCallExpression(parent) ||
@ -42,14 +42,14 @@ const hasPostfixPart = (node: Object, parent: Object) =>
(t.isTaggedTemplateExpression(parent) && parent.tag === node) ||
t.isTSNonNullExpression(parent);
export function NullableTypeAnnotation(node: Object, parent: Object): boolean {
export function NullableTypeAnnotation(node: any, parent: any): boolean {
return t.isArrayTypeAnnotation(parent);
}
export function FunctionTypeAnnotation(
node: Object,
parent: Object,
printStack: Array<Object>,
node: any,
parent: any,
printStack: Array<any>,
): boolean {
return (
// (() => A) | (() => B)
@ -65,27 +65,27 @@ export function FunctionTypeAnnotation(
);
}
export function UpdateExpression(node: Object, parent: Object): boolean {
export function UpdateExpression(node: any, parent: any): boolean {
return hasPostfixPart(node, parent) || isClassExtendsClause(node, parent);
}
export function ObjectExpression(
node: Object,
parent: Object,
printStack: Array<Object>,
node: any,
parent: any,
printStack: Array<any>,
): boolean {
return isFirstInStatement(printStack, { considerArrow: true });
}
export function DoExpression(
node: Object,
parent: Object,
printStack: Array<Object>,
node: any,
parent: any,
printStack: Array<any>,
): boolean {
return isFirstInStatement(printStack);
}
export function Binary(node: Object, parent: Object): boolean {
export function Binary(node: any, parent: any): boolean {
if (
node.operator === "**" &&
t.isBinaryExpression(parent, { operator: "**" })
@ -124,7 +124,7 @@ export function Binary(node: Object, parent: Object): boolean {
}
}
export function UnionTypeAnnotation(node: Object, parent: Object): boolean {
export function UnionTypeAnnotation(node: any, parent: any): boolean {
return (
t.isArrayTypeAnnotation(parent) ||
t.isNullableTypeAnnotation(parent) ||
@ -143,7 +143,7 @@ export function TSTypeAssertion() {
return true;
}
export function TSUnionType(node: Object, parent: Object): boolean {
export function TSUnionType(node: any, parent: any): boolean {
return (
t.isTSArrayType(parent) ||
t.isTSOptionalType(parent) ||
@ -155,11 +155,11 @@ export function TSUnionType(node: Object, parent: Object): boolean {
export { TSUnionType as TSIntersectionType };
export function TSInferType(node: Object, parent: Object): boolean {
export function TSInferType(node: any, parent: any): boolean {
return t.isTSArrayType(parent) || t.isTSOptionalType(parent);
}
export function BinaryExpression(node: Object, parent: Object): boolean {
export function BinaryExpression(node: any, parent: any): boolean {
// let i = (1 in []);
// for ((1 in []);;);
return (
@ -168,7 +168,7 @@ export function BinaryExpression(node: Object, parent: Object): boolean {
);
}
export function SequenceExpression(node: Object, parent: Object): boolean {
export function SequenceExpression(node: any, parent: any): boolean {
if (
// Although parentheses wouldn"t hurt around sequence
// expressions in the head of for loops, traditional style
@ -191,7 +191,7 @@ export function SequenceExpression(node: Object, parent: Object): boolean {
return true;
}
export function YieldExpression(node: Object, parent: Object): boolean {
export function YieldExpression(node: any, parent: any): boolean {
return (
t.isBinary(parent) ||
t.isUnaryLike(parent) ||
@ -205,14 +205,14 @@ export function YieldExpression(node: Object, parent: Object): boolean {
export { YieldExpression as AwaitExpression };
export function ClassExpression(
node: Object,
parent: Object,
printStack: Array<Object>,
node: any,
parent: any,
printStack: Array<any>,
): boolean {
return isFirstInStatement(printStack, { considerDefaultExports: true });
}
export function UnaryLike(node: Object, parent: Object): boolean {
export function UnaryLike(node: any, parent: any): boolean {
return (
hasPostfixPart(node, parent) ||
t.isBinaryExpression(parent, { operator: "**", left: node }) ||
@ -221,18 +221,18 @@ export function UnaryLike(node: Object, parent: Object): boolean {
}
export function FunctionExpression(
node: Object,
parent: Object,
printStack: Array<Object>,
node: any,
parent: any,
printStack: Array<any>,
): boolean {
return isFirstInStatement(printStack, { considerDefaultExports: true });
}
export function ArrowFunctionExpression(node: Object, parent: Object): boolean {
export function ArrowFunctionExpression(node: any, parent: any): boolean {
return t.isExportDeclaration(parent) || ConditionalExpression(node, parent);
}
export function ConditionalExpression(node: Object, parent: Object): boolean {
export function ConditionalExpression(node: any, parent?): boolean {
if (
t.isUnaryLike(parent) ||
t.isBinary(parent) ||
@ -247,10 +247,7 @@ export function ConditionalExpression(node: Object, parent: Object): boolean {
return UnaryLike(node, parent);
}
export function OptionalMemberExpression(
node: Object,
parent: Object,
): boolean {
export function OptionalMemberExpression(node: any, parent: any): boolean {
return (
t.isCallExpression(parent, { callee: node }) ||
t.isMemberExpression(parent, { object: node })
@ -259,19 +256,15 @@ export function OptionalMemberExpression(
export { OptionalMemberExpression as OptionalCallExpression };
export function AssignmentExpression(
node: Object,
parent: Object,
printStack: Array<Object>,
): boolean {
export function AssignmentExpression(node: any, parent: any): boolean {
if (t.isObjectPattern(node.left)) {
return true;
} else {
return ConditionalExpression(node, parent, printStack);
return ConditionalExpression(node, parent);
}
}
export function LogicalExpression(node: Object, parent: Object): boolean {
export function LogicalExpression(node: any, parent: any): boolean {
switch (node.operator) {
case "||":
if (!t.isLogicalExpression(parent)) return false;
@ -286,7 +279,7 @@ export function LogicalExpression(node: Object, parent: Object): boolean {
// Walk up the print stack to determine if our node can come first
// in statement.
function isFirstInStatement(
printStack: Array<Object>,
printStack: Array<any>,
{ considerArrow = false, considerDefaultExports = false } = {},
): boolean {
let i = printStack.length - 1;

View File

@ -1,8 +1,8 @@
import * as t from "@babel/types";
type WhitespaceObject = {
before?: boolean,
after?: boolean,
before?: boolean;
after?: boolean;
};
/**
@ -13,7 +13,10 @@ type WhitespaceObject = {
* // { hasCall: false, hasFunction: true, hasHelper: false }
*/
function crawl(node, state = {}) {
function crawl(
node: t.Node,
state: { hasCall?: boolean; hasFunction?: boolean; hasHelper?: boolean } = {},
) {
if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
crawl(node.object, state);
if (node.computed) crawl(node.property, state);
@ -26,6 +29,7 @@ function crawl(node, state = {}) {
} else if (t.isFunction(node)) {
state.hasFunction = true;
} else if (t.isIdentifier(node)) {
// @ts-expect-error todo(flow->ts): node.callee is not really expected here…
state.hasHelper = state.hasHelper || isHelper(node.callee);
}
@ -36,7 +40,7 @@ function crawl(node, state = {}) {
* Test if a node is or has a helper.
*/
function isHelper(node) {
function isHelper(node: t.Node): boolean {
if (t.isMemberExpression(node)) {
return isHelper(node.object) || isHelper(node.property);
} else if (t.isIdentifier(node)) {
@ -66,12 +70,23 @@ function isType(node) {
* Tests for node types that need whitespace.
*/
export const nodes = {
export const nodes: {
[K in string]?: (
node: K extends t.Node["type"] ? Extract<t.Node, { type: K }> : t.Node,
// todo:
// node: K extends keyof typeof t
// ? Extract<typeof t[K], { type: "string" }>
// : t.Node,
parent: t.Node,
) => void;
} = {
/**
* Test if AssignmentExpression needs whitespace.
*/
AssignmentExpression(node: Object): ?WhitespaceObject {
AssignmentExpression(
node: t.AssignmentExpression,
): WhitespaceObject | undefined | null {
const state = crawl(node.right);
if ((state.hasCall && state.hasHelper) || state.hasFunction) {
return {
@ -85,9 +100,9 @@ export const nodes = {
* Test if SwitchCase needs whitespace.
*/
SwitchCase(node: Object, parent: Object): WhitespaceObject {
SwitchCase(node: t.SwitchCase, parent: t.SwitchStatement): WhitespaceObject {
return {
before: node.consequent.length || parent.cases[0] === node,
before: !!node.consequent.length || parent.cases[0] === node,
after:
!node.consequent.length &&
parent.cases[parent.cases.length - 1] === node,
@ -98,7 +113,7 @@ export const nodes = {
* Test if LogicalExpression needs whitespace.
*/
LogicalExpression(node: Object): ?WhitespaceObject {
LogicalExpression(node: t.LogicalExpression): WhitespaceObject | undefined {
if (t.isFunction(node.left) || t.isFunction(node.right)) {
return {
after: true,
@ -110,8 +125,8 @@ export const nodes = {
* Test if Literal needs whitespace.
*/
Literal(node: Object): ?WhitespaceObject {
if (node.value === "use strict") {
Literal(node: t.Literal): WhitespaceObject | undefined | null {
if (t.isStringLiteral(node) && node.value === "use strict") {
return {
after: true,
};
@ -122,7 +137,7 @@ export const nodes = {
* Test if CallExpressionish needs whitespace.
*/
CallExpression(node: Object): ?WhitespaceObject {
CallExpression(node: t.CallExpression): WhitespaceObject | undefined | null {
if (t.isFunction(node.callee) || isHelper(node)) {
return {
before: true,
@ -131,7 +146,9 @@ export const nodes = {
}
},
OptionalCallExpression(node: Object): ?WhitespaceObject {
OptionalCallExpression(
node: t.OptionalCallExpression,
): WhitespaceObject | undefined | null {
if (t.isFunction(node.callee)) {
return {
before: true,
@ -144,7 +161,9 @@ export const nodes = {
* Test if VariableDeclaration needs whitespace.
*/
VariableDeclaration(node: Object): ?WhitespaceObject {
VariableDeclaration(
node: t.VariableDeclaration,
): WhitespaceObject | undefined | null {
for (let i = 0; i < node.declarations.length; i++) {
const declar = node.declarations[i];
@ -167,7 +186,7 @@ export const nodes = {
* Test if IfStatement needs whitespace.
*/
IfStatement(node: Object): ?WhitespaceObject {
IfStatement(node: t.IfStatement): WhitespaceObject | undefined | null {
if (t.isBlockStatement(node.consequent)) {
return {
before: true,
@ -182,9 +201,9 @@ export const nodes = {
*/
nodes.ObjectProperty = nodes.ObjectTypeProperty = nodes.ObjectMethod = function (
node: Object,
parent,
): ?WhitespaceObject {
node: t.ObjectProperty | t.ObjectTypeProperty | t.ObjectMethod,
parent: any,
): WhitespaceObject | undefined | null {
if (parent.properties[0] === node) {
return {
before: true,
@ -193,9 +212,9 @@ nodes.ObjectProperty = nodes.ObjectTypeProperty = nodes.ObjectMethod = function
};
nodes.ObjectTypeCallProperty = function (
node: Object,
parent,
): ?WhitespaceObject {
node: t.ObjectTypeCallProperty,
parent: any,
): WhitespaceObject | undefined | null {
if (parent.callProperties[0] === node && !parent.properties?.length) {
return {
before: true,
@ -203,7 +222,10 @@ nodes.ObjectTypeCallProperty = function (
}
};
nodes.ObjectTypeIndexer = function (node: Object, parent): ?WhitespaceObject {
nodes.ObjectTypeIndexer = function (
node: t.ObjectTypeIndexer,
parent: any,
): WhitespaceObject | undefined | null {
if (
parent.indexers[0] === node &&
!parent.properties?.length &&
@ -216,9 +238,9 @@ nodes.ObjectTypeIndexer = function (node: Object, parent): ?WhitespaceObject {
};
nodes.ObjectTypeInternalSlot = function (
node: Object,
parent,
): ?WhitespaceObject {
node: t.ObjectTypeInternalSlot,
parent: any,
): WhitespaceObject | undefined | null {
if (
parent.internalSlots[0] === node &&
!parent.properties?.length &&
@ -240,7 +262,7 @@ export const list = {
* Return VariableDeclaration declarations init properties.
*/
VariableDeclaration(node: Object): Array<Object> {
VariableDeclaration(node: t.VariableDeclaration) {
return node.declarations.map(decl => decl.init);
},
@ -248,7 +270,7 @@ export const list = {
* Return VariableDeclaration elements.
*/
ArrayExpression(node: Object): Array<Object> {
ArrayExpression(node: t.ArrayExpression) {
return node.elements;
},
@ -256,7 +278,7 @@ export const list = {
* Return VariableDeclaration properties.
*/
ObjectExpression(node: Object): Array<Object> {
ObjectExpression(node: t.ObjectExpression) {
return node.properties;
},
};
@ -265,20 +287,22 @@ export const list = {
* Add whitespace tests for nodes and their aliases.
*/
[
([
["Function", true],
["Class", true],
["Loop", true],
["LabeledStatement", true],
["SwitchStatement", true],
["TryStatement", true],
].forEach(function ([type, amounts]) {
] as Array<[string, any]>).forEach(function ([type, amounts]) {
if (typeof amounts === "boolean") {
amounts = { after: amounts, before: amounts };
}
[type].concat(t.FLIPPED_ALIAS_KEYS[type] || []).forEach(function (type) {
nodes[type] = function () {
return amounts;
};
});
[type as string]
.concat(t.FLIPPED_ALIAS_KEYS[type] || [])
.forEach(function (type) {
nodes[type] = function () {
return amounts;
};
});
});

View File

@ -3,6 +3,7 @@ import * as n from "./node";
import * as t from "@babel/types";
import * as generatorFunctions from "./generators";
import type SourceMap from "./source-map";
const SCIENTIFIC_NOTATION = /e/i;
const ZERO_DECIMAL_INTEGER = /\.0+$/;
@ -10,26 +11,29 @@ const NON_DECIMAL_LITERAL = /^0[box]/;
const PURE_ANNOTATION_RE = /^\s*[@#]__PURE__\s*$/;
export type Format = {
shouldPrintComment: (comment: string) => boolean,
retainLines: boolean,
retainFunctionParens: boolean,
comments: boolean,
auxiliaryCommentBefore: string,
auxiliaryCommentAfter: string,
compact: boolean | "auto",
minified: boolean,
concise: boolean,
shouldPrintComment: (comment: string) => boolean;
retainLines: boolean;
retainFunctionParens: boolean;
comments: boolean;
auxiliaryCommentBefore: string;
auxiliaryCommentAfter: string;
compact: boolean | "auto";
minified: boolean;
concise: boolean;
indent: {
adjustMultilineComment: boolean,
style: string,
base: number,
},
decoratorsBeforeExport: boolean,
adjustMultilineComment: boolean;
style: string;
base: number;
};
decoratorsBeforeExport: boolean;
recordAndTupleSyntaxType: "bar" | "hash";
jsescOption;
jsonCompatibleStrings?;
};
export default class Printer {
constructor(format, map) {
this.format = format || {};
class Printer {
constructor(format: Format, map: SourceMap) {
this.format = format;
this._buf = new Buffer(map);
}
@ -37,14 +41,14 @@ export default class Printer {
inForStatementInitCounter: number = 0;
declare _buf: Buffer;
_printStack: Array<Node> = [];
_printStack: Array<t.Node> = [];
_indent: number = 0;
_insideAux: boolean = false;
_printedCommentStarts: Object = {};
_parenPushNewlineState: ?Object = null;
_printedCommentStarts: any = {};
_parenPushNewlineState: any = null;
_noLineTerminator: boolean = false;
_printAuxAfterOnNextUserNode: boolean = false;
_printedComments: WeakSet = new WeakSet();
_printedComments: WeakSet<any> = new WeakSet();
_endsWithInteger = false;
_endsWithWord = false;
@ -199,19 +203,19 @@ export default class Printer {
this._buf.removeTrailingNewline();
}
exactSource(loc: Object, cb: () => void) {
exactSource(loc: any, cb: () => void) {
this._catchUp("start", loc);
this._buf.exactSource(loc, cb);
}
source(prop: string, loc: Object): void {
source(prop: string, loc: any): void {
this._catchUp(prop, loc);
this._buf.source(prop, loc);
}
withSource(prop: string, loc: Object, cb: () => void): void {
withSource(prop: string, loc: any, cb: () => void): void {
this._catchUp(prop, loc);
this._buf.withSource(prop, loc, cb);
@ -303,7 +307,7 @@ export default class Printer {
parenPushNewlineState.printed = true;
}
_catchUp(prop: string, loc: Object) {
_catchUp(prop: string, loc: any) {
if (!this.format.retainLines) return;
// catch up to this nodes newline if we're behind
@ -341,7 +345,7 @@ export default class Printer {
* `undefined` will be returned and not `foo` due to the terminator.
*/
startTerminatorless(isLabel: boolean = false): Object {
startTerminatorless(isLabel: boolean = false): any {
if (isLabel) {
this._noLineTerminator = true;
return null;
@ -356,7 +360,7 @@ export default class Printer {
* Print an ending parentheses if a starting one has been printed.
*/
endTerminatorless(state: Object) {
endTerminatorless(state?: any) {
this._noLineTerminator = false;
if (state?.printed) {
this.dedent();
@ -365,7 +369,7 @@ export default class Printer {
}
}
print(node, parent) {
print(node, parent?) {
if (!node) return;
const oldConcise = this.format.concise;
@ -417,7 +421,7 @@ export default class Printer {
this._insideAux = oldInAux;
}
_maybeAddAuxComment(enteredPositionlessNode) {
_maybeAddAuxComment(enteredPositionlessNode?) {
if (enteredPositionlessNode) this._printAuxBeforeComment();
if (!this._insideAux) this._printAuxAfterComment();
}
@ -460,7 +464,7 @@ export default class Printer {
}
}
printJoin(nodes: ?Array, parent: Object, opts = {}) {
printJoin(nodes: Array<any> | undefined | null, parent: any, opts: any = {}) {
if (!nodes?.length) return;
if (opts.indent) this.indent();
@ -527,12 +531,24 @@ export default class Printer {
if (indent) this.dedent();
}
printSequence(nodes, parent, opts = {}) {
printSequence(
nodes,
parent,
opts: {
statement?: boolean;
indent?: boolean;
addNewlines?: Function;
} = {},
) {
opts.statement = true;
return this.printJoin(nodes, parent, opts);
}
printList(items, parent, opts = {}) {
printList(
items,
parent,
opts: { separator?: Function; indent?: boolean; statement?: boolean } = {},
) {
if (opts.separator == null) {
opts.separator = commaSeparator;
}
@ -627,7 +643,7 @@ export default class Printer {
if (printNewLines) this.newline(1);
}
_printComments(comments?: Array<Object>, inlinePureAnnotation?: boolean) {
_printComments(comments?: Array<any>, inlinePureAnnotation?: boolean) {
if (!comments?.length) return;
if (
@ -646,8 +662,8 @@ export default class Printer {
}
}
}
printAssertions(node: Node) {
// todo(flow->ts): was Node
printAssertions(node) {
if (node.assertions?.length) {
this.space();
this.word("assert");
@ -664,6 +680,10 @@ export default class Printer {
// Expose the node type functions and helpers on the prototype for easy usage.
Object.assign(Printer.prototype, generatorFunctions);
type GeneratorFunctions = typeof generatorFunctions;
interface Printer extends GeneratorFunctions {}
export default Printer;
function commaSeparator() {
this.token(",");
this.space();

View File

@ -5,6 +5,13 @@ import sourceMap from "source-map";
*/
export default class SourceMap {
private _cachedMap: sourceMap.SourceMapGenerator | null;
private _code: any;
private _opts: any;
private _rawMappings: any[];
private _lastGenLine: number;
private _lastSourceLine: number;
private _lastSourceColumn: number;
constructor(opts, code) {
this._cachedMap = null;
this._code = code;
@ -57,8 +64,8 @@ export default class SourceMap {
generatedColumn: number,
line: number,
column: number,
identifierName: ?string,
filename: ?string,
identifierName?: string | null,
filename?: string | null,
force?: boolean,
) {
// Adding an empty mapping at the start of a generated line just clutters the map.

View File

@ -251,6 +251,9 @@ __metadata:
"@babel/helper-fixtures": "workspace:*"
"@babel/parser": "workspace:*"
"@babel/types": "workspace:^7.12.11"
"@types/jsesc": ^2.5.0
"@types/lodash": ^4.14.150
"@types/source-map": ^0.5.0
jsesc: "condition: BABEL_8_BREAKING ? ^3.0.2 : ^2.5.1"
source-map: ^0.5.0
languageName: unknown
@ -3906,6 +3909,13 @@ __metadata:
languageName: node
linkType: hard
"@types/jsesc@npm:^2.5.0":
version: 2.5.1
resolution: "@types/jsesc@npm:2.5.1"
checksum: c4df356ce6b1f2af847f9b059075b879c15a7834ce4387c8d5e5cebc24d1173abae5d19c07160d24f74c6e7413ee312a66ce3ce965d0544278d2c16b218306e1
languageName: node
linkType: hard
"@types/json-schema@npm:^7.0.3":
version: 7.0.4
resolution: "@types/json-schema@npm:7.0.4"
@ -3920,10 +3930,10 @@ __metadata:
languageName: node
linkType: hard
"@types/lodash@npm:^4.14.162":
version: 4.14.165
resolution: "@types/lodash@npm:4.14.165"
checksum: 525bfc34b0b591cc957125a961c70e63e5ad8b23cbd89b7594a5ea74823285b6d96993a7eec506e26b379ee52dc9dcd3a894ff210be4c97bccb536e62361dbc8
"@types/lodash@npm:^4.14.150, @types/lodash@npm:^4.14.162":
version: 4.14.168
resolution: "@types/lodash@npm:4.14.168"
checksum: 9a4e25f89fc035b9f0388f1f7be85e5eff49f9e6db0d93432c9a89fce0916f8a89db4e8290415f7ea02de6b00d3573826378dcb655b7b2d20530a6e8d6dd6fd0
languageName: node
linkType: hard
@ -3964,6 +3974,13 @@ __metadata:
languageName: node
linkType: hard
"@types/source-map@npm:^0.5.0":
version: 0.5.2
resolution: "@types/source-map@npm:0.5.2"
checksum: 228e1ef7c7f9c126cf38afdef2c3ccfb1224523c3692da6148abb9bb81095269645495773e94477e8512e1f652419b471cc8c30997f6bd222185e931f6d97acc
languageName: node
linkType: hard
"@types/stack-utils@npm:^2.0.0":
version: 2.0.0
resolution: "@types/stack-utils@npm:2.0.0"