From 27f6e8bdbbe5ae4210658bfaf8ae6d4fac031c71 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 22 Dec 2022 09:28:21 +0800 Subject: [PATCH] Refactor enum declaration print (#14037) --- src/language-js/print/enum-members.js | 35 ------- src/language-js/print/enum.js | 135 ++++++++++++++++++++++++++ src/language-js/print/flow.js | 47 +++------ src/language-js/print/typescript.js | 23 +---- 4 files changed, 150 insertions(+), 90 deletions(-) delete mode 100644 src/language-js/print/enum-members.js create mode 100644 src/language-js/print/enum.js diff --git a/src/language-js/print/enum-members.js b/src/language-js/print/enum-members.js deleted file mode 100644 index c42b1ed0d..000000000 --- a/src/language-js/print/enum-members.js +++ /dev/null @@ -1,35 +0,0 @@ -import { hardline, softline, group, indent } from "../../document/builders.js"; -import { printDanglingComments } from "../../main/comments.js"; -import { shouldPrintComma } from "../utils/index.js"; -import { printArrayItems } from "./array.js"; - -function printEnumMemberList(path, print, options) { - const { - node: { members, hasUnknownMembers }, - } = path; - - if (members.length === 0 && !hasUnknownMembers) { - return [printDanglingComments(path, options), softline]; - } - - return [ - indent([ - ...(members.length > 0 - ? [ - hardline, - printArrayItems(path, options, "members", print), - hasUnknownMembers || shouldPrintComma(options) ? "," : "", - ] - : []), - ...(hasUnknownMembers ? [hardline, "..."] : []), - ]), - printDanglingComments(path, options, /* sameIndent */ true), - hardline, - ]; -} - -function printEnumMembers(path, print, options) { - return group(["{", printEnumMemberList(path, print, options), "}"]); -} - -export default printEnumMembers; diff --git a/src/language-js/print/enum.js b/src/language-js/print/enum.js new file mode 100644 index 000000000..8202654f8 --- /dev/null +++ b/src/language-js/print/enum.js @@ -0,0 +1,135 @@ +import { hardline, softline, group, indent } from "../../document/builders.js"; +import { printDanglingComments } from "../../main/comments.js"; +import { shouldPrintComma } from "../utils/index.js"; +import { printArrayItems } from "./array.js"; +import { printTypeScriptModifiers } from "./misc.js"; + +function printEnumMemberList(path, print, options) { + const { + node: { members, hasUnknownMembers }, + } = path; + + if (members.length === 0 && !hasUnknownMembers) { + return [printDanglingComments(path, options), softline]; + } + + return [ + indent([ + ...(members.length > 0 + ? [ + hardline, + printArrayItems(path, options, "members", print), + hasUnknownMembers || shouldPrintComma(options) ? "," : "", + ] + : []), + ...(hasUnknownMembers ? [hardline, "..."] : []), + ]), + printDanglingComments(path, options, /* sameIndent */ true), + hardline, + ]; +} + +function printEnumMembers(path, print, options) { + return group(["{", printEnumMemberList(path, print, options), "}"]); +} + +/* +- `EnumBooleanMember`(flow) +- `EnumNumberMember`(flow) +- `EnumStringMember`(flow) +- `EnumDefaultedMember`(flow) +- `TSEnumMember`(TypeScript) +*/ +function printEnumMember(path, print) { + const { node } = path; + + let idDoc = print("id"); + + if (node.computed) { + idDoc = ["[", idDoc, "]"]; + } + + let initializerDoc = ""; + + // `TSEnumMember` + if (node.initializer) { + initializerDoc = print("initializer"); + } + + // Flow + if (node.init) { + initializerDoc = print("init"); + } + + if (!initializerDoc) { + return idDoc; + } + + return [idDoc, " = ", initializerDoc]; +} + +/* +- `EnumBooleanBody`(flow) +- `EnumNumberBody`(flow) +- `EnumStringBody`(flow) +- `EnumSymbolBody`(flow) +*/ +function printEnumBody(path, print, options) { + const { node } = path; + let type; + + if (node.type === "EnumSymbolBody" || node.explicitType) { + switch (node.type) { + case "EnumBooleanBody": + type = "boolean"; + break; + case "EnumNumberBody": + type = "number"; + break; + case "EnumStringBody": + type = "string"; + break; + case "EnumSymbolBody": + type = "symbol"; + break; + } + } + + return [type ? `of ${type} ` : "", printEnumMembers(path, print, options)]; +} + +/* +- `DeclareEnum`(flow) +- `EnumDeclaration`(flow) +- `TSEnumDeclaration`(TypeScript) +*/ +function printEnumDeclaration(path, print, options) { + const { node } = path; + const parts = []; + + if ( + node.declare || + (node.type === "DeclareEnum" && + path.parent.type !== "DeclareExportDeclaration") + ) { + parts.push("declare "); + } + + parts.push(printTypeScriptModifiers(path, options, print)); + + if (node.const) { + parts.push("const "); + } + + parts.push("enum ", print("id"), " "); + + if (node.type === "TSEnumDeclaration") { + parts.push(printEnumMembers(path, print, options)); + } else { + parts.push(print("body")); + } + + return parts; +} + +export { printEnumDeclaration, printEnumMember, printEnumBody }; diff --git a/src/language-js/print/flow.js b/src/language-js/print/flow.js index 93ccf3a50..8a671de69 100644 --- a/src/language-js/print/flow.js +++ b/src/language-js/print/flow.js @@ -24,7 +24,11 @@ import { printExportDeclaration, printExportAllDeclaration } from "./module.js"; import { printTupleType } from "./array.js"; import { printObject } from "./object.js"; import { printPropertyKey } from "./property.js"; -import printEnumMembers from "./enum-members.js"; +import { + printEnumDeclaration, + printEnumBody, + printEnumMember, +} from "./enum.js"; import { printBigInt } from "./literal.js"; import { printOptionalToken, @@ -105,52 +109,23 @@ function printFlow(path, options, print) { return [print("elementType"), "[]"]; case "BooleanLiteralTypeAnnotation": return String(node.value); + case "DeclareEnum": case "EnumDeclaration": - return [ - node.type === "DeclareEnum" && - path.parent.type !== "DeclareExportDeclaration" - ? "declare " - : "", - "enum ", - print("id"), - " ", - print("body"), - ]; + return printEnumDeclaration(path, print, options); case "EnumBooleanBody": case "EnumNumberBody": case "EnumStringBody": - case "EnumSymbolBody": { - let type; - if (node.type === "EnumSymbolBody" || node.explicitType) { - switch (node.type) { - case "EnumBooleanBody": - type = "boolean"; - break; - case "EnumNumberBody": - type = "number"; - break; - case "EnumStringBody": - type = "string"; - break; - case "EnumSymbolBody": - type = "symbol"; - break; - } - } - return [ - type ? `of ${type} ` : "", - printEnumMembers(path, print, options), - ]; - } + case "EnumSymbolBody": + return printEnumBody(path, print, options); case "EnumBooleanMember": case "EnumNumberMember": case "EnumStringMember": - return [print("id"), " = ", print("init")]; case "EnumDefaultedMember": - return print("id"); + return printEnumMember(path, print); + case "FunctionTypeParam": { const name = node.name ? print("name") diff --git a/src/language-js/print/typescript.js b/src/language-js/print/typescript.js index d64d0b371..e2d6585d3 100644 --- a/src/language-js/print/typescript.js +++ b/src/language-js/print/typescript.js @@ -43,7 +43,7 @@ import { printIndexedAccessType, printJSDocType, } from "./type-annotation.js"; -import printEnumMembers from "./enum-members.js"; +import { printEnumDeclaration, printEnumMember } from "./enum.js"; function printTypescript(path, options, print) { const { node } = path; @@ -361,26 +361,11 @@ function printTypescript(path, options, print) { return group(parts); case "TSEnumDeclaration": - return [ - node.declare ? "declare " : "", - printTypeScriptModifiers(path, options, print), - node.const ? "const " : "", - "enum ", - print("id"), - " ", - printEnumMembers(path, print, options), - ]; + return printEnumDeclaration(path, print, options); + case "TSEnumMember": - if (node.computed) { - parts.push("[", print("id"), "]"); - } else { - parts.push(print("id")); - } + return printEnumMember(path, print); - if (node.initializer) { - parts.push(" = ", print("initializer")); - } - return parts; case "TSImportEqualsDeclaration": if (node.isExport) { parts.push("export ");