From 12dfde1fcef0380db34864f1b2cc0d339a976220 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 2 Feb 2026 22:18:20 +0800 Subject: [PATCH] Add `printSemicolon` (#18841) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/language-js/print/class-body.js | 6 ++++-- src/language-js/print/class.js | 3 ++- src/language-js/print/component.js | 6 +++--- src/language-js/print/do-while-statement.js | 7 +++++-- src/language-js/print/estree.js | 12 +++++++---- src/language-js/print/flow.js | 12 +++++++---- src/language-js/print/function.js | 6 +++--- src/language-js/print/hook.js | 20 +++++++------------ src/language-js/print/miscellaneous.js | 5 +++++ src/language-js/print/module-declaration.js | 4 ++-- src/language-js/print/module.js | 15 ++++++++------ src/language-js/print/opaque-type.js | 4 ++-- src/language-js/print/return-statement.js | 9 +++++---- src/language-js/print/type-alias.js | 4 ++-- src/language-js/print/typescript.js | 7 ++++--- src/language-js/print/variable-declaration.js | 6 ++++-- 16 files changed, 73 insertions(+), 53 deletions(-) diff --git a/src/language-js/print/class-body.js b/src/language-js/print/class-body.js index db66ee7c0..8fab3e45d 100644 --- a/src/language-js/print/class-body.js +++ b/src/language-js/print/class-body.js @@ -19,7 +19,7 @@ import { import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import { isNextLineEmpty } from "../utilities/is-next-line-empty.js"; import { shouldHugTheOnlyParameter } from "./function-parameters.js"; -import { printTrailingComma } from "./miscellaneous.js"; +import { printSemicolon, printTrailingComma } from "./miscellaneous.js"; /* - `ClassBody` @@ -177,7 +177,9 @@ function printClassMemberSemicolon(path, options) { const { parent } = path; if (path.callParent(isClassBody)) { - return options.semi || parent.type === "ObjectTypeAnnotation" ? ";" : ""; + return parent.type === "ObjectTypeAnnotation" + ? ";" + : printSemicolon(options); } if (parent.type === "TSTypeLiteral") { diff --git a/src/language-js/print/class.js b/src/language-js/print/class.js index 061f6abeb..f06ad92c7 100644 --- a/src/language-js/print/class.js +++ b/src/language-js/print/class.js @@ -29,6 +29,7 @@ import { printDeclareToken, printDefiniteToken, printOptionalToken, + printSemicolon, printTypeScriptAccessibilityToken, } from "./miscellaneous.js"; import { printTypeAnnotationProperty } from "./type-annotation.js"; @@ -362,7 +363,7 @@ function printClassProperty(path, options, print) { " =", isAbstractProperty ? undefined : "value", ), - options.semi ? ";" : "", + printSemicolon(options), ]; } diff --git a/src/language-js/print/component.js b/src/language-js/print/component.js index 8cb5861d4..4901aed67 100644 --- a/src/language-js/print/component.js +++ b/src/language-js/print/component.js @@ -1,6 +1,6 @@ import { group } from "../../document/index.js"; import { printFunctionParameters } from "./function-parameters.js"; -import { printDeclareToken } from "./miscellaneous.js"; +import { printDeclareToken, printSemicolon } from "./miscellaneous.js"; /** * @import AstPath from "../../common/ast-path.js" @@ -33,8 +33,8 @@ function printComponent(path, options, print) { parts.push(" ", print("body")); } - if (options.semi && node.type === "DeclareComponent") { - parts.push(";"); + if (node.type === "DeclareComponent") { + parts.push(printSemicolon(options)); } return parts; diff --git a/src/language-js/print/do-while-statement.js b/src/language-js/print/do-while-statement.js index adae9d416..45d52b2b6 100644 --- a/src/language-js/print/do-while-statement.js +++ b/src/language-js/print/do-while-statement.js @@ -1,6 +1,9 @@ import { group, hardline } from "../../document/index.js"; import { printDoWhileStatementBody } from "./clause.js"; -import { printDoWhileStatementCondition } from "./miscellaneous.js"; +import { + printDoWhileStatementCondition, + printSemicolon, +} from "./miscellaneous.js"; function printDoWhileStatement(path, options, print) { return [ @@ -9,7 +12,7 @@ function printDoWhileStatement(path, options, print) { "while (", printDoWhileStatementCondition(path, options, print), ")", - options.semi ? ";" : "", + printSemicolon(options), ]; } diff --git a/src/language-js/print/estree.js b/src/language-js/print/estree.js index 300bafc9f..e0bfd9986 100644 --- a/src/language-js/print/estree.js +++ b/src/language-js/print/estree.js @@ -41,7 +41,11 @@ import { printHtmlBinding } from "./html-binding.js"; import { printIfStatement } from "./if-statement.js"; import { printLiteral } from "./literal.js"; import { printMemberExpression } from "./member.js"; -import { printDefiniteToken, printOptionalToken } from "./miscellaneous.js"; +import { + printDefiniteToken, + printOptionalToken, + printSemicolon, +} from "./miscellaneous.js"; import { printExportDeclaration, printImportDeclaration, @@ -218,7 +222,7 @@ function printEstree(path, options, print, args) { case "Super": return "super"; case "Directive": - return [print("value"), options.semi ? ";" : ""]; + return [print("value"), printSemicolon(options)]; case "UnaryExpression": { const parts = [node.operator]; @@ -269,7 +273,7 @@ function printEstree(path, options, print, args) { return [ node.type === "BreakStatement" ? "break" : "continue", node.label ? [" ", print("label")] : "", - options.semi ? ";" : "", + printSemicolon(options), ]; case "LabeledStatement": return [ @@ -286,7 +290,7 @@ function printEstree(path, options, print, args) { case "SwitchCase": return printSwitchCase(path, options, print); case "DebuggerStatement": - return ["debugger", options.semi ? ";" : ""]; + return ["debugger", printSemicolon(options)]; case "ClassDeclaration": case "ClassExpression": diff --git a/src/language-js/print/flow.js b/src/language-js/print/flow.js index 5dcc30895..b0a459429 100644 --- a/src/language-js/print/flow.js +++ b/src/language-js/print/flow.js @@ -35,7 +35,11 @@ import { printKey } from "./key.js"; import { printBigInt } from "./literal.js"; import { printFlowMappedTypeProperty } from "./mapped-type.js"; import { printMatch, printMatchCase, printMatchPattern } from "./match.js"; -import { printDeclareToken, printOptionalToken } from "./miscellaneous.js"; +import { + printDeclareToken, + printOptionalToken, + printSemicolon, +} from "./miscellaneous.js"; import { printExportDeclaration } from "./module.js"; import { printObject } from "./object.js"; import { printOpaqueType } from "./opaque-type.js"; @@ -82,7 +86,7 @@ function printFlow(path, options, print, args) { "function ", print("id"), print("predicate"), - options.semi ? ";" : "", + printSemicolon(options), ]; case "DeclareModule": return ["declare module ", print("id"), " ", print("body")]; @@ -90,7 +94,7 @@ function printFlow(path, options, print, args) { return [ "declare module.exports", printTypeAnnotationProperty(path, print), - options.semi ? ";" : "", + printSemicolon(options), ]; case "DeclareNamespace": return ["declare namespace ", print("id"), " ", print("body")]; @@ -101,7 +105,7 @@ function printFlow(path, options, print, args) { node.kind ?? "var", " ", print("id"), - options.semi ? ";" : "", + printSemicolon(options), ]; case "DeclareExportDeclaration": case "DeclareExportAllDeclaration": diff --git a/src/language-js/print/function.js b/src/language-js/print/function.js index 92edc8098..42fc7e89e 100644 --- a/src/language-js/print/function.js +++ b/src/language-js/print/function.js @@ -11,7 +11,7 @@ import { shouldGroupFunctionParameters, } from "./function-parameters.js"; import { printKey } from "./key.js"; -import { printDeclareToken } from "./miscellaneous.js"; +import { printDeclareToken, printSemicolon } from "./miscellaneous.js"; import { printTypeAnnotationProperty } from "./type-annotation.js"; /** @@ -86,7 +86,7 @@ function printFunction(path, options, print, args) { ]), node.body ? " " : "", print("body"), - options.semi && (node.declare || !node.body) ? ";" : "", + node.declare || !node.body ? printSemicolon(options) : "", ]; } @@ -168,7 +168,7 @@ function printMethodValue(path, options, print) { if (node.body) { parts.push(" ", print("body")); } else { - parts.push(options.semi ? ";" : ""); + parts.push(printSemicolon(options)); } return parts; diff --git a/src/language-js/print/hook.js b/src/language-js/print/hook.js index 2a902052a..3ca7de15c 100644 --- a/src/language-js/print/hook.js +++ b/src/language-js/print/hook.js @@ -3,7 +3,7 @@ import { printFunctionParameters, shouldGroupFunctionParameters, } from "./function-parameters.js"; -import { printDeclareToken } from "./miscellaneous.js"; +import { printDeclareToken, printSemicolon } from "./miscellaneous.js"; /** * @import AstPath from "../../common/ast-path.js" @@ -14,18 +14,12 @@ import { printDeclareToken } from "./miscellaneous.js"; - "DeclareHook" */ function printDeclareHook(path, options, print) { - const { node } = path; - - const parts = [printDeclareToken(path), "hook"]; - if (node.id) { - parts.push(" ", print("id")); - } - - if (options.semi) { - parts.push(";"); - } - - return parts; + return [ + printDeclareToken(path), + "hook", + path.node.id ? [" ", print("id")] : "", + printSemicolon(options), + ]; } /* diff --git a/src/language-js/print/miscellaneous.js b/src/language-js/print/miscellaneous.js index f681765bd..1d916617b 100644 --- a/src/language-js/print/miscellaneous.js +++ b/src/language-js/print/miscellaneous.js @@ -196,6 +196,10 @@ function printTrailingComma(options, level = "es5") { return shouldPrintTrailingComma(options, level) ? ifBreak(",") : ""; } +function printSemicolon(options) { + return options.semi ? ";" : ""; +} + export { printAbstractToken, printDanglingCommentsInList, @@ -204,6 +208,7 @@ export { printIfOrWhileConditionOrWithStatementObject as printDoWhileStatementCondition, printIfOrWhileConditionOrWithStatementObject as printIfStatementCondition, printOptionalToken, + printSemicolon, printTrailingComma, printTypeScriptAccessibilityToken, printIfOrWhileConditionOrWithStatementObject as printWhileStatementCondition, diff --git a/src/language-js/print/module-declaration.js b/src/language-js/print/module-declaration.js index 1a7b4d4b0..a4e84c5bd 100644 --- a/src/language-js/print/module-declaration.js +++ b/src/language-js/print/module-declaration.js @@ -1,5 +1,5 @@ import { group } from "../../document/index.js"; -import { printDeclareToken } from "./miscellaneous.js"; +import { printDeclareToken, printSemicolon } from "./miscellaneous.js"; function printModuleDeclaration(path, options, print) { const { node } = path; @@ -8,7 +8,7 @@ function printModuleDeclaration(path, options, print) { printDeclareToken(path), node.kind === "global" ? "" : `${node.kind} `, print("id"), - node.body ? [" ", group(print("body"))] : options.semi ? ";" : "", + node.body ? [" ", group(print("body"))] : printSemicolon(options), ]; } diff --git a/src/language-js/print/module.js b/src/language-js/print/module.js index c7c68e3f6..b62798f92 100644 --- a/src/language-js/print/module.js +++ b/src/language-js/print/module.js @@ -18,7 +18,11 @@ import { needsHardlineAfterDanglingComment } from "../utilities/needs-hardline-a import { isStringLiteral } from "../utilities/node-types.js"; import { stripComments } from "../utilities/strip-comments.js"; import { printDecoratorsBeforeExport } from "./decorators.js"; -import { printDeclareToken, printTrailingComma } from "./miscellaneous.js"; +import { + printDeclareToken, + printSemicolon, + printTrailingComma, +} from "./miscellaneous.js"; import { printObject } from "./object.js"; /** @@ -38,7 +42,7 @@ function printImportDeclaration(path, options, print) { printModuleSpecifiers(path, options, print), printModuleSource(path, options, print), printImportAttributes(path, options, print), - options.semi ? ";" : "", + printSemicolon(options), ]; } @@ -117,11 +121,10 @@ const shouldOmitSemicolon = createTypeCheckFunction([ ]); function printSemicolonAfterExportDeclaration(node, options) { if ( - options.semi && - (!node.declaration || - (isDefaultExport(node) && !shouldOmitSemicolon(node.declaration))) + !node.declaration || + (isDefaultExport(node) && !shouldOmitSemicolon(node.declaration)) ) { - return ";"; + return printSemicolon(options); } return ""; diff --git a/src/language-js/print/opaque-type.js b/src/language-js/print/opaque-type.js index d6d65e794..72def5c9b 100644 --- a/src/language-js/print/opaque-type.js +++ b/src/language-js/print/opaque-type.js @@ -1,5 +1,5 @@ import { group, indent, line } from "../../document/index.js"; -import { printDeclareToken } from "./miscellaneous.js"; +import { printDeclareToken, printSemicolon } from "./miscellaneous.js"; /* - `DeclareOpaqueType`(flow) @@ -37,7 +37,7 @@ function printOpaqueType(path, options, print) { parts.push(" = ", print("impltype")); } - parts.push(options.semi ? ";" : ""); + parts.push(printSemicolon(options)); return parts; } diff --git a/src/language-js/print/return-statement.js b/src/language-js/print/return-statement.js index bc246d4f3..a2efd77fc 100644 --- a/src/language-js/print/return-statement.js +++ b/src/language-js/print/return-statement.js @@ -9,6 +9,7 @@ import { printDanglingComments } from "../../main/comments/print.js"; import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import { isBinaryish } from "../utilities/node-types.js"; import { returnArgumentHasLeadingComment } from "../utilities/return-statement-has-leading-comment.js"; +import { printSemicolon } from "./miscellaneous.js"; /** @import {Doc} from "../../document/index.js"; @@ -58,20 +59,20 @@ function printReturnOrThrowStatement(path, options, print) { const hasDanglingComments = hasComment(node, CommentCheckFlags.Dangling); const shouldPrintSemiBeforeComments = - options.semi && hasDanglingComments && hasComment(node, CommentCheckFlags.Last | CommentCheckFlags.Line); if (shouldPrintSemiBeforeComments) { - parts.push(";"); + parts.push(printSemicolon(options)); } + // TODO[@fisker]: should able to remove this after we exclude `;` from range if (hasDanglingComments) { parts.push(" ", printDanglingComments(path, options)); } - if (!shouldPrintSemiBeforeComments && options.semi) { - parts.push(";"); + if (!shouldPrintSemiBeforeComments) { + parts.push(printSemicolon(options)); } return parts; diff --git a/src/language-js/print/type-alias.js b/src/language-js/print/type-alias.js index 01f26809e..e3f9c1315 100644 --- a/src/language-js/print/type-alias.js +++ b/src/language-js/print/type-alias.js @@ -1,5 +1,5 @@ import { printAssignment } from "./assignment.js"; -import { printDeclareToken } from "./miscellaneous.js"; +import { printDeclareToken, printSemicolon } from "./miscellaneous.js"; /* - `DeclareTypeAlias`(flow) @@ -19,7 +19,7 @@ function printTypeAlias(path, options, print) { node.type === "TSTypeAliasDeclaration" ? "typeAnnotation" : "right"; return [ printAssignment(path, options, print, parts, " =", rightPropertyName), - options.semi ? ";" : "", + printSemicolon(options), ]; } diff --git a/src/language-js/print/typescript.js b/src/language-js/print/typescript.js index 61b3d6b8b..650ff7386 100644 --- a/src/language-js/print/typescript.js +++ b/src/language-js/print/typescript.js @@ -25,6 +25,7 @@ import { printTypeScriptMappedType } from "./mapped-type.js"; import { printMethodSignature } from "./method-signature.js"; import { printOptionalToken, + printSemicolon, printTypeScriptAccessibilityToken, } from "./miscellaneous.js"; import { printImportKind } from "./module.js"; @@ -67,7 +68,7 @@ function printTypescript(path, options, print, args) { case "TSDeclareFunction": return printFunction(path, options, print); case "TSExportAssignment": - return ["export = ", print("expression"), options.semi ? ";" : ""]; + return ["export = ", print("expression"), printSemicolon(options)]; case "TSModuleBlock": return printBlock(path, options, print); case "TSInterfaceBody": @@ -156,7 +157,7 @@ function printTypescript(path, options, print, args) { return printMethodSignature(path, options, print); case "TSNamespaceExportDeclaration": - return ["export as namespace ", print("id"), options.semi ? ";" : ""]; + return ["export as namespace ", print("id"), printSemicolon(options)]; case "TSEnumDeclaration": return printEnumDeclaration(path, print); case "TSEnumBody": @@ -171,7 +172,7 @@ function printTypescript(path, options, print, args) { print("id"), " = ", print("moduleReference"), - options.semi ? ";" : "", + printSemicolon(options), ]; case "TSExternalModuleReference": return printCallExpression(path, options, print); diff --git a/src/language-js/print/variable-declaration.js b/src/language-js/print/variable-declaration.js index acf2e03f6..40c394d5a 100644 --- a/src/language-js/print/variable-declaration.js +++ b/src/language-js/print/variable-declaration.js @@ -1,6 +1,6 @@ import { group, hardline, indent, line } from "../../document/index.js"; import { hasComment } from "../utilities/comments.js"; -import { printDeclareToken } from "./miscellaneous.js"; +import { printDeclareToken, printSemicolon } from "./miscellaneous.js"; function printVariableDeclaration(path, options, print) { const { node } = path; @@ -34,7 +34,9 @@ function printVariableDeclaration(path, options, print) { .slice(1) .map((p) => [",", hasValue && !isParentForLoop ? hardline : line, p]), ), - options.semi && !(isParentForLoop && parentNode.body !== node) ? ";" : "", + !(isParentForLoop && parentNode.body !== node) + ? printSemicolon(options) + : "", ]); }