diff --git a/eslint.config.js b/eslint.config.js index 5cd213d9d..b8cf75073 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -445,7 +445,7 @@ const configs = [ "prettier-internal-rules/no-node-comments": [ "error", { - file: "src/language-js/utilities/index.js", + file: "src/language-js/utilities/comments.js", functions: ["hasComment", "getComments"], }, "src/language-js/pragma.js", @@ -512,6 +512,12 @@ const configs = [ ], }, }, + { + files: ["src/language-js/utilities/utilities.js"], + rules: { + "unicorn/prefer-export-from": ["error", { ignoreUsedVariables: false }], + }, + }, ]; export default configs; diff --git a/src/language-js/comments/can-attach-comment.js b/src/language-js/comments/can-attach-comment.js index f08637ac6..f4ca1c492 100644 --- a/src/language-js/comments/can-attach-comment.js +++ b/src/language-js/comments/can-attach-comment.js @@ -1,12 +1,12 @@ import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; +import { isMeaningfulEmptyStatement } from "../utilities/is-meaningful-empty-statement.js"; import { - createTypeCheckFunction, getFunctionParameters, - isMeaningfulEmptyStatement, isMethod, isShorthandSpecifier, isTsAsConstExpression, -} from "../utilities/index.js"; +} from "../utilities/utilities.js"; /** @import {Node} from "../types/estree.js"; diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index 815a5fc6f..85693ab9a 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -10,17 +10,11 @@ import hasNewlineInRange from "../../utilities/has-newline-in-range.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; import { locEnd, locStart } from "../loc.js"; import { isInsideCallOrNewExpressionParentheses } from "../utilities/call-or-new-expression-parentheses.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import getTextWithoutComments from "../utilities/get-text-without-comments.js"; -import { - createTypeCheckFunction, - getCallArguments, - getFunctionParameters, - isMethod, - isObjectProperty, - isPrettierIgnoreComment, -} from "../utilities/index.js"; import isBlockComment from "../utilities/is-block-comment.js"; import isLineComment from "../utilities/is-line-comment.js"; +import { isPrettierIgnoreComment } from "../utilities/is-prettier-ignore-comment.js"; import isTypeCastComment from "../utilities/is-type-cast-comment.js"; import { isBinaryCastExpression, @@ -31,6 +25,12 @@ import { isMemberExpression, isUnionType, } from "../utilities/node-types.js"; +import { + getCallArguments, + getFunctionParameters, + isMethod, + isObjectProperty, +} from "../utilities/utilities.js"; /** @import {Node, Comment, NodeMap} from "../types/estree.js"; diff --git a/src/language-js/comments/will-print-own-comments.js b/src/language-js/comments/will-print-own-comments.js index 35a3c479a..d72256a17 100644 --- a/src/language-js/comments/will-print-own-comments.js +++ b/src/language-js/comments/will-print-own-comments.js @@ -1,11 +1,11 @@ -import { - createTypeCheckFunction, - hasNodeIgnoreComment, - isIifeCalleeOrTaggedTemplateExpressionTag, - shouldUnionTypePrintOwnComments, -} from "../utilities/index.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; +import { hasNodeIgnoreComment } from "../utilities/has-node-ignore-comment.js"; import { isJsxElement, isUnionType } from "../utilities/node-types.js"; import { shouldExpressionStatementPrintOwnComments } from "../utilities/should-expression-statement-print-own-comments.js"; +import { + isIifeCalleeOrTaggedTemplateExpressionTag, + shouldUnionTypePrintOwnComments, +} from "../utilities/utilities.js"; /** @import {Node} from "../types/estree.js"; diff --git a/src/language-js/embed/css.js b/src/language-js/embed/css.js index 0c3b901fa..f3171e760 100644 --- a/src/language-js/embed/css.js +++ b/src/language-js/embed/css.js @@ -8,7 +8,7 @@ import { } from "../../document/index.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; import { printTemplateExpressions } from "../print/template-literal.js"; -import isNodeMatches from "../utilities/is-node-matches.js"; +import { isNodeMatches } from "../utilities/is-node-matches.js"; import { isAngularComponentStyles } from "./utilities.js"; async function printEmbedCss(textToDoc, print, path, options) { diff --git a/src/language-js/embed/utilities.js b/src/language-js/embed/utilities.js index 1fb097ec9..bdc954976 100644 --- a/src/language-js/embed/utilities.js +++ b/src/language-js/embed/utilities.js @@ -1,9 +1,6 @@ -import { - CommentCheckFlags, - hasComment, - isObjectProperty, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import { isArrayExpression } from "../utilities/node-types.js"; +import { isObjectProperty } from "../utilities/utilities.js"; const angularComponentObjectExpressionPredicates = [ (node, name) => name === "properties" && node.type === "ObjectExpression", diff --git a/src/language-js/massage-ast/index.js b/src/language-js/massage-ast/index.js index dc65ebb25..4293b5064 100644 --- a/src/language-js/massage-ast/index.js +++ b/src/language-js/massage-ast/index.js @@ -1,4 +1,4 @@ -import { isMeaningfulEmptyStatement } from "../utilities/index.js"; +import { isMeaningfulEmptyStatement } from "../utilities/is-meaningful-empty-statement.js"; import { isArrayExpression, isBigIntLiteral, diff --git a/src/language-js/parentheses/chain-expression.js b/src/language-js/parentheses/chain-expression.js index a1828a68f..bb05ecd7f 100644 --- a/src/language-js/parentheses/chain-expression.js +++ b/src/language-js/parentheses/chain-expression.js @@ -1,4 +1,4 @@ -import { createTypeCheckFunction } from "../utilities/index.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; /** @import AstPath from "../../common/ast-path.js" diff --git a/src/language-js/parentheses/identifier.js b/src/language-js/parentheses/identifier.js index 1a3ec0678..55306f019 100644 --- a/src/language-js/parentheses/identifier.js +++ b/src/language-js/parentheses/identifier.js @@ -1,5 +1,5 @@ -import { startsWithNoLookaheadToken } from "../utilities/index.js"; import { isBinaryCastExpression } from "../utilities/node-types.js"; +import { startsWithNoLookaheadToken } from "../utilities/utilities.js"; function shouldAddParenthesesToIdentifier(path) { const { node } = path; diff --git a/src/language-js/parentheses/needs-parentheses.js b/src/language-js/parentheses/needs-parentheses.js index 28e70cfe3..4a8a9652f 100644 --- a/src/language-js/parentheses/needs-parentheses.js +++ b/src/language-js/parentheses/needs-parentheses.js @@ -1,14 +1,5 @@ -import { - createTypeCheckFunction, - getFunctionParameters, - getPrecedence, - hasComment, - isBitwiseOperator, - isNullishCoalescing, - isObjectProperty, - shouldFlatten, - startsWithNoLookaheadToken, -} from "../utilities/index.js"; +import { hasComment } from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import { isArrayExpression, isBinaryCastExpression, @@ -22,6 +13,15 @@ import { isReturnOrThrowStatement, isUnionType, } from "../utilities/node-types.js"; +import { + getFunctionParameters, + getPrecedence, + isBitwiseOperator, + isNullishCoalescing, + isObjectProperty, + shouldFlatten, + startsWithNoLookaheadToken, +} from "../utilities/utilities.js"; import { shouldAddParenthesesToChainElement } from "./chain-expression.js"; import { shouldAddParenthesesToIdentifier } from "./identifier.js"; import { parentNeedsParentheses } from "./parent-needs-parentheses.js"; diff --git a/src/language-js/parentheses/parent-needs-parentheses.js b/src/language-js/parentheses/parent-needs-parentheses.js index 770dc1b43..d7087bd2c 100644 --- a/src/language-js/parentheses/parent-needs-parentheses.js +++ b/src/language-js/parentheses/parent-needs-parentheses.js @@ -1,16 +1,16 @@ import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; -import { - getLeftSidePathName, - hasNakedLeftSide, - hasNode, - stripChainElementWrappers, -} from "../utilities/index.js"; import { isCallExpression, isMemberExpression, isReturnOrThrowStatement, } from "../utilities/node-types.js"; import { returnArgumentHasLeadingComment } from "../utilities/return-statement-has-leading-comment.js"; +import { + getLeftSidePathName, + hasNakedLeftSide, + hasNode, + stripChainElementWrappers, +} from "../utilities/utilities.js"; /** * @import AstPath from "../../common/ast-path.js" diff --git a/src/language-js/parse/postprocess/index.js b/src/language-js/parse/postprocess/index.js index 4dadfd6d4..0f5c8e365 100644 --- a/src/language-js/parse/postprocess/index.js +++ b/src/language-js/parse/postprocess/index.js @@ -1,6 +1,6 @@ import * as assert from "#universal/assert"; import { locEnd, locEndWithFullText, locStart } from "../../loc.js"; -import createTypeCheckFunction from "../../utilities/create-type-check-function.js"; +import { createTypeCheckFunction } from "../../utilities/create-type-check-function.js"; import getRaw from "../../utilities/get-raw.js"; import getTextWithoutComments from "../../utilities/get-text-without-comments.js"; import isBlockComment from "../../utilities/is-block-comment.js"; diff --git a/src/language-js/print/angular.js b/src/language-js/print/angular.js index e77d48029..59f48a9f9 100644 --- a/src/language-js/print/angular.js +++ b/src/language-js/print/angular.js @@ -1,6 +1,7 @@ import { group, join, line } from "../../document/index.js"; import UnexpectedNodeError from "../../utilities/unexpected-node-error.js"; -import { createTypeCheckFunction, hasNode } from "../utilities/index.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; +import { hasNode } from "../utilities/utilities.js"; import { printBinaryishExpression } from "./binaryish.js"; /** @import AstPath from "../../common/ast-path.js" */ diff --git a/src/language-js/print/array.js b/src/language-js/print/array.js index 91485f288..01784e1b7 100644 --- a/src/language-js/print/array.js +++ b/src/language-js/print/array.js @@ -13,18 +13,17 @@ import isNextLineEmptyAfterIndex from "../../utilities/is-next-line-empty.js"; import skipInlineComment from "../../utilities/skip-inline-comment.js"; import skipTrailingComment from "../../utilities/skip-trailing-comment.js"; import { locEnd, locStart } from "../loc.js"; -import { - CommentCheckFlags, - hasComment, - isSignedNumericLiteral, - shouldPrintComma, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import { isArrayExpression, isNumericLiteral, isObjectExpression, isTupleType, } from "../utilities/node-types.js"; +import { + isSignedNumericLiteral, + shouldPrintComma, +} from "../utilities/utilities.js"; import { printDanglingCommentsInList, printOptionalToken, diff --git a/src/language-js/print/arrow-function.js b/src/language-js/print/arrow-function.js index 0586376c7..221b0a45f 100644 --- a/src/language-js/print/arrow-function.js +++ b/src/language-js/print/arrow-function.js @@ -14,15 +14,7 @@ import { printCommentsSeparately, printDanglingComments, } from "../../main/comments/print.js"; -import { - CommentCheckFlags, - getFunctionParameters, - hasComment, - hasLeadingOwnLineComment, - isTemplateOnItsOwnLine, - shouldPrintComma, - startsWithNoLookaheadToken, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import { isArrayExpression, isBinaryish, @@ -30,6 +22,13 @@ import { isJsxElement, isObjectExpression, } from "../utilities/node-types.js"; +import { + getFunctionParameters, + hasLeadingOwnLineComment, + isTemplateOnItsOwnLine, + shouldPrintComma, + startsWithNoLookaheadToken, +} from "../utilities/utilities.js"; import { printReturnType, shouldPrintParamsWithoutParens } from "./function.js"; import { printFunctionParameters } from "./function-parameters.js"; diff --git a/src/language-js/print/assignment.js b/src/language-js/print/assignment.js index 30d378a30..106b6c6bb 100644 --- a/src/language-js/print/assignment.js +++ b/src/language-js/print/assignment.js @@ -10,12 +10,6 @@ import { } from "../../document/index.js"; import getStringWidth from "../../utilities/get-string-width.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; -import { - getCallArguments, - hasLeadingOwnLineComment, - isLoneShortArgument, - isObjectProperty, -} from "../utilities/index.js"; import { isBinaryish, isBooleanLiteral, @@ -28,6 +22,12 @@ import { isTypeAlias, isUnionType, } from "../utilities/node-types.js"; +import { + getCallArguments, + hasLeadingOwnLineComment, + isLoneShortArgument, + isObjectProperty, +} from "../utilities/utilities.js"; import { shouldInlineLogicalExpression } from "./binaryish.js"; import { printCallExpression } from "./call-expression.js"; diff --git a/src/language-js/print/await-expression.js b/src/language-js/print/await-expression.js index 50bd87bda..910f88be0 100644 --- a/src/language-js/print/await-expression.js +++ b/src/language-js/print/await-expression.js @@ -1,9 +1,9 @@ import { group, indent, softline } from "../../document/index.js"; -import { startsWithNoLookaheadToken } from "../utilities/index.js"; import { isCallExpression, isMemberExpression, } from "../utilities/node-types.js"; +import { startsWithNoLookaheadToken } from "../utilities/utilities.js"; /** * @import AstPath from "../../common/ast-path.js" diff --git a/src/language-js/print/binaryish.js b/src/language-js/print/binaryish.js index 651e1cc4f..3694ed9a3 100644 --- a/src/language-js/print/binaryish.js +++ b/src/language-js/print/binaryish.js @@ -14,14 +14,7 @@ import { softline, } from "../../document/index.js"; import { printComments } from "../../main/comments/print.js"; -import { - CommentCheckFlags, - hasComment, - hasLeadingOwnLineComment, - isBooleanTypeCoercion, - isObjectProperty, - shouldFlatten, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import isTypeCastComment from "../utilities/is-type-cast-comment.js"; import { isArrayExpression, @@ -32,6 +25,12 @@ import { isObjectExpression, isReturnOrThrowStatement, } from "../utilities/node-types.js"; +import { + hasLeadingOwnLineComment, + isBooleanTypeCoercion, + isObjectProperty, + shouldFlatten, +} from "../utilities/utilities.js"; /** @import {Doc} from "../../document/index.js" */ diff --git a/src/language-js/print/block.js b/src/language-js/print/block.js index 3c3c4fce7..855a7e194 100644 --- a/src/language-js/print/block.js +++ b/src/language-js/print/block.js @@ -1,11 +1,8 @@ import { hardline, indent } from "../../document/index.js"; import { printDanglingComments } from "../../main/comments/print.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; -import { - CommentCheckFlags, - hasComment, - isNextLineEmpty, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { isNextLineEmpty } from "../utilities/utilities.js"; import { printStatementSequence } from "./statement-sequence.js"; /** @import {Doc} from "../../document/index.js" */ diff --git a/src/language-js/print/call-arguments.js b/src/language-js/print/call-arguments.js index d33b3ee28..2257349d6 100644 --- a/src/language-js/print/call-arguments.js +++ b/src/language-js/print/call-arguments.js @@ -10,22 +10,7 @@ import { softline, willBreak, } from "../../document/index.js"; -import { - CommentCheckFlags, - getCallArguments, - getCallArgumentSelector, - getFunctionParameters, - hasComment, - isFunctionCompositionArgs, - isLongCurriedCallExpression, - isNextLineEmpty, - isObjectProperty, - isSimpleCallArgument, - isSimpleType, - iterateCallArgumentsPath, - shouldPrintComma, - stripChainElementWrappers, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import { isArrayExpression, isBinaryCastExpression, @@ -37,6 +22,20 @@ import { isRegExpLiteral, isStringLiteral, } from "../utilities/node-types.js"; +import { + getCallArguments, + getCallArgumentSelector, + getFunctionParameters, + isFunctionCompositionArgs, + isLongCurriedCallExpression, + isNextLineEmpty, + isObjectProperty, + isSimpleCallArgument, + isSimpleType, + iterateCallArgumentsPath, + shouldPrintComma, + stripChainElementWrappers, +} from "../utilities/utilities.js"; import { isConciselyPrintedArray } from "./array.js"; import { printDanglingCommentsInList } from "./miscellaneous.js"; diff --git a/src/language-js/print/call-expression.js b/src/language-js/print/call-expression.js index ca10b9461..ccc35ee66 100644 --- a/src/language-js/print/call-expression.js +++ b/src/language-js/print/call-expression.js @@ -1,15 +1,15 @@ import { group, join, lineSuffixBoundary } from "../../document/index.js"; import needsParentheses from "../parentheses/needs-parentheses.js"; -import { - getCallArguments, - hasComment, - isMemberish, - isNodeMatches, - isTemplateOnItsOwnLine, - iterateCallArgumentsPath, -} from "../utilities/index.js"; +import { hasComment } from "../utilities/comments.js"; +import { isNodeMatches } from "../utilities/is-node-matches.js"; import { isCallExpression, isStringLiteral } from "../utilities/node-types.js"; import { isTestCall } from "../utilities/test-libraries.js"; +import { + getCallArguments, + isMemberish, + isTemplateOnItsOwnLine, + iterateCallArgumentsPath, +} from "../utilities/utilities.js"; import printCallArguments from "./call-arguments.js"; import printMemberChain from "./member-chain.js"; import { printOptionalToken } from "./miscellaneous.js"; diff --git a/src/language-js/print/class-body.js b/src/language-js/print/class-body.js index 53c6b47e7..4bc9d9c9b 100644 --- a/src/language-js/print/class-body.js +++ b/src/language-js/print/class-body.js @@ -12,12 +12,11 @@ import hasNewlineInRange from "../../utilities/has-newline-in-range.js"; import { locEnd, locStart } from "../loc.js"; import { CommentCheckFlags, - createTypeCheckFunction, getComments, hasComment, - isNextLineEmpty, - shouldPrintComma, -} from "../utilities/index.js"; +} from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; +import { isNextLineEmpty, shouldPrintComma } from "../utilities/utilities.js"; import { shouldHugTheOnlyParameter } from "./function-parameters.js"; /* diff --git a/src/language-js/print/class.js b/src/language-js/print/class.js index 4bd7e137c..2f278e119 100644 --- a/src/language-js/print/class.js +++ b/src/language-js/print/class.js @@ -14,13 +14,10 @@ import { } from "../../main/comments/print.js"; import createGroupIdMapper from "../../utilities/create-group-id-mapper.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; -import { - CommentCheckFlags, - createTypeCheckFunction, - hasComment, - stripChainElementWrappers, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import { isMemberExpression } from "../utilities/node-types.js"; +import { stripChainElementWrappers } from "../utilities/utilities.js"; import { printAssignment } from "./assignment.js"; import { printClassMemberDecorators } from "./decorators.js"; import { printMethod } from "./function.js"; diff --git a/src/language-js/print/estree.js b/src/language-js/print/estree.js index 35e1e1104..a01d0d891 100644 --- a/src/language-js/print/estree.js +++ b/src/language-js/print/estree.js @@ -7,17 +7,14 @@ import { } from "../../document/index.js"; import { printDanglingComments } from "../../main/comments/print.js"; import UnexpectedNodeError from "../../utilities/unexpected-node-error.js"; -import { - CommentCheckFlags, - hasComment, - isMeaningfulEmptyStatement, - isMethod, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { isMeaningfulEmptyStatement } from "../utilities/is-meaningful-empty-statement.js"; import { isArrayExpression, isLiteral, isObjectExpression, } from "../utilities/node-types.js"; +import { isMethod } from "../utilities/utilities.js"; import { printArray } from "./array.js"; import { printArrowFunction } from "./arrow-function.js"; import { diff --git a/src/language-js/print/expression-statement.js b/src/language-js/print/expression-statement.js index df6e2e123..490037038 100644 --- a/src/language-js/print/expression-statement.js +++ b/src/language-js/print/expression-statement.js @@ -8,7 +8,7 @@ import { isSingleVueEventBindingExpressionStatement, shouldExpressionStatementPrintLeadingSemicolon, } from "../semicolon/semicolon.js"; -import { CommentCheckFlags, getComments } from "../utilities/index.js"; +import { CommentCheckFlags, getComments } from "../utilities/comments.js"; import { shouldExpressionStatementPrintOwnComments } from "../utilities/should-expression-statement-print-own-comments.js"; import { isVueEventBindingFunctionExpression, diff --git a/src/language-js/print/flow.js b/src/language-js/print/flow.js index d759af6b5..725b2f895 100644 --- a/src/language-js/print/flow.js +++ b/src/language-js/print/flow.js @@ -5,8 +5,8 @@ import { replaceEndOfLine } from "../../document/index.js"; import printNumber from "../../utilities/print-number.js"; import printString from "../../utilities/print-string.js"; import getRaw from "../utilities/get-raw.js"; -import { isMethod } from "../utilities/index.js"; import isFlowKeywordType from "../utilities/is-flow-keyword-type.js"; +import { isMethod } from "../utilities/utilities.js"; import { printArray } from "./array.js"; import { printArrayType } from "./array-type.js"; import { printBinaryCastExpression } from "./cast-expression.js"; diff --git a/src/language-js/print/function-parameters.js b/src/language-js/print/function-parameters.js index 319b17fc8..c6a3773d3 100644 --- a/src/language-js/print/function-parameters.js +++ b/src/language-js/print/function-parameters.js @@ -10,9 +10,15 @@ import { willBreak, } from "../../document/index.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; +import { hasComment } from "../utilities/comments.js"; +import { + isArrayExpression, + isObjectExpression, + isObjectType, +} from "../utilities/node-types.js"; +import { isTestCall } from "../utilities/test-libraries.js"; import { getFunctionParameters, - hasComment, hasRestParameter, isFlowObjectTypePropertyAFunction, isNextLineEmpty, @@ -20,13 +26,7 @@ import { isTypeAnnotationAFunction, iterateFunctionParametersPath, shouldPrintComma, -} from "../utilities/index.js"; -import { - isArrayExpression, - isObjectExpression, - isObjectType, -} from "../utilities/node-types.js"; -import { isTestCall } from "../utilities/test-libraries.js"; +} from "../utilities/utilities.js"; import { printDanglingCommentsInList } from "./miscellaneous.js"; /** @import AstPath from "../../common/ast-path.js" */ diff --git a/src/language-js/print/function-type.js b/src/language-js/print/function-type.js index 649c9d8d5..2c54b87e5 100644 --- a/src/language-js/print/function-type.js +++ b/src/language-js/print/function-type.js @@ -1,6 +1,6 @@ import { group } from "../../document/index.js"; import { hasSameLocStart } from "../loc.js"; -import { isFlowObjectTypePropertyAFunction } from "../utilities/index.js"; +import { isFlowObjectTypePropertyAFunction } from "../utilities/utilities.js"; import { printClassMemberSemicolon } from "./class.js"; import { printFunctionParameters, diff --git a/src/language-js/print/function.js b/src/language-js/print/function.js index 616fa731e..78c1aefb9 100644 --- a/src/language-js/print/function.js +++ b/src/language-js/print/function.js @@ -1,13 +1,12 @@ import * as assert from "#universal/assert"; import { group } from "../../document/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { isCallExpression } from "../utilities/node-types.js"; import { - CommentCheckFlags, getCallArguments, getFunctionParameters, - hasComment, isMethod, -} from "../utilities/index.js"; -import { isCallExpression } from "../utilities/node-types.js"; +} from "../utilities/utilities.js"; import { printFunctionParameters, shouldBreakFunctionParameters, diff --git a/src/language-js/print/if-statement.js b/src/language-js/print/if-statement.js index 9f04b1859..6d070c501 100644 --- a/src/language-js/print/if-statement.js +++ b/src/language-js/print/if-statement.js @@ -1,10 +1,7 @@ import { group, hardline } from "../../document/index.js"; import { printDanglingComments } from "../../main/comments/print.js"; -import { - CommentCheckFlags, - hasComment, - needsHardlineAfterDanglingComment, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { needsHardlineAfterDanglingComment } from "../utilities/utilities.js"; import { adjustClause, printIfStatementCondition } from "./miscellaneous.js"; /** diff --git a/src/language-js/print/index-signature.js b/src/language-js/print/index-signature.js index 4c5dd374b..7f07246d9 100644 --- a/src/language-js/print/index-signature.js +++ b/src/language-js/print/index-signature.js @@ -5,7 +5,7 @@ import { join, softline, } from "../../document/index.js"; -import { shouldPrintComma } from "../utilities/index.js"; +import { shouldPrintComma } from "../utilities/utilities.js"; import { printClassMemberSemicolon } from "./class.js"; import { printTypeAnnotationProperty } from "./type-annotation.js"; diff --git a/src/language-js/print/index.js b/src/language-js/print/index.js index 6b4f79c9c..3dd7c68db 100644 --- a/src/language-js/print/index.js +++ b/src/language-js/print/index.js @@ -8,13 +8,10 @@ import { import { printComments } from "../../main/comments/print.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; import needsParentheses from "../parentheses/needs-parentheses.js"; -import { - CommentCheckFlags, - createTypeCheckFunction, - hasComment, - isIifeCalleeOrTaggedTemplateExpressionTag, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import isIgnored from "../utilities/is-ignored.js"; +import { isIifeCalleeOrTaggedTemplateExpressionTag } from "../utilities/utilities.js"; import { printAngular } from "./angular.js"; import { printDecorators } from "./decorators.js"; import { printEstree } from "./estree.js"; diff --git a/src/language-js/print/intersection-type.js b/src/language-js/print/intersection-type.js index b650e3c7a..392610599 100644 --- a/src/language-js/print/intersection-type.js +++ b/src/language-js/print/intersection-type.js @@ -1,6 +1,6 @@ import { group, indent, line } from "../../document/index.js"; -import { hasLeadingOwnLineComment } from "../utilities/index.js"; import { isObjectType } from "../utilities/node-types.js"; +import { hasLeadingOwnLineComment } from "../utilities/utilities.js"; // `TSIntersectionType` and `IntersectionTypeAnnotation` function printIntersectionType(path, options, print) { diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js index 82856a107..9e8567c6e 100644 --- a/src/language-js/print/jsx.js +++ b/src/language-js/print/jsx.js @@ -20,16 +20,12 @@ import { } from "../../main/comments/print.js"; import { getPreferredQuote } from "../../utilities/get-preferred-quote.js"; import UnexpectedNodeError from "../../utilities/unexpected-node-error.js"; -import WhitespaceUtilities from "../../utilities/whitespace-utilities.js"; import needsParentheses from "../parentheses/needs-parentheses.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import getRaw from "../utilities/get-raw.js"; -import { - CommentCheckFlags, - createTypeCheckFunction, - hasComment, - hasNodeIgnoreComment, - stripChainElementWrappers, -} from "../utilities/index.js"; +import { isMeaningfulJsxText } from "../utilities/is-meaningful-jsx-text.js"; +import { jsxWhitespace } from "../utilities/jsx-whitespace.js"; import { isArrayExpression, isBinaryish, @@ -38,6 +34,7 @@ import { isObjectExpression, isStringLiteral, } from "../utilities/node-types.js"; +import { stripChainElementWrappers } from "../utilities/utilities.js"; /** @import AstPath from "../../common/ast-path.js"; @@ -45,16 +42,6 @@ import { @import {Doc} from "../../document/index.js"; */ -/* -Only the following are treated as whitespace inside JSX. - -- U+0020 SPACE -- U+000A LF -- U+000D CR -- U+0009 TAB -*/ -const jsxWhitespace = new WhitespaceUtilities(" \n\r\t"); - const isEmptyStringOrAnyLine = (doc) => doc === "" || doc === line || doc === hardline || doc === softline; @@ -855,20 +842,6 @@ function isEmptyJsxElement(node) { return child.type === "JSXText" && !isMeaningfulJsxText(child); } -// Meaningful if it contains non-whitespace characters, -// or it contains whitespace without a new line. -/** - * @param {Node} node - * @returns {boolean} - */ -function isMeaningfulJsxText(node) { - return ( - node.type === "JSXText" && - (jsxWhitespace.hasNonWhitespaceCharacter(getRaw(node)) || - !/\n/.test(getRaw(node))) - ); -} - // Detect an expression node representing `{" "}` function isJsxWhitespaceExpression(node) { return ( @@ -879,33 +852,4 @@ function isJsxWhitespaceExpression(node) { ); } -/** - * @param {AstPath} path - * @returns {boolean} - */ -function hasJsxIgnoreComment(path) { - const { node, parent } = path; - if (!isJsxElement(node) || !isJsxElement(parent)) { - return false; - } - - // Lookup the previous sibling, ignoring any empty JSXText elements - const { index, siblings } = path; - let prevSibling; - for (let i = index; i > 0; i--) { - const candidate = siblings[i - 1]; - if (candidate.type === "JSXText" && !isMeaningfulJsxText(candidate)) { - continue; - } - prevSibling = candidate; - break; - } - - return ( - prevSibling?.type === "JSXExpressionContainer" && - prevSibling.expression.type === "JSXEmptyExpression" && - hasNodeIgnoreComment(prevSibling.expression) - ); -} - -export { hasJsxIgnoreComment, printJsx }; +export { printJsx }; diff --git a/src/language-js/print/mapped-type.js b/src/language-js/print/mapped-type.js index adc0e4135..f76f3ed8e 100644 --- a/src/language-js/print/mapped-type.js +++ b/src/language-js/print/mapped-type.js @@ -10,8 +10,8 @@ import { printDanglingComments } from "../../main/comments/print.js"; import hasNewline from "../../utilities/has-newline.js"; import hasNewlineInRange from "../../utilities/has-newline-in-range.js"; import { locEnd, locStart } from "../loc.js"; +import { CommentCheckFlags, getComments } from "../utilities/comments.js"; import getTextWithoutComments from "../utilities/get-text-without-comments.js"; -import { CommentCheckFlags, getComments } from "../utilities/index.js"; import isLineComment from "../utilities/is-line-comment.js"; import { printClassMemberSemicolon } from "./class.js"; diff --git a/src/language-js/print/match.js b/src/language-js/print/match.js index 2235779a3..11283e15a 100644 --- a/src/language-js/print/match.js +++ b/src/language-js/print/match.js @@ -13,13 +13,12 @@ import { printDanglingComments, } from "../../main/comments/print.js"; import needsParentheses from "../parentheses/needs-parentheses.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import { - CommentCheckFlags, - createTypeCheckFunction, - hasComment, hasLeadingOwnLineComment, isNextLineEmpty, -} from "../utilities/index.js"; +} from "../utilities/utilities.js"; /* - `MatchExpression` (Flow) diff --git a/src/language-js/print/member-chain.js b/src/language-js/print/member-chain.js index 7fdd0886f..2a30cbf93 100644 --- a/src/language-js/print/member-chain.js +++ b/src/language-js/print/member-chain.js @@ -13,20 +13,19 @@ import getNextNonSpaceNonCommentCharacterIndex from "../../utilities/get-next-no import isNextLineEmptyAfterIndex from "../../utilities/is-next-line-empty.js"; import { locEnd } from "../loc.js"; import needsParentheses from "../parentheses/needs-parentheses.js"; -import { - CommentCheckFlags, - hasComment, - isLongCurriedCallExpression, - isMemberish, - isNextLineEmpty, - isSimpleCallArgument, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import { isCallExpression, isFunctionOrArrowExpression, isMemberExpression, isNumericLiteral, } from "../utilities/node-types.js"; +import { + isLongCurriedCallExpression, + isMemberish, + isNextLineEmpty, + isSimpleCallArgument, +} from "../utilities/utilities.js"; import { printBindExpressionCallee } from "./bind-expression.js"; import printCallArguments from "./call-arguments.js"; import { printMemberLookup } from "./member.js"; diff --git a/src/language-js/print/member.js b/src/language-js/print/member.js index 0685b8fd4..4ff745998 100644 --- a/src/language-js/print/member.js +++ b/src/language-js/print/member.js @@ -5,16 +5,16 @@ import { lineSuffixBoundary, softline, } from "../../document/index.js"; -import { - getCallArguments, - stripChainElementWrappers, -} from "../utilities/index.js"; import { isCallExpression, isChainElementWrapper, isMemberExpression, isNumericLiteral, } from "../utilities/node-types.js"; +import { + getCallArguments, + stripChainElementWrappers, +} from "../utilities/utilities.js"; import { printOptionalToken } from "./miscellaneous.js"; const isCallExpressionWithArguments = (node) => diff --git a/src/language-js/print/miscellaneous.js b/src/language-js/print/miscellaneous.js index 5788281ec..3ecdbc9e9 100644 --- a/src/language-js/print/miscellaneous.js +++ b/src/language-js/print/miscellaneous.js @@ -6,11 +6,8 @@ import { softline, } from "../../document/index.js"; import { printDanglingComments } from "../../main/comments/print.js"; -import { - CommentCheckFlags, - createTypeCheckFunction, - hasComment, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import { isCallExpression, isMemberExpression, diff --git a/src/language-js/print/module.js b/src/language-js/print/module.js index db7f451a8..4310d4bac 100644 --- a/src/language-js/print/module.js +++ b/src/language-js/print/module.js @@ -12,16 +12,15 @@ import { printDanglingComments } from "../../main/comments/print.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; import UnexpectedNodeError from "../../utilities/unexpected-node-error.js"; import { locEnd, locStart } from "../loc.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import getTextWithoutComments from "../utilities/get-text-without-comments.js"; +import { isStringLiteral } from "../utilities/node-types.js"; import { - CommentCheckFlags, - createTypeCheckFunction, - hasComment, isShorthandSpecifier, needsHardlineAfterDanglingComment, shouldPrintComma, -} from "../utilities/index.js"; -import { isStringLiteral } from "../utilities/node-types.js"; +} from "../utilities/utilities.js"; import { printDecoratorsBeforeExport } from "./decorators.js"; import { printDeclareToken } from "./miscellaneous.js"; import { printObject } from "./object.js"; diff --git a/src/language-js/print/object.js b/src/language-js/print/object.js index a7a1bc99b..40377d91b 100644 --- a/src/language-js/print/object.js +++ b/src/language-js/print/object.js @@ -12,16 +12,15 @@ import hasNewline from "../../utilities/has-newline.js"; import hasNewlineInRange from "../../utilities/has-newline-in-range.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; import { locEnd, locStart } from "../loc.js"; -import getTextWithoutComments from "../utilities/get-text-without-comments.js"; import { CommentCheckFlags, - createTypeCheckFunction, getComments, hasComment, - isNextLineEmpty, - shouldPrintComma, -} from "../utilities/index.js"; +} from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; +import getTextWithoutComments from "../utilities/get-text-without-comments.js"; import { isObjectType } from "../utilities/node-types.js"; +import { isNextLineEmpty, shouldPrintComma } from "../utilities/utilities.js"; import { shouldHugTheOnlyParameter } from "./function-parameters.js"; import { printDanglingCommentsInList, diff --git a/src/language-js/print/return-statement.js b/src/language-js/print/return-statement.js index 4efcf2277..bc246d4f3 100644 --- a/src/language-js/print/return-statement.js +++ b/src/language-js/print/return-statement.js @@ -6,7 +6,7 @@ import { softline, } from "../../document/index.js"; import { printDanglingComments } from "../../main/comments/print.js"; -import { CommentCheckFlags, hasComment } from "../utilities/index.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"; diff --git a/src/language-js/print/statement-sequence.js b/src/language-js/print/statement-sequence.js index 80331cf35..dd4efc4e3 100644 --- a/src/language-js/print/statement-sequence.js +++ b/src/language-js/print/statement-sequence.js @@ -1,5 +1,5 @@ import { hardline } from "../../document/index.js"; -import { isNextLineEmpty } from "../utilities/index.js"; +import { isNextLineEmpty } from "../utilities/utilities.js"; /** * @import {Doc} from "../../document/index.js" diff --git a/src/language-js/print/switch-statement.js b/src/language-js/print/switch-statement.js index cf2081dac..02577c903 100644 --- a/src/language-js/print/switch-statement.js +++ b/src/language-js/print/switch-statement.js @@ -6,11 +6,8 @@ import { softline, } from "../../document/index.js"; import { printDanglingComments } from "../../main/comments/print.js"; -import { - CommentCheckFlags, - hasComment, - isNextLineEmpty, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { isNextLineEmpty } from "../utilities/utilities.js"; import { printStatementSequence } from "./statement-sequence.js"; function printSwitchStatement(path, options, print) { diff --git a/src/language-js/print/template-literal.js b/src/language-js/print/template-literal.js index 867ed76e0..ac1fb01d0 100644 --- a/src/language-js/print/template-literal.js +++ b/src/language-js/print/template-literal.js @@ -19,13 +19,13 @@ import { CommentCheckFlags, getComments, hasComment, - stripChainElementWrappers, -} from "../utilities/index.js"; +} from "../utilities/comments.js"; import { isBinaryCastExpression, isBinaryish, isMemberExpression, } from "../utilities/node-types.js"; +import { stripChainElementWrappers } from "../utilities/utilities.js"; /** * @import {Doc} from "../../document/index.js" diff --git a/src/language-js/print/ternary.js b/src/language-js/print/ternary.js index 93d289cb1..bab09ce2c 100644 --- a/src/language-js/print/ternary.js +++ b/src/language-js/print/ternary.js @@ -16,9 +16,7 @@ import { CommentCheckFlags, getComments, hasComment, - isLoneShortArgument, - isSimpleExpressionByNodeCount, -} from "../utilities/index.js"; +} from "../utilities/comments.js"; import isBlockComment from "../utilities/is-block-comment.js"; import { isBinaryCastExpression, @@ -29,6 +27,10 @@ import { isMemberExpression, isReturnOrThrowStatement, } from "../utilities/node-types.js"; +import { + isLoneShortArgument, + isSimpleExpressionByNodeCount, +} from "../utilities/utilities.js"; import { printTernaryOld } from "./ternary-old.js"; /** diff --git a/src/language-js/print/try-statement.js b/src/language-js/print/try-statement.js index c1af19e35..1675fd71a 100644 --- a/src/language-js/print/try-statement.js +++ b/src/language-js/print/try-statement.js @@ -1,7 +1,7 @@ import { indent, softline } from "../../document/index.js"; import hasNewline from "../../utilities/has-newline.js"; import { locEnd, locStart } from "../loc.js"; -import { hasComment } from "../utilities/index.js"; +import { hasComment } from "../utilities/comments.js"; import isBlockComment from "../utilities/is-block-comment.js"; function printTryStatement(path, options, print) { diff --git a/src/language-js/print/type-annotation.js b/src/language-js/print/type-annotation.js index 099ddafc2..02578ea7a 100644 --- a/src/language-js/print/type-annotation.js +++ b/src/language-js/print/type-annotation.js @@ -1,9 +1,6 @@ -import { - CommentCheckFlags, - hasComment, - isSimpleType, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import { isObjectType, isUnionType } from "../utilities/node-types.js"; +import { isSimpleType } from "../utilities/utilities.js"; import { shouldHugUnionType } from "./union-type.js"; /** diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js index 5e8990ee8..5f5d4cf79 100644 --- a/src/language-js/print/type-parameters.js +++ b/src/language-js/print/type-parameters.js @@ -12,14 +12,13 @@ import { import { printDanglingComments } from "../../main/comments/print.js"; import hasNewline from "../../utilities/has-newline.js"; import { locEnd } from "../loc.js"; -import { - CommentCheckFlags, - getFunctionParameters, - hasComment, - shouldPrintComma, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; import { isObjectType } from "../utilities/node-types.js"; import { isTestCall } from "../utilities/test-libraries.js"; +import { + getFunctionParameters, + shouldPrintComma, +} from "../utilities/utilities.js"; import { isArrowFunctionVariableDeclarator } from "./assignment.js"; import { printTypeAnnotationProperty, diff --git a/src/language-js/print/union-type.js b/src/language-js/print/union-type.js index 5134cd27f..8b6877697 100644 --- a/src/language-js/print/union-type.js +++ b/src/language-js/print/union-type.js @@ -12,18 +12,17 @@ import { printCommentsSeparately, } from "../../main/comments/print.js"; import needsParentheses from "../parentheses/needs-parentheses.js"; -import { - CommentCheckFlags, - createTypeCheckFunction, - hasComment, - hasLeadingOwnLineComment, - shouldUnionTypePrintOwnComments, -} from "../utilities/index.js"; +import { CommentCheckFlags, hasComment } from "../utilities/comments.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; import { isConditionalType, isTupleType, isTypeAlias, } from "../utilities/node-types.js"; +import { + hasLeadingOwnLineComment, + shouldUnionTypePrintOwnComments, +} from "../utilities/utilities.js"; /** @import {Doc} from "../../document/index.js"; diff --git a/src/language-js/print/variable-declaration.js b/src/language-js/print/variable-declaration.js index 71978af8e..acf2e03f6 100644 --- a/src/language-js/print/variable-declaration.js +++ b/src/language-js/print/variable-declaration.js @@ -1,5 +1,5 @@ import { group, hardline, indent, line } from "../../document/index.js"; -import { hasComment } from "../utilities/index.js"; +import { hasComment } from "../utilities/comments.js"; import { printDeclareToken } from "./miscellaneous.js"; function printVariableDeclaration(path, options, print) { diff --git a/src/language-js/semicolon/semicolon.js b/src/language-js/semicolon/semicolon.js index d390a45f2..7135a6143 100644 --- a/src/language-js/semicolon/semicolon.js +++ b/src/language-js/semicolon/semicolon.js @@ -1,7 +1,10 @@ import needsParentheses from "../parentheses/needs-parentheses.js"; import { shouldPrintParamsWithoutParens } from "../print/function.js"; -import { getLeftSidePathName, hasNakedLeftSide } from "../utilities/index.js"; import { isJsxElement } from "../utilities/node-types.js"; +import { + getLeftSidePathName, + hasNakedLeftSide, +} from "../utilities/utilities.js"; function shouldExpressionStatementPrintLeadingSemicolon(path, options) { if (options.semi) { diff --git a/src/language-js/utilities/comments.js b/src/language-js/utilities/comments.js new file mode 100644 index 000000000..6f4c758ac --- /dev/null +++ b/src/language-js/utilities/comments.js @@ -0,0 +1,84 @@ +import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; +import isBlockComment from "./is-block-comment.js"; +import isLineComment from "./is-line-comment.js"; +import { isPrettierIgnoreComment } from "./is-prettier-ignore-comment.js"; + +/** +@import { + Node, + Comment, +} from "../types/estree.js"; +@import AstPath from "../../common/ast-path.js"; +*/ + +/** @enum {number} */ +const CommentCheckFlags = { + /** Check comment is a leading comment */ + Leading: 1 << 1, + /** Check comment is a trailing comment */ + Trailing: 1 << 2, + /** Check comment is a dangling comment */ + Dangling: 1 << 3, + /** Check comment is a block comment */ + Block: 1 << 4, + /** Check comment is a line comment */ + Line: 1 << 5, + /** Check comment is a `prettier-ignore` comment */ + PrettierIgnore: 1 << 6, + /** Check comment is the first attached comment */ + First: 1 << 7, + /** Check comment is the last attached comment */ + Last: 1 << 8, +}; + +const getCommentTestFunction = (flags, fn) => { + if (typeof flags === "function") { + fn = flags; + flags = 0; + } + if (flags || fn) { + return (comment, index, comments) => + !( + (flags & CommentCheckFlags.Leading && !comment.leading) || + (flags & CommentCheckFlags.Trailing && !comment.trailing) || + (flags & CommentCheckFlags.Dangling && + (comment.leading || comment.trailing)) || + (flags & CommentCheckFlags.Block && !isBlockComment(comment)) || + (flags & CommentCheckFlags.Line && !isLineComment(comment)) || + (flags & CommentCheckFlags.First && index !== 0) || + (flags & CommentCheckFlags.Last && index !== comments.length - 1) || + (flags & CommentCheckFlags.PrettierIgnore && + !isPrettierIgnoreComment(comment)) || + (fn && !fn(comment)) + ); + } +}; +/** + * @param {Node} node + * @param {number | function} [flags] + * @param {function} [fn] + * @returns {boolean} + */ +function hasComment(node, flags, fn) { + if (!isNonEmptyArray(node?.comments)) { + return false; + } + const test = getCommentTestFunction(flags, fn); + return test ? node.comments.some(test) : true; +} + +/** + * @param {Node} node + * @param {number | function} [flags] + * @param {function} [fn] + * @returns {Comment[]} + */ +function getComments(node, flags, fn) { + if (!Array.isArray(node?.comments)) { + return []; + } + const test = getCommentTestFunction(flags, fn); + return test ? node.comments.filter(test) : node.comments; +} + +export { CommentCheckFlags, getComments, hasComment }; diff --git a/src/language-js/utilities/create-type-check-function.js b/src/language-js/utilities/create-type-check-function.js index 212c26748..657b0abc9 100644 --- a/src/language-js/utilities/create-type-check-function.js +++ b/src/language-js/utilities/create-type-check-function.js @@ -31,4 +31,4 @@ function createTypeCheckFunction(typesArray) { return (node) => types.has(node?.type); } -export default createTypeCheckFunction; +export { createTypeCheckFunction }; diff --git a/src/language-js/utilities/has-jsx-ignore-comment.js b/src/language-js/utilities/has-jsx-ignore-comment.js new file mode 100644 index 000000000..e3ed5477c --- /dev/null +++ b/src/language-js/utilities/has-jsx-ignore-comment.js @@ -0,0 +1,39 @@ +import { hasNodeIgnoreComment } from "./has-node-ignore-comment.js"; +import { isMeaningfulJsxText } from "./is-meaningful-jsx-text.js"; +import { isJsxElement } from "./node-types.js"; + +/** +@import AstPath from "../../common/ast-path.js"; +@import {Node} from "../types/estree.js"; +*/ + +/** + * @param {AstPath} path + * @returns {boolean} + */ +function hasJsxIgnoreComment(path) { + const { node, parent } = path; + if (!isJsxElement(node) || !isJsxElement(parent)) { + return false; + } + + // Lookup the previous sibling, ignoring any empty JSXText elements + const { index, siblings } = path; + let prevSibling; + for (let i = index; i > 0; i--) { + const candidate = siblings[i - 1]; + if (candidate.type === "JSXText" && !isMeaningfulJsxText(candidate)) { + continue; + } + prevSibling = candidate; + break; + } + + return ( + prevSibling?.type === "JSXExpressionContainer" && + prevSibling.expression.type === "JSXEmptyExpression" && + hasNodeIgnoreComment(prevSibling.expression) + ); +} + +export { hasJsxIgnoreComment }; diff --git a/src/language-js/utilities/has-node-ignore-comment.js b/src/language-js/utilities/has-node-ignore-comment.js new file mode 100644 index 000000000..ea439fa09 --- /dev/null +++ b/src/language-js/utilities/has-node-ignore-comment.js @@ -0,0 +1,9 @@ +import { CommentCheckFlags, hasComment } from "./comments.js"; + +function hasNodeIgnoreComment(node) { + return ( + node?.prettierIgnore || hasComment(node, CommentCheckFlags.PrettierIgnore) + ); +} + +export { hasNodeIgnoreComment }; diff --git a/src/language-js/utilities/is-block-comment.js b/src/language-js/utilities/is-block-comment.js index eb01ca2ce..0211d8091 100644 --- a/src/language-js/utilities/is-block-comment.js +++ b/src/language-js/utilities/is-block-comment.js @@ -1,4 +1,4 @@ -import createTypeCheckFunction from "./create-type-check-function.js"; +import { createTypeCheckFunction } from "./create-type-check-function.js"; /** @import {Comment} from "../types/estree.js"; diff --git a/src/language-js/utilities/is-flow-keyword-type.js b/src/language-js/utilities/is-flow-keyword-type.js index 58de9bb52..e8fd31a27 100644 --- a/src/language-js/utilities/is-flow-keyword-type.js +++ b/src/language-js/utilities/is-flow-keyword-type.js @@ -1,4 +1,4 @@ -import createTypeCheckFunction from "./create-type-check-function.js"; +import { createTypeCheckFunction } from "./create-type-check-function.js"; const isFlowKeywordType = createTypeCheckFunction([ "AnyTypeAnnotation", diff --git a/src/language-js/utilities/is-ignored.js b/src/language-js/utilities/is-ignored.js index a2ec0857e..06c22689c 100644 --- a/src/language-js/utilities/is-ignored.js +++ b/src/language-js/utilities/is-ignored.js @@ -1,5 +1,5 @@ -import { hasJsxIgnoreComment } from "../print/jsx.js"; -import { hasNodeIgnoreComment } from "./index.js"; +import { hasJsxIgnoreComment } from "./has-jsx-ignore-comment.js"; +import { hasNodeIgnoreComment } from "./has-node-ignore-comment.js"; function isIgnored(path) { return hasNodeIgnoreComment(path.node) || hasJsxIgnoreComment(path); diff --git a/src/language-js/utilities/is-line-comment.js b/src/language-js/utilities/is-line-comment.js index 8c70b4494..16e67ae45 100644 --- a/src/language-js/utilities/is-line-comment.js +++ b/src/language-js/utilities/is-line-comment.js @@ -1,4 +1,4 @@ -import createTypeCheckFunction from "./create-type-check-function.js"; +import { createTypeCheckFunction } from "./create-type-check-function.js"; /** @import {Comment} from "../types/estree.js"; diff --git a/src/language-js/utilities/is-meaningful-empty-statement.js b/src/language-js/utilities/is-meaningful-empty-statement.js index e5d1242a2..8f01e2c57 100644 --- a/src/language-js/utilities/is-meaningful-empty-statement.js +++ b/src/language-js/utilities/is-meaningful-empty-statement.js @@ -23,4 +23,4 @@ function isMeaningfulEmptyStatement({ node, parent }) { return false; } -export default isMeaningfulEmptyStatement; +export { isMeaningfulEmptyStatement }; diff --git a/src/language-js/utilities/is-meaningful-jsx-text.js b/src/language-js/utilities/is-meaningful-jsx-text.js new file mode 100644 index 000000000..47279befc --- /dev/null +++ b/src/language-js/utilities/is-meaningful-jsx-text.js @@ -0,0 +1,22 @@ +import getRaw from "./get-raw.js"; +import { jsxWhitespace } from "./jsx-whitespace.js"; + +/** +@import {Node} from "../types/estree.js"; +*/ + +// Meaningful if it contains non-whitespace characters, +// or it contains whitespace without a new line. +/** + * @param {Node} node + * @returns {boolean} + */ +function isMeaningfulJsxText(node) { + return ( + node.type === "JSXText" && + (jsxWhitespace.hasNonWhitespaceCharacter(getRaw(node)) || + !/\n/.test(getRaw(node))) + ); +} + +export { isMeaningfulJsxText }; diff --git a/src/language-js/utilities/is-node-matches.js b/src/language-js/utilities/is-node-matches.js index 79d62f361..c79310944 100644 --- a/src/language-js/utilities/is-node-matches.js +++ b/src/language-js/utilities/is-node-matches.js @@ -59,4 +59,4 @@ function isNodeMatches(node, nameOrPaths) { ); } -export default isNodeMatches; +export { isNodeMatches }; diff --git a/src/language-js/utilities/is-prettier-ignore-comment.js b/src/language-js/utilities/is-prettier-ignore-comment.js new file mode 100644 index 000000000..4a5b50856 --- /dev/null +++ b/src/language-js/utilities/is-prettier-ignore-comment.js @@ -0,0 +1,5 @@ +function isPrettierIgnoreComment(comment) { + return comment.value.trim() === "prettier-ignore" && !comment.unignore; +} + +export { isPrettierIgnoreComment }; diff --git a/src/language-js/utilities/jsx-whitespace.js b/src/language-js/utilities/jsx-whitespace.js new file mode 100644 index 000000000..cebea8486 --- /dev/null +++ b/src/language-js/utilities/jsx-whitespace.js @@ -0,0 +1,13 @@ +import WhitespaceUtilities from "../../utilities/whitespace-utilities.js"; + +/* +Only the following are treated as whitespace inside JSX. + +- U+0020 SPACE +- U+000A LF +- U+000D CR +- U+0009 TAB +*/ +const jsxWhitespace = new WhitespaceUtilities(" \n\r\t"); + +export { jsxWhitespace }; diff --git a/src/language-js/utilities/node-types.js b/src/language-js/utilities/node-types.js index db2c24efd..d7ccb4043 100644 --- a/src/language-js/utilities/node-types.js +++ b/src/language-js/utilities/node-types.js @@ -1,4 +1,4 @@ -import createTypeCheckFunction from "./create-type-check-function.js"; +import { createTypeCheckFunction } from "./create-type-check-function.js"; /** @import { diff --git a/src/language-js/utilities/return-statement-has-leading-comment.js b/src/language-js/utilities/return-statement-has-leading-comment.js index ff81453aa..c59d320f1 100644 --- a/src/language-js/utilities/return-statement-has-leading-comment.js +++ b/src/language-js/utilities/return-statement-has-leading-comment.js @@ -1,13 +1,12 @@ import hasNewlineInRange from "../../utilities/has-newline-in-range.js"; import { locEnd, locStart } from "../loc.js"; +import { CommentCheckFlags, hasComment } from "./comments.js"; +import { isJsxElement } from "./node-types.js"; import { - CommentCheckFlags, getLeftSide, - hasComment, hasLeadingOwnLineComment, hasNakedLeftSide, -} from "./index.js"; -import { isJsxElement } from "./node-types.js"; +} from "./utilities.js"; // This recurses the return argument, looking for the first token // (the leftmost leaf node) and, if it (or its parents) has any diff --git a/src/language-js/utilities/should-expression-statement-print-own-comments.js b/src/language-js/utilities/should-expression-statement-print-own-comments.js index 493f6f8a2..48f3f3ea7 100644 --- a/src/language-js/utilities/should-expression-statement-print-own-comments.js +++ b/src/language-js/utilities/should-expression-statement-print-own-comments.js @@ -1,5 +1,5 @@ import { shouldExpressionStatementPrintLeadingSemicolon } from "../semicolon/semicolon.js"; -import { CommentCheckFlags, getComments } from "./index.js"; +import { CommentCheckFlags, getComments } from "./comments.js"; import isTypeCastComment from "./is-type-cast-comment.js"; function shouldExpressionStatementPrintOwnComments(path, options) { diff --git a/src/language-js/utilities/test-libraries.js b/src/language-js/utilities/test-libraries.js index e52c4ceb6..a1962721e 100644 --- a/src/language-js/utilities/test-libraries.js +++ b/src/language-js/utilities/test-libraries.js @@ -1,11 +1,11 @@ -import { getCallArguments, getFunctionParameters } from "./index.js"; -import isNodeMatches from "./is-node-matches.js"; +import { isNodeMatches } from "./is-node-matches.js"; import { isCallExpression, isFunctionOrArrowExpression, isNumericLiteral, isStringLiteral, } from "./node-types.js"; +import { getCallArguments, getFunctionParameters } from "./utilities.js"; /** @import { diff --git a/src/language-js/utilities/index.js b/src/language-js/utilities/utilities.js similarity index 88% rename from src/language-js/utilities/index.js rename to src/language-js/utilities/utilities.js index 126fff5ae..f13d4410d 100644 --- a/src/language-js/utilities/index.js +++ b/src/language-js/utilities/utilities.js @@ -2,7 +2,6 @@ import { hasDescendant } from "../../utilities/ast.js"; import getStringWidth from "../../utilities/get-string-width.js"; import hasNewline from "../../utilities/has-newline.js"; import isNextLineEmptyAfterIndex from "../../utilities/is-next-line-empty.js"; -import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; import isObject from "../../utilities/is-object.js"; import printString from "../../utilities/print-string.js"; import { @@ -13,11 +12,12 @@ import { locStart, } from "../loc.js"; import getVisitorKeys from "../traverse/get-visitor-keys.js"; -import createTypeCheckFunction from "./create-type-check-function.js"; +import { CommentCheckFlags, getComments, hasComment } from "./comments.js"; +import { createTypeCheckFunction } from "./create-type-check-function.js"; import getRaw from "./get-raw.js"; +import { hasNodeIgnoreComment } from "./has-node-ignore-comment.js"; import isBlockComment from "./is-block-comment.js"; import isFlowKeywordType from "./is-flow-keyword-type.js"; -import isLineComment from "./is-line-comment.js"; import isTsKeywordType from "./is-ts-keyword-type.js"; import { isArrayExpression, @@ -760,86 +760,6 @@ function getCallArgumentSelector(node, index) { throw new RangeError("Invalid argument index"); } -function isPrettierIgnoreComment(comment) { - return comment.value.trim() === "prettier-ignore" && !comment.unignore; -} - -function hasNodeIgnoreComment(node) { - return ( - node?.prettierIgnore || hasComment(node, CommentCheckFlags.PrettierIgnore) - ); -} - -/** @enum {number} */ -const CommentCheckFlags = { - /** Check comment is a leading comment */ - Leading: 1 << 1, - /** Check comment is a trailing comment */ - Trailing: 1 << 2, - /** Check comment is a dangling comment */ - Dangling: 1 << 3, - /** Check comment is a block comment */ - Block: 1 << 4, - /** Check comment is a line comment */ - Line: 1 << 5, - /** Check comment is a `prettier-ignore` comment */ - PrettierIgnore: 1 << 6, - /** Check comment is the first attached comment */ - First: 1 << 7, - /** Check comment is the last attached comment */ - Last: 1 << 8, -}; - -const getCommentTestFunction = (flags, fn) => { - if (typeof flags === "function") { - fn = flags; - flags = 0; - } - if (flags || fn) { - return (comment, index, comments) => - !( - (flags & CommentCheckFlags.Leading && !comment.leading) || - (flags & CommentCheckFlags.Trailing && !comment.trailing) || - (flags & CommentCheckFlags.Dangling && - (comment.leading || comment.trailing)) || - (flags & CommentCheckFlags.Block && !isBlockComment(comment)) || - (flags & CommentCheckFlags.Line && !isLineComment(comment)) || - (flags & CommentCheckFlags.First && index !== 0) || - (flags & CommentCheckFlags.Last && index !== comments.length - 1) || - (flags & CommentCheckFlags.PrettierIgnore && - !isPrettierIgnoreComment(comment)) || - (fn && !fn(comment)) - ); - } -}; -/** - * @param {Node} node - * @param {number | function} [flags] - * @param {function} [fn] - * @returns {boolean} - */ -function hasComment(node, flags, fn) { - if (!isNonEmptyArray(node?.comments)) { - return false; - } - const test = getCommentTestFunction(flags, fn); - return test ? node.comments.some(test) : true; -} - -/** - * @param {Node} node - * @param {number | function} [flags] - * @param {function} [fn] - * @returns {Comment[]} - */ -function getComments(node, flags, fn) { - if (!Array.isArray(node?.comments)) { - return []; - } - const test = getCommentTestFunction(flags, fn); - return test ? node.comments.filter(test) : node.comments; -} - /** * @param {Node} node * @returns {boolean} @@ -959,20 +879,15 @@ function stripChainElementWrappers(node) { } export { - CommentCheckFlags, - createTypeCheckFunction, getCallArguments, getCallArgumentSelector, - getComments, getFunctionParameters, getLeftSide, getLeftSidePathName, getPrecedence, - hasComment, hasLeadingOwnLineComment, hasNakedLeftSide, hasNode, - hasNodeIgnoreComment, hasRestParameter, isBitwiseOperator, isBooleanTypeCoercion, @@ -986,7 +901,6 @@ export { isNextLineEmpty, isNullishCoalescing, isObjectProperty, - isPrettierIgnoreComment, isShorthandSpecifier, isSignedNumericLiteral, isSimpleCallArgument, @@ -1004,5 +918,3 @@ export { startsWithNoLookaheadToken, stripChainElementWrappers, }; -export { default as isMeaningfulEmptyStatement } from "./is-meaningful-empty-statement.js"; -export { default as isNodeMatches } from "./is-node-matches.js"; diff --git a/src/language-js/utilities/vue-event-binding.js b/src/language-js/utilities/vue-event-binding.js index 1477ff1da..736a5d7ae 100644 --- a/src/language-js/utilities/vue-event-binding.js +++ b/src/language-js/utilities/vue-event-binding.js @@ -1,4 +1,4 @@ -import createTypeCheckFunction from "./create-type-check-function.js"; +import { createTypeCheckFunction } from "../utilities/create-type-check-function.js"; // https://github.com/vuejs/core/blob/35785f3cd7bd86cbec3f8324022491da2d088b61/packages/compiler-core/src/babelUtils.ts#L498 const isVueEventBindingTsNode = createTypeCheckFunction([