diff --git a/.eslintrc.yml b/.eslintrc.yml index 89c520c2d..37c6964be 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -117,6 +117,7 @@ overrides: prettier-internal-rules/no-doc-builder-concat: error prettier-internal-rules/prefer-fast-path-each: error prettier-internal-rules/prefer-is-non-empty-array: error + prettier-internal-rules/no-empty-flat-contents-for-if-break: error - files: src/document/*.js rules: prettier-internal-rules/no-doc-builder-concat: off diff --git a/.github/workflows/eslint-rules.yml b/.github/workflows/eslint-rules.yml index 75b183a46..8f2b9db6a 100644 --- a/.github/workflows/eslint-rules.yml +++ b/.github/workflows/eslint-rules.yml @@ -3,11 +3,11 @@ name: Internal_ESLint_Rules_Test on: push: paths: - - "scripts/tools/eslint-plugin-prettier-internal-rules" + - "scripts/tools/eslint-plugin-prettier-internal-rules/**" - ".github/workflows/eslint-rules.yml" pull_request: paths: - - "scripts/tools/eslint-plugin-prettier-internal-rules" + - "scripts/tools/eslint-plugin-prettier-internal-rules/**" - ".github/workflows/eslint-rules.yml" jobs: diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/index.js b/scripts/tools/eslint-plugin-prettier-internal-rules/index.js index 3bec6a3e2..a8ab40ff2 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/index.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/index.js @@ -10,5 +10,6 @@ module.exports = { "prefer-fast-path-each": require("./prefer-fast-path-each"), "prefer-is-non-empty-array": require("./prefer-is-non-empty-array"), "require-json-extensions": require("./require-json-extensions"), + "no-empty-flat-contents-for-if-break": require("./no-empty-flat-contents-for-if-break"), }, }; diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/no-empty-flat-contents-for-if-break.js b/scripts/tools/eslint-plugin-prettier-internal-rules/no-empty-flat-contents-for-if-break.js new file mode 100644 index 000000000..5d9d852e0 --- /dev/null +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/no-empty-flat-contents-for-if-break.js @@ -0,0 +1,42 @@ +"use strict"; + +const selector = [ + "CallExpression", + "[optional=false]", + '[callee.type="Identifier"]', + '[callee.name="ifBreak"]', + "[arguments.length=2]", + '[arguments.1.type="Literal"]', + '[arguments.1.value=""]', + ':not([arguments.0.type="SpreadElement"])', +].join(""); + +const messageId = "no-empty-flat-contents-for-if-break"; + +module.exports = { + meta: { + type: "suggestion", + docs: { + url: + "https://github.com/prettier/prettier/blob/main/scripts/eslint-plugin-prettier-internal-rules/no-empty-flat-contents-for-if-break.js", + }, + messages: { + [messageId]: + "Please don't pass an empty string to second parameter of ifBreak.", + }, + fixable: "code", + }, + create(context) { + return { + [selector](node) { + const [breakContents] = node.arguments; + context.report({ + node, + messageId, + fix: (fixer) => + fixer.removeRange([breakContents.range[1], node.range[1] - 1]), + }); + }, + }; + }, +}; diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/test.js b/scripts/tools/eslint-plugin-prettier-internal-rules/test.js index e02c8008e..85ab03c21 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/test.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/test.js @@ -204,3 +204,46 @@ test("require-json-extensions", { }, ], }); + +test("no-empty-flat-contents-for-if-break", { + valid: [ + "ifBreak('foo', 'bar')", + "ifBreak(doc1, doc2)", + "ifBreak(',')", + "ifBreak(doc)", + "ifBreak('foo', '', { groupId })", + "ifBreak(...foo, { groupId })", + ], + invalid: [ + { + code: "ifBreak('foo', '')", + output: "ifBreak('foo')", + errors: [ + { + message: + "Please don't pass an empty string to second parameter of ifBreak.", + }, + ], + }, + { + code: "ifBreak('foo' , '' )", + output: "ifBreak('foo')", + errors: [ + { + message: + "Please don't pass an empty string to second parameter of ifBreak.", + }, + ], + }, + { + code: "ifBreak(doc, '')", + output: "ifBreak(doc)", + errors: [ + { + message: + "Please don't pass an empty string to second parameter of ifBreak.", + }, + ], + }, + ], +}); diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index 10a2f0971..971bd3160 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -186,7 +186,7 @@ function genericPrint(path, options, print) { options.originalText[locEnd(node) - 1] !== ";" ? "" : options.__isHTMLStyleAttribute && isLastNode(path, node) - ? ifBreak(";", "") + ? ifBreak(";") : ";", ]; } diff --git a/src/language-js/print/ternary.js b/src/language-js/print/ternary.js index bcbf7315f..976f7b9cf 100644 --- a/src/language-js/print/ternary.js +++ b/src/language-js/print/ternary.js @@ -221,10 +221,10 @@ function printTernary(path, options, print) { // parens when using ?: within JSX, because the parens are analogous to // curly braces in an if statement. const wrap = (doc) => [ - ifBreak("(", ""), + ifBreak("("), indent([softline, doc]), softline, - ifBreak(")", ""), + ifBreak(")"), ]; // The only things we don't wrap are: diff --git a/src/language-js/print/typescript.js b/src/language-js/print/typescript.js index 331e4f732..a9b42d67d 100644 --- a/src/language-js/print/typescript.js +++ b/src/language-js/print/typescript.js @@ -348,7 +348,7 @@ function printTypescript(path, options, print) { n.optional ? getTypeScriptMappedTypeModifier(n.optional, "?") : "", n.typeAnnotation ? ": " : "", path.call(print, "typeAnnotation"), - ifBreak(semi, ""), + ifBreak(semi), ]), printDanglingComments(path, options, /* sameIndent */ true), options.bracketSpacing ? line : softline, diff --git a/src/language-yaml/print/flow-mapping-sequence.js b/src/language-yaml/print/flow-mapping-sequence.js index 28b87a059..b5d8152eb 100644 --- a/src/language-yaml/print/flow-mapping-sequence.js +++ b/src/language-yaml/print/flow-mapping-sequence.js @@ -29,7 +29,7 @@ function printFlowMapping(path, print, options) { alignWithSpaces(options.tabWidth, [ bracketSpacing, printChildren(path, print, options), - options.trailingComma === "none" ? "" : ifBreak(",", ""), + options.trailingComma === "none" ? "" : ifBreak(","), hasEndComments(node) ? [hardline, join(hardline, path.map(print, "endComments"))] : "",