diff --git a/changelog_unreleased/javascript/13274.md b/changelog_unreleased/javascript/13274.md new file mode 100644 index 000000000..26466f984 --- /dev/null +++ b/changelog_unreleased/javascript/13274.md @@ -0,0 +1,34 @@ +#### Fix inconsistent formatting for multiline strings (#13274 by @GlebDolzhikov) + + +```jsx +// Input +const loremIpsumFooBazBar1 = 'Multiline string\ + Multiline string\ +' + +const loremIpsumFooBazBar2 = 'Multiline string\ + Multiline string\ + Multiline string' + +// Prettier stable +const loremIpsumFooBazBar1 = "Multiline string\ + Multiline string\ +"; + +const loremIpsumFooBazBar2 = + "Multiline string\ + Multiline string\ + Multiline string"; + +// Prettier main +const loremIpsumFooBazBar1 = + "Multiline string\ + Multiline string\ +"; + +const loremIpsumFooBazBar2 = + "Multiline string\ + Multiline string\ + Multiline string"; +``` diff --git a/changelog_unreleased/scss/13286.md b/changelog_unreleased/scss/13286.md new file mode 100644 index 000000000..d64d73195 --- /dev/null +++ b/changelog_unreleased/scss/13286.md @@ -0,0 +1,13 @@ +#### fix: extra space between '#' and '{' (#13286 by @jspereiramoura) + + +```scss +// Input +padding: var(--spacer#{(1) + 2}); + +// Prettier stable +padding: var(--spacer# {(1) + 2}); + +// Prettier main +padding: var(--spacer#{(1) + 2}); +``` diff --git a/changelog_unreleased/typescript/13289.md b/changelog_unreleased/typescript/13289.md new file mode 100644 index 000000000..7a4183c19 --- /dev/null +++ b/changelog_unreleased/typescript/13289.md @@ -0,0 +1,13 @@ +#### Fix parens in inferred function return types with `extends` (#13289 by @GlebDolzhikov) + + +```ts +// Input +type Foo = T extends (...a: any[]) => (infer R extends string) ? R : never; + +// Prettier stable +type Foo = T extends (...a: any[]) => infer R extends string ? R : never; + +// Prettier main +type Foo = T extends ((...a: any[]) => infer R extends string) ? R : never; +``` diff --git a/cspell.json b/cspell.json index 2690ee562..45249b3b9 100644 --- a/cspell.json +++ b/cspell.json @@ -14,6 +14,7 @@ "arrayify", "Artem", "Ascher", + "astro", "atrule", "atrules", "atword", @@ -215,6 +216,7 @@ "neoclide", "neoformat", "neovim", + "nginx", "nnoremap", "nocheck", "nonenumerable", @@ -355,6 +357,7 @@ "webstorm", "Weixin", "whitespaces", + "withastro", "wxss", "xdescribe", "xtest", diff --git a/docs/plugins.md b/docs/plugins.md index d60c5bf08..8dcd3546a 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -58,6 +58,7 @@ To turn off plugin autoloading, use `--no-plugin-search` when using Prettier CLI ## Community Plugins - [`prettier-plugin-apex`](https://github.com/dangmai/prettier-plugin-apex) by [**@dangmai**](https://github.com/dangmai) +- [`prettier-plugin-astro`](https://github.com/withastro/prettier-plugin-astro) by [**@withastro contributors**](https://github.com/withastro/prettier-plugin-astro/graphs/contributors) - [`prettier-plugin-elm`](https://github.com/gicentre/prettier-plugin-elm) by [**@giCentre**](https://github.com/gicentre) - [`prettier-plugin-erb`](https://github.com/adamzapasnik/prettier-plugin-erb) by [**@adamzapasnik**](https://github.com/adamzapasnik) - [`prettier-plugin-glsl`](https://github.com/NaridaL/glsl-language-toolkit/tree/main/packages/prettier-plugin-glsl) by [**@NaridaL**](https://github.com/NaridaL) @@ -65,6 +66,8 @@ To turn off plugin autoloading, use `--no-plugin-search` when using Prettier CLI - [`prettier-plugin-java`](https://github.com/jhipster/prettier-java) by [**@JHipster**](https://github.com/jhipster) - [`prettier-plugin-jsonata`](https://github.com/Stedi/prettier-plugin-jsonata) by [**@Stedi**](https://github.com/Stedi) - [`prettier-plugin-kotlin`](https://github.com/Angry-Potato/prettier-plugin-kotlin) by [**@Angry-Potato**](https://github.com/Angry-Potato) +- [`prettier-plugin-nginx`](https://github.com/joedeandev/prettier-plugin-nginx) by [**@joedeandev**](https://github.com/joedeandev) +- [`prettier-plugin-prisma`](https://github.com/umidbekk/prettier-plugin-prisma) by [**@umidbekk**](https://github.com/umidbekk) - [`prettier-plugin-properties`](https://github.com/eemeli/prettier-plugin-properties) by [**@eemeli**](https://github.com/eemeli) - [`prettier-plugin-sh`](https://github.com/un-ts/prettier/tree/master/packages/sh) by [**@JounQin**](https://github.com/JounQin) - [`prettier-plugin-sql`](https://github.com/un-ts/prettier/tree/master/packages/sql) by [**@JounQin**](https://github.com/JounQin) diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index b7dd826de..325c63eb7 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -832,6 +832,14 @@ function genericPrint(path, options, print) { continue; } + if ( + iNode.value?.endsWith("#") && + iNextNode.value === "{" && + isParenGroupNode(iNextNode.group) + ) { + continue; + } + // Be default all values go through `line` parts.push(line); } diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index af60560fc..01ba7a8da 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -410,6 +410,16 @@ function needsParens(path, options) { // fallthrough case "TSFunctionType": case "TSConstructorType": + if (name === "extendsType" && parent.type === "TSConditionalType") { + const returnTypeAnnotation = (node.returnType || node.typeAnnotation) + .typeAnnotation; + if ( + returnTypeAnnotation.type === "TSInferType" && + returnTypeAnnotation.typeParameter.constraint + ) { + return true; + } + } if (name === "checkType" && parent.type === "TSConditionalType") { return true; } diff --git a/src/language-js/print/flow.js b/src/language-js/print/flow.js index 09b699e83..0f7643bd2 100644 --- a/src/language-js/print/flow.js +++ b/src/language-js/print/flow.js @@ -4,6 +4,7 @@ import assert from "node:assert"; import { printDanglingComments } from "../../main/comments.js"; import { printString, printNumber } from "../../common/util.js"; import { hardline, softline, group, indent } from "../../document/builders.js"; +import { replaceTextEndOfLine } from "../../document/utils.js"; import { getParentExportDeclaration, isFunctionNotation, @@ -268,7 +269,7 @@ function printFlow(path, options, print) { case "QualifiedTypeIdentifier": return [print("qualification"), ".", print("id")]; case "StringLiteralTypeAnnotation": - return printString(rawText(node), options); + return replaceTextEndOfLine(printString(rawText(node), options)); case "NumberLiteralTypeAnnotation": assert.strictEqual(typeof node.value, "number"); // fall through diff --git a/src/language-js/print/literal.js b/src/language-js/print/literal.js index bafba771a..b007a48d8 100644 --- a/src/language-js/print/literal.js +++ b/src/language-js/print/literal.js @@ -1,4 +1,5 @@ import { printString, printNumber } from "../../common/util.js"; +import { replaceTextEndOfLine } from "../../document/utils.js"; function printLiteral(path, options /*, print*/) { const node = path.getNode(); @@ -12,7 +13,7 @@ function printLiteral(path, options /*, print*/) { case "NumericLiteral": // Babel 6 Literal split return printNumber(node.extra.raw); case "StringLiteral": // Babel 6 Literal split - return printString(node.extra.raw, options); + return replaceTextEndOfLine(printString(node.extra.raw, options)); case "NullLiteral": // Babel 6 Literal split return "null"; case "BooleanLiteral": // Babel 6 Literal split @@ -39,7 +40,7 @@ function printLiteral(path, options /*, print*/) { } if (typeof value === "string") { - return printString(node.raw, options); + return replaceTextEndOfLine(printString(node.raw, options)); } return String(value); diff --git a/tests/format/flow/literal/__snapshots__/jsfmt.spec.js.snap b/tests/format/flow/literal/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..bafcf8a56 --- /dev/null +++ b/tests/format/flow/literal/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`multiline.js format 1`] = ` +====================================options===================================== +parsers: ["flow", "babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +type loremIpsumFooBazBar1 = 'Multiline string\\ + Multiline string' + +type loremIpsumFooBazBar2 = 'Multiline string\\ + Multiline string\\ + Multiline string' + +=====================================output===================================== +type loremIpsumFooBazBar1 = + "Multiline string\\ + Multiline string"; + +type loremIpsumFooBazBar2 = + "Multiline string\\ + Multiline string\\ + Multiline string"; + +================================================================================ +`; diff --git a/tests/format/flow/literal/jsfmt.spec.js b/tests/format/flow/literal/jsfmt.spec.js new file mode 100644 index 000000000..fbfa6501a --- /dev/null +++ b/tests/format/flow/literal/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["flow", "babel"]); diff --git a/tests/format/flow/literal/multiline.js b/tests/format/flow/literal/multiline.js new file mode 100644 index 000000000..22648828e --- /dev/null +++ b/tests/format/flow/literal/multiline.js @@ -0,0 +1,6 @@ +type loremIpsumFooBazBar1 = 'Multiline string\ + Multiline string' + +type loremIpsumFooBazBar2 = 'Multiline string\ + Multiline string\ + Multiline string' diff --git a/tests/format/js/strings/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/strings/__snapshots__/jsfmt.spec.js.snap index 09ba47f0c..999978e14 100644 --- a/tests/format/js/strings/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/strings/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,70 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`multiline-literal.js - {"trailingComma":"all"} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow"] +printWidth: 80 +trailingComma: "all" + | printWidth +=====================================input====================================== +// https://github.com/prettier/prettier/pull/13274 + +const loremIpsumFooBazBar1 = 'Multiline string\\ + Multiline string\\ +' + +const loremIpsumFooBazBar2 = 'Multiline string\\ + Multiline string\\ + Multiline string' + +=====================================output===================================== +// https://github.com/prettier/prettier/pull/13274 + +const loremIpsumFooBazBar1 = + "Multiline string\\ + Multiline string\\ +"; + +const loremIpsumFooBazBar2 = + "Multiline string\\ + Multiline string\\ + Multiline string"; + +================================================================================ +`; + +exports[`multiline-literal.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow"] +printWidth: 80 + | printWidth +=====================================input====================================== +// https://github.com/prettier/prettier/pull/13274 + +const loremIpsumFooBazBar1 = 'Multiline string\\ + Multiline string\\ +' + +const loremIpsumFooBazBar2 = 'Multiline string\\ + Multiline string\\ + Multiline string' + +=====================================output===================================== +// https://github.com/prettier/prettier/pull/13274 + +const loremIpsumFooBazBar1 = + "Multiline string\\ + Multiline string\\ +"; + +const loremIpsumFooBazBar2 = + "Multiline string\\ + Multiline string\\ + Multiline string"; + +================================================================================ +`; + exports[`non-octal-eight-and-nine.js [acorn] format 1`] = ` "Invalid escape sequence (3:3) 1 | // https://github.com/babel/babel/pull/11852 diff --git a/tests/format/js/strings/multiline-literal.js b/tests/format/js/strings/multiline-literal.js new file mode 100644 index 000000000..fcecf64f3 --- /dev/null +++ b/tests/format/js/strings/multiline-literal.js @@ -0,0 +1,9 @@ +// https://github.com/prettier/prettier/pull/13274 + +const loremIpsumFooBazBar1 = 'Multiline string\ + Multiline string\ +' + +const loremIpsumFooBazBar2 = 'Multiline string\ + Multiline string\ + Multiline string' diff --git a/tests/format/scss/variables/__snapshots__/jsfmt.spec.js.snap b/tests/format/scss/variables/__snapshots__/jsfmt.spec.js.snap index 4e99ead7f..07e8aa4d6 100644 --- a/tests/format/scss/variables/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/scss/variables/__snapshots__/jsfmt.spec.js.snap @@ -132,6 +132,7 @@ printWidth: 80 prop1: var(--#{$var}); prop2: var(#{$var}, --my-#{$var}, pink); prop3: calc(var(--#{$var}) * 1px); + prop4: var(--spacer#{(1) + 2}); } @supports (--#{$prop}: green) { @@ -147,6 +148,7 @@ printWidth: 80 prop1: var(--#{$var}); prop2: var(#{$var}, --my-#{$var}, pink); prop3: calc(var(--#{$var}) * 1px); + prop4: var(--spacer#{(1) + 2}); } @supports (--#{$prop}: green) { diff --git a/tests/format/scss/variables/variables.scss b/tests/format/scss/variables/variables.scss index 35e7c6e9b..577714686 100644 --- a/tests/format/scss/variables/variables.scss +++ b/tests/format/scss/variables/variables.scss @@ -4,6 +4,7 @@ prop1: var(--#{$var}); prop2: var(#{$var}, --my-#{$var}, pink); prop3: calc(var(--#{$var}) * 1px); + prop4: var(--spacer#{(1) + 2}); } @supports (--#{$prop}: green) { diff --git a/tests/format/typescript/conditional-types/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/conditional-types/__snapshots__/jsfmt.spec.js.snap index d109f4511..7231c3da4 100644 --- a/tests/format/typescript/conditional-types/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/typescript/conditional-types/__snapshots__/jsfmt.spec.js.snap @@ -278,6 +278,20 @@ type Unpacked = T extends (infer U)[] ================================================================================ `; +exports[`issue-13275.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +type Foo = T extends ((...a: any[]) => infer R extends string) ? R : never; + +=====================================output===================================== +type Foo = T extends ((...a: any[]) => infer R extends string) ? R : never; + +================================================================================ +`; + exports[`nested-in-condition.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] diff --git a/tests/format/typescript/conditional-types/issue-13275.ts b/tests/format/typescript/conditional-types/issue-13275.ts new file mode 100644 index 000000000..de1ccb285 --- /dev/null +++ b/tests/format/typescript/conditional-types/issue-13275.ts @@ -0,0 +1 @@ +type Foo = T extends ((...a: any[]) => infer R extends string) ? R : never; diff --git a/tests/format/typescript/literal/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/literal/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..cb42c67fc --- /dev/null +++ b/tests/format/typescript/literal/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`multiline.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +type loremIpsumFooBazBar1 = 'Multiline string\\ + Multiline string' + +type loremIpsumFooBazBar2 = 'Multiline string\\ + Multiline string\\ + Multiline string' + +=====================================output===================================== +type loremIpsumFooBazBar1 = "Multiline string\\ + Multiline string"; + +type loremIpsumFooBazBar2 = "Multiline string\\ + Multiline string\\ + Multiline string"; + +================================================================================ +`; diff --git a/tests/format/typescript/literal/jsfmt.spec.js b/tests/format/typescript/literal/jsfmt.spec.js new file mode 100644 index 000000000..2ea3bb6eb --- /dev/null +++ b/tests/format/typescript/literal/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["typescript"]); diff --git a/tests/format/typescript/literal/multiline.ts b/tests/format/typescript/literal/multiline.ts new file mode 100644 index 000000000..22648828e --- /dev/null +++ b/tests/format/typescript/literal/multiline.ts @@ -0,0 +1,6 @@ +type loremIpsumFooBazBar1 = 'Multiline string\ + Multiline string' + +type loremIpsumFooBazBar2 = 'Multiline string\ + Multiline string\ + Multiline string'