convert @babel/generator to TypeScript (#12487)

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
Bogdan Savluk
2021-01-27 19:21:07 +01:00
committed by GitHub
parent 45fdde0ce2
commit 9ac36b136a
23 changed files with 982 additions and 513 deletions

View File

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

View File

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

View File

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