diff --git a/.eslintrc.cjs b/.eslintrc.cjs index f094328cb..fba917c9c 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -154,6 +154,7 @@ module.exports = { ], "unicorn/prefer-includes": "error", "unicorn/prefer-json-parse-buffer": "error", + "unicorn/prefer-logical-operator-over-ternary": "error", "unicorn/prefer-module": "error", "unicorn/prefer-native-coercion-functions": "error", "unicorn/prefer-node-protocol": "error", diff --git a/changelog_unreleased/cli/13081.md b/changelog_unreleased/cli/13081.md new file mode 100644 index 000000000..67acee028 --- /dev/null +++ b/changelog_unreleased/cli/13081.md @@ -0,0 +1,3 @@ +#### Infer parser for `.lintstagedrc` (#13081 by @OrRosenblatt) + +A `.lintstagedrc` file (without extension) is handled using `json` and `yaml` parsers. diff --git a/changelog_unreleased/javascript/13054.md b/changelog_unreleased/javascript/13054.md new file mode 100644 index 000000000..6fddc71be --- /dev/null +++ b/changelog_unreleased/javascript/13054.md @@ -0,0 +1,28 @@ +#### Fix docblock parsing (#13054 by @fisker) + + +```jsx +// With `--insert-pragma` flag + +// Input +/* comment */ +foo() + +// Prettier stable +/** + * /* comment + * + * @format + */ + +foo(); + +// Prettier main +/** + * comment + * + * @format + */ + +foo(); +``` diff --git a/cspell.json b/cspell.json index b499d7f7a..ce95c05bf 100644 --- a/cspell.json +++ b/cspell.json @@ -176,6 +176,8 @@ "linearize", "linebreak", "linebreaks", + "lintstaged", + "lintstagedrc", "literalline", "loglevel", "lowercased", diff --git a/package.json b/package.json index 89f5ad020..88a69281a 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "html-tag-names": "2.0.1", "html-void-elements": "2.0.1", "ignore": "5.2.0", - "jest-docblock": "28.0.2", + "jest-docblock": "28.1.1", "json5": "2.2.1", "leven": "4.0.0", "lines-and-columns": "2.0.3", diff --git a/src/language-css/parser-postcss.js b/src/language-css/parser-postcss.js index 3d7ea4fcd..be247e1fe 100644 --- a/src/language-css/parser-postcss.js +++ b/src/language-css/parser-postcss.js @@ -364,9 +364,7 @@ function parseNestedCSS(node, options) { if (typeof node.selector === "string") { selector = node.raws.selector - ? node.raws.selector.scss - ? node.raws.selector.scss - : node.raws.selector.raw + ? node.raws.selector.scss ?? node.raws.selector.raw : node.selector; if (node.raws.between && node.raws.between.trim().length > 0) { @@ -380,9 +378,7 @@ function parseNestedCSS(node, options) { if (typeof node.value === "string") { value = node.raws.value - ? node.raws.value.scss - ? node.raws.value.scss - : node.raws.value.raw + ? node.raws.value.scss ?? node.raws.value.raw : node.value; value = value.trim(); @@ -394,9 +390,7 @@ function parseNestedCSS(node, options) { if (typeof node.params === "string") { params = node.raws.params - ? node.raws.params.scss - ? node.raws.params.scss - : node.raws.params.raw + ? node.raws.params.scss ?? node.raws.params.raw : node.params; if (node.raws.afterName && node.raws.afterName.trim().length > 0) { diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index 75025315c..0a67b421c 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -419,7 +419,7 @@ function genericPrint(path, options, print) { ? [node.namespace === true ? "" : node.namespace.trim(), "|"] : "", node.attribute.trim(), - node.operator ? node.operator : "", + node.operator ?? "", node.value ? quoteAttributeValue( adjustStrings(node.value.trim(), options), diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js index 9d6bebe23..d7a0ff585 100644 --- a/src/language-js/print/jsx.js +++ b/src/language-js/print/jsx.js @@ -567,27 +567,6 @@ function printJsxOpeningElement(path, options, print) { ]); } - const lastAttrHasTrailingComments = - node.attributes.length > 0 && - hasComment(getLast(node.attributes), CommentCheckFlags.Trailing); - - const bracketSameLine = - // Simple tags (no attributes and no comment in tag name) should be - // kept unbroken regardless of `bracketSameLine`. - // jsxBracketSameLine is deprecated in favour of bracketSameLine, - // but is still needed for backwards compatibility. - (node.attributes.length === 0 && !nameHasComments) || - ((options.bracketSameLine || options.jsxBracketSameLine) && - // We should print the bracket in a new line for the following cases: - //
- //
- (!nameHasComments || node.attributes.length > 0) && - !lastAttrHasTrailingComments); - // We should print the opening element expanded if any prop value is a // string literal with newlines const shouldBreak = @@ -610,13 +589,50 @@ function printJsxOpeningElement(path, options, print) { print("name"), print("typeParameters"), indent(path.map(() => [attributeLine, print()], "attributes")), - node.selfClosing ? line : bracketSameLine ? ">" : softline, - node.selfClosing ? "/>" : bracketSameLine ? "" : ">", + ...printEndOfOpeningTag(node, options, nameHasComments), ], { shouldBreak } ); } +function printEndOfOpeningTag(node, options, nameHasComments) { + if (node.selfClosing) { + return [line, "/>"]; + } + const bracketSameLine = shouldPrintBracketSameLine( + node, + options, + nameHasComments + ); + if (bracketSameLine) { + return [">"]; + } + return [softline, ">"]; +} + +function shouldPrintBracketSameLine(node, options, nameHasComments) { + const lastAttrHasTrailingComments = + node.attributes.length > 0 && + hasComment(getLast(node.attributes), CommentCheckFlags.Trailing); + return ( + // Simple tags (no attributes and no comment in tag name) should be + // kept unbroken regardless of `bracketSameLine`. + // jsxBracketSameLine is deprecated in favour of bracketSameLine, + // but is still needed for backwards compatibility. + (node.attributes.length === 0 && !nameHasComments) || + ((options.bracketSameLine || options.jsxBracketSameLine) && + // We should print the bracket in a new line for the following cases: + //
+ //
+ (!nameHasComments || node.attributes.length > 0) && + !lastAttrHasTrailingComments) + ); +} + function printJsxClosingElement(path, options, print) { const node = path.getValue(); const parts = []; diff --git a/src/language-yaml/embed.js b/src/language-yaml/embed.js index 60218898d..babe99d24 100644 --- a/src/language-yaml/embed.js +++ b/src/language-yaml/embed.js @@ -1,11 +1,11 @@ function embed(path, print, textToDoc, options) { const node = path.getValue(); - // Try to format `.prettierrc` and `.stylelintrc` as `json` first + // Try to format `.prettierrc`, `.stylelintrc`, and `.lintstagedrc` as `json` first if ( node.type === "root" && options.filepath && - /(?:[/\\]|^)\.(?:prettier|stylelint)rc$/.test(options.filepath) + /(?:[/\\]|^)\.(?:prettier|stylelint|lintstaged)rc$/.test(options.filepath) ) { return textToDoc(options.originalText, { ...options, parser: "json" }); } diff --git a/src/language-yaml/languages.evaluate.js b/src/language-yaml/languages.evaluate.js index 701f6dcbe..34fc7892b 100644 --- a/src/language-yaml/languages.evaluate.js +++ b/src/language-yaml/languages.evaluate.js @@ -11,6 +11,7 @@ const languages = [ ...data.filenames.filter((filename) => filename !== "yarn.lock"), ".prettierrc", ".stylelintrc", + ".lintstagedrc", ], })), ]; diff --git a/tests/format/misc/insert-pragma/js/__snapshots__/jsfmt.spec.js.snap b/tests/format/misc/insert-pragma/js/__snapshots__/jsfmt.spec.js.snap index 8ec5cc9b2..93eafd4a8 100644 --- a/tests/format/misc/insert-pragma/js/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/misc/insert-pragma/js/__snapshots__/jsfmt.spec.js.snap @@ -262,3 +262,25 @@ printWidth: 80 ================================================================================ `; + +exports[`with-comment.js - {"insertPragma":true} format 1`] = ` +====================================options===================================== +insertPragma: true +parsers: ["flow", "babel", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +/* comment */ +foo() + +=====================================output===================================== +/** + * comment + * + * @format + */ + +foo(); + +================================================================================ +`; diff --git a/tests/format/misc/insert-pragma/js/with-comment.js b/tests/format/misc/insert-pragma/js/with-comment.js new file mode 100644 index 000000000..23f24e53c --- /dev/null +++ b/tests/format/misc/insert-pragma/js/with-comment.js @@ -0,0 +1,2 @@ +/* comment */ +foo() diff --git a/tests/integration/__tests__/__snapshots__/support-info.js.snap b/tests/integration/__tests__/__snapshots__/support-info.js.snap index 94289e4fb..284147437 100644 --- a/tests/integration/__tests__/__snapshots__/support-info.js.snap +++ b/tests/integration/__tests__/__snapshots__/support-info.js.snap @@ -774,7 +774,8 @@ exports[`CLI --support-info (stdout) 1`] = ` "CITATION.cff", "glide.lock", ".prettierrc", - ".stylelintrc" + ".stylelintrc", + ".lintstagedrc" ], "linguistLanguageId": 407, "name": "YAML", diff --git a/tests/integration/__tests__/with-parser-inference.js b/tests/integration/__tests__/with-parser-inference.js index 8d88e3ef7..32d205c21 100644 --- a/tests/integration/__tests__/with-parser-inference.js +++ b/tests/integration/__tests__/with-parser-inference.js @@ -70,4 +70,29 @@ describe("infers parser from filename", () => { ` + "\n" ); }); + + test("json from .lintstagedrc", () => { + expect( + prettier.format(" { '*': 'your-cmd' } ", { + filepath: "/path/to/.lintstagedrc", + }) + ).toBe('{ "*": "your-cmd" }\n'); + }); + + test("yaml from .lintstagedrc", () => { + expect( + prettier.format( + /* indent */ ` + '*': + - your-cmd + `, + { filepath: "/path/to/.lintstagedrc" } + ) + ).toBe( + outdent` + "*": + - your-cmd + ` + "\n" + ); + }); }); diff --git a/yarn.lock b/yarn.lock index a16a1c42d..9bbd48302 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4976,16 +4976,7 @@ __metadata: languageName: node linkType: hard -"jest-docblock@npm:28.0.2": - version: 28.0.2 - resolution: "jest-docblock@npm:28.0.2" - dependencies: - detect-newline: ^3.0.0 - checksum: 97aa9707127d5bfc4589485374711bbbb7d9049067fd562132592102f0b841682357eca9b95e35496f78538a2ae400b0b0a8b03f477d6773fc093be9f4716f1f - languageName: node - linkType: hard - -"jest-docblock@npm:^28.1.1": +"jest-docblock@npm:28.1.1, jest-docblock@npm:^28.1.1": version: 28.1.1 resolution: "jest-docblock@npm:28.1.1" dependencies: @@ -6881,7 +6872,7 @@ __metadata: html-void-elements: 2.0.1 ignore: 5.2.0 jest: 28.1.0 - jest-docblock: 28.0.2 + jest-docblock: 28.1.1 jest-light-runner: 0.2.2 jest-snapshot-serializer-ansi: 1.0.0 jest-snapshot-serializer-raw: 1.2.0