convert @babel/generator to TypeScript (#12487)
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
parent
45fdde0ce2
commit
9ac36b136a
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
@ -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("%%");
|
||||
@ -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("{");
|
||||
@ -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);
|
||||
}
|
||||
@ -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");
|
||||
}
|
||||
@ -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(">");
|
||||
}
|
||||
@ -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();
|
||||
@ -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");
|
||||
@ -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();
|
||||
@ -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++) {
|
||||
@ -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("#");
|
||||
}
|
||||
@ -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();
|
||||
@ -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();
|
||||
}
|
||||
246
packages/babel-generator/src/index.ts
Normal file
246
packages/babel-generator/src/index.ts
Normal 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();
|
||||
}
|
||||
@ -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) {
|
||||
@ -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;
|
||||
@ -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;
|
||||
};
|
||||
});
|
||||
});
|
||||
@ -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();
|
||||
@ -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.
|
||||
25
yarn.lock
25
yarn.lock
@ -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"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user