From cf36209a271629ec682c41a3489a3c0da901e77d Mon Sep 17 00:00:00 2001 From: Cyrille David Date: Wed, 4 Jan 2023 11:49:24 +0100 Subject: [PATCH 01/12] Handlebars: Add tests for `{{! prettier-ignore}}` (#13693) --- .../__snapshots__/jsfmt.spec.js.snap | 44 +++++++++++++++++++ .../prettier-ignore/prettier-ignore.hbs | 23 +++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/tests/format/handlebars/prettier-ignore/__snapshots__/jsfmt.spec.js.snap b/tests/format/handlebars/prettier-ignore/__snapshots__/jsfmt.spec.js.snap index de2480488..68980791d 100644 --- a/tests/format/handlebars/prettier-ignore/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/handlebars/prettier-ignore/__snapshots__/jsfmt.spec.js.snap @@ -6,6 +6,27 @@ parsers: ["glimmer"] printWidth: 80 | printWidth =====================================input====================================== +{{! prettier-ignore }} +{{ ugly}} + +{{! prettier-ignore }}{{ ugly}} + +{{! prettier-ignore }} + ugly + +{{! prettier-ignore }} ugly + +{{! prettier-ignore }} +{{# ugly}} +{{/ ugly}} + +{{! prettier-ignore }}{{# ugly}}{{/ ugly}} + +{{! prettier-ignore }} +{{! ugly}} + +{{! prettier-ignore }}{{! ugly}} + {{! prettier-ignore }}
"hello! my parent was ignored" @@ -40,7 +61,30 @@ printWidth: 80 {{/another-sibling}}
+ =====================================output===================================== +{{! prettier-ignore }} +{{ ugly}} + +{{! prettier-ignore }}{{ugly}} + +{{! prettier-ignore }} +ugly + +{{! prettier-ignore }} +ugly + +{{! prettier-ignore }} +{{# ugly}} +{{/ ugly}} + +{{! prettier-ignore }}{{#ugly}}{{/ugly}} + +{{! prettier-ignore }} +{{! ugly}} + +{{! prettier-ignore }}{{! ugly}} + {{! prettier-ignore }}
"hello! my parent was ignored" diff --git a/tests/format/handlebars/prettier-ignore/prettier-ignore.hbs b/tests/format/handlebars/prettier-ignore/prettier-ignore.hbs index cfe3574a1..b2a3b5c0a 100644 --- a/tests/format/handlebars/prettier-ignore/prettier-ignore.hbs +++ b/tests/format/handlebars/prettier-ignore/prettier-ignore.hbs @@ -1,3 +1,24 @@ +{{! prettier-ignore }} +{{ ugly}} + +{{! prettier-ignore }}{{ ugly}} + +{{! prettier-ignore }} + ugly + +{{! prettier-ignore }} ugly + +{{! prettier-ignore }} +{{# ugly}} +{{/ ugly}} + +{{! prettier-ignore }}{{# ugly}}{{/ ugly}} + +{{! prettier-ignore }} +{{! ugly}} + +{{! prettier-ignore }}{{! ugly}} + {{! prettier-ignore }}
"hello! my parent was ignored" @@ -31,4 +52,4 @@
{{/another-sibling}} -
\ No newline at end of file + From b77d912c0c1a5df85e3e9b5b192fc92523e411ee Mon Sep 17 00:00:00 2001 From: Cyrille David Date: Wed, 4 Jan 2023 11:51:39 +0100 Subject: [PATCH 02/12] ember / glimmer: Preserve self-closing tags (#13691) --- changelog_unreleased/handlebars/13691.md | 34 +++++++++++++++++++ src/language-handlebars/utils.js | 1 + .../__snapshots__/jsfmt.spec.js.snap | 18 ++++++++++ .../handlebars/element-node/element-node.hbs | 9 +++++ .../__snapshots__/jsfmt.spec.js.snap | 2 +- .../__snapshots__/jsfmt.spec.js.snap | 12 +++---- 6 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 changelog_unreleased/handlebars/13691.md diff --git a/changelog_unreleased/handlebars/13691.md b/changelog_unreleased/handlebars/13691.md new file mode 100644 index 000000000..ab836c2d1 --- /dev/null +++ b/changelog_unreleased/handlebars/13691.md @@ -0,0 +1,34 @@ +#### Preserve self-closing tags (#13691 by @dcyriller) + + +```hbs +{{! Input }} +
+
+ + + + + + + +{{! Prettier stable }} +
+
+ + + + + + + +{{! Prettier main }} +
+
+ + + + + + +``` diff --git a/src/language-handlebars/utils.js b/src/language-handlebars/utils.js index 07e4c5754..aef7f46f8 100644 --- a/src/language-handlebars/utils.js +++ b/src/language-handlebars/utils.js @@ -41,6 +41,7 @@ const voidTags = new Set(htmlVoidElements); function isVoid(node) { return ( voidTags.has(node.tag) || + node.selfClosing === true || (isGlimmerComponent(node) && node.children.every((node) => isWhitespaceNode(node))) ); diff --git a/tests/format/handlebars/element-node/__snapshots__/jsfmt.spec.js.snap b/tests/format/handlebars/element-node/__snapshots__/jsfmt.spec.js.snap index 7d36706bc..c1aeb2e78 100644 --- a/tests/format/handlebars/element-node/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/handlebars/element-node/__snapshots__/jsfmt.spec.js.snap @@ -45,6 +45,15 @@ printWidth: 80 +
+
+ + + + + + + =====================================output=====================================
Hello @@ -91,5 +100,14 @@ printWidth: 80 @prop4={{true}} as |thing| /> + +
+
+ + + + + + ================================================================================ `; diff --git a/tests/format/handlebars/element-node/element-node.hbs b/tests/format/handlebars/element-node/element-node.hbs index 0c12a8da0..c4ed2d380 100644 --- a/tests/format/handlebars/element-node/element-node.hbs +++ b/tests/format/handlebars/element-node/element-node.hbs @@ -36,3 +36,12 @@ + +
+
+ + + + + + diff --git a/tests/format/handlebars/html-whitespace-sensitivity/__snapshots__/jsfmt.spec.js.snap b/tests/format/handlebars/html-whitespace-sensitivity/__snapshots__/jsfmt.spec.js.snap index 33cc64a94..73daa2ee6 100644 --- a/tests/format/handlebars/html-whitespace-sensitivity/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/handlebars/html-whitespace-sensitivity/__snapshots__/jsfmt.spec.js.snap @@ -702,7 +702,7 @@ printWidth: 40 =====================================input======================================   |   =====================================output===================================== -   |   +   |   ================================================================================ `; diff --git a/tests/format/handlebars/single-quote-option/__snapshots__/jsfmt.spec.js.snap b/tests/format/handlebars/single-quote-option/__snapshots__/jsfmt.spec.js.snap index 4229856d7..a26517e85 100644 --- a/tests/format/handlebars/single-quote-option/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/handlebars/single-quote-option/__snapshots__/jsfmt.spec.js.snap @@ -99,8 +99,8 @@ singleQuote: false
-
-
+
+
@@ -126,7 +126,7 @@ singleQuote: false class="padding {{if foo (if fooAgain 'bar' (if fooAgainAgain 'bar' 'foo'))}} baz" ->
+/> ================================================================================ `; @@ -161,8 +161,8 @@ singleQuote: true
-
-
+
+
@@ -188,7 +188,7 @@ singleQuote: true class='padding {{if foo (if fooAgain "bar" (if fooAgainAgain "bar" "foo"))}} baz' ->
+/> ================================================================================ `; From 0c5d4f34587817d1da09fc04a03e49fb5c048a76 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Fri, 6 Jan 2023 17:13:41 +0900 Subject: [PATCH 03/12] Fix removing commas from function arguments in maps (#14089) Co-authored-by: fisker Cheung --- changelog_unreleased/scss/14089.md | 22 ++++++++ src/language-css/parser-postcss.js | 17 ------- src/language-css/printer-postcss.js | 29 ++++++----- .../__snapshots__/jsfmt.spec.js.snap | 51 +++++++++++++++++++ .../function-argument-2.scss | 18 +++++++ 5 files changed, 106 insertions(+), 31 deletions(-) create mode 100644 changelog_unreleased/scss/14089.md create mode 100644 tests/format/scss/map/function-argument/function-argument-2.scss diff --git a/changelog_unreleased/scss/14089.md b/changelog_unreleased/scss/14089.md new file mode 100644 index 000000000..45e6ce284 --- /dev/null +++ b/changelog_unreleased/scss/14089.md @@ -0,0 +1,22 @@ +#### Fix removing commas from function arguments in maps (#14089 by @sosukesuzuki) + + +```scss +/* Input */ +$foo: map-fn( + ( + "#{prop}": inner-fn($first, $second), + ) +); + +/* Prettier stable */ +$foo: map-fn(("#{prop}": inner-fn($first $second))); + +/* Prettier main */ +$foo: map-fn( + ( + "#{prop}": inner-fn($first, $second), + ) +); + +``` diff --git a/src/language-css/parser-postcss.js b/src/language-css/parser-postcss.js index 13b42c467..652f968f9 100644 --- a/src/language-css/parser-postcss.js +++ b/src/language-css/parser-postcss.js @@ -122,23 +122,6 @@ function parseValueNode(valueNode, options) { parenGroupStack.pop(); parenGroup = getLast(parenGroupStack); } else if (node.type === "comma") { - if (commaGroup.groups.length > 1) { - for (const group of commaGroup.groups) { - // if css interpolation - if ( - group.value && - typeof group.value === "string" && - group.value.includes("#{") - ) { - commaGroup.groups = [ - stringifyNode({ - groups: commaGroup.groups, - }).trim(), - ]; - break; - } - } - } parenGroup.groups.push(commaGroup); commaGroup = { groups: [], diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index c847279b3..44d11d502 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -547,6 +547,7 @@ function genericPrint(path, options, print) { let insideSCSSInterpolationInString = false; let didBreak = false; + for (let i = 0; i < node.groups.length; ++i) { parts.push(printed[i]); @@ -594,20 +595,20 @@ function genericPrint(path, options, print) { } // Ignore spaces before/after string interpolation (i.e. `"#{my-fn("_")}"`) - const isStartSCSSInterpolationInString = - iNode.type === "value-string" && iNode.value.startsWith("#{"); - const isEndingSCSSInterpolationInString = - insideSCSSInterpolationInString && - iNextNode.type === "value-string" && - iNextNode.value.endsWith("}"); - - if ( - isStartSCSSInterpolationInString || - isEndingSCSSInterpolationInString - ) { - insideSCSSInterpolationInString = !insideSCSSInterpolationInString; - - continue; + if (iNode.type === "value-string" && iNode.quoted) { + const positionOfOpeningInterpolation = iNode.value.lastIndexOf("#{"); + const positionOfClosingInterpolation = iNode.value.lastIndexOf("}"); + if ( + positionOfOpeningInterpolation !== -1 && + positionOfClosingInterpolation !== -1 + ) { + insideSCSSInterpolationInString = + positionOfOpeningInterpolation > positionOfClosingInterpolation; + } else if (positionOfOpeningInterpolation !== -1) { + insideSCSSInterpolationInString = true; + } else if (positionOfClosingInterpolation !== -1) { + insideSCSSInterpolationInString = false; + } } if (insideSCSSInterpolationInString) { diff --git a/tests/format/scss/map/function-argument/__snapshots__/jsfmt.spec.js.snap b/tests/format/scss/map/function-argument/__snapshots__/jsfmt.spec.js.snap index 0ea75e6bb..e74fed620 100644 --- a/tests/format/scss/map/function-argument/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/scss/map/function-argument/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,56 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`function-argument-2.scss format 1`] = ` +====================================options===================================== +parsers: ["scss"] +printWidth: 80 + | printWidth +=====================================input====================================== +$display-breakpoints: map-deep-merge( + ( + "sm-only": "only screen and (min-width: #{$map-get + $grid-breakpoints + "hogehoge"}) and (max-width: #{$a})", + "sm-only": "inside a long long long long long long long long long long long long long long string #{call("")}", + "sm-only": "inside a long long long long long long long long long long long long long long string #{$foo} and #{call("")}", + "sm-only": "inside a long long long long long long long long long long long long long long string #{call($a)}", + ), + $display-breakpoints +); + +@each $name, $hue in $hues { + $map: map.merge( + $map, + ( + '#{$prefix}-#{$name}': blend.set($base, $hue: $hue), + ) + ); +} + +=====================================output===================================== +$display-breakpoints: map-deep-merge( + ( + "sm-only": "only screen and (min-width: #{$map-get + $grid-breakpoints + "hogehoge"}) and (max-width: #{$a})", + "sm-only": + "inside a long long long long long long long long long long long long long long string #{call("")}", + "sm-only": + "inside a long long long long long long long long long long long long long long string #{$foo} and #{call("")}", + "sm-only": + "inside a long long long long long long long long long long long long long long string #{call($a)}", + ), + $display-breakpoints +); + +@each $name, $hue in $hues { + $map: map.merge( + $map, + ( + "#{$prefix}-#{$name}": blend.set($base, $hue: $hue), + ) + ); +} + +================================================================================ +`; + exports[`functional-argument.scss format 1`] = ` ====================================options===================================== parsers: ["scss"] diff --git a/tests/format/scss/map/function-argument/function-argument-2.scss b/tests/format/scss/map/function-argument/function-argument-2.scss new file mode 100644 index 000000000..4af8674e8 --- /dev/null +++ b/tests/format/scss/map/function-argument/function-argument-2.scss @@ -0,0 +1,18 @@ +$display-breakpoints: map-deep-merge( + ( + "sm-only": "only screen and (min-width: #{$map-get + $grid-breakpoints + "hogehoge"}) and (max-width: #{$a})", + "sm-only": "inside a long long long long long long long long long long long long long long string #{call("")}", + "sm-only": "inside a long long long long long long long long long long long long long long string #{$foo} and #{call("")}", + "sm-only": "inside a long long long long long long long long long long long long long long string #{call($a)}", + ), + $display-breakpoints +); + +@each $name, $hue in $hues { + $map: map.merge( + $map, + ( + '#{$prefix}-#{$name}': blend.set($base, $hue: $hue), + ) + ); +} From 9e09a78cf50e47535688b3f9ca4f24f440cfe012 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Sat, 7 Jan 2023 16:43:15 +0800 Subject: [PATCH 04/12] Stop inserting space in LESS property access (#14103) --- changelog_unreleased/less/14103.md | 17 ++++++++++++++ src/language-css/clean.js | 21 ++++++++++++++++++ src/language-css/printer-postcss.js | 21 +++++++++++++++++- .../case/__snapshots__/jsfmt.spec.js.snap | 22 ++++++++++++++----- tests/format/less/case/variable.less | 6 +++++ 5 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 changelog_unreleased/less/14103.md diff --git a/changelog_unreleased/less/14103.md b/changelog_unreleased/less/14103.md new file mode 100644 index 000000000..cddb91e0f --- /dev/null +++ b/changelog_unreleased/less/14103.md @@ -0,0 +1,17 @@ +#### Do not insert space in LESS property access (#14103 by @fisker) + + +```less +// Input +a { + color: @colors[@white]; +} + +// Prettier stable +a { + color: @colors[ @white]; +} + +// Prettier main + +``` diff --git a/src/language-css/clean.js b/src/language-css/clean.js index 8dc592570..eee08eda6 100644 --- a/src/language-css/clean.js +++ b/src/language-css/clean.js @@ -183,6 +183,27 @@ function clean(ast, newObj, parent) { }); } } + + // We parse `@var[ foo ]` and `@var[foo]` differently + if ( + ast.type === "value-comma_group" && + ast.groups.some( + (node) => + (node.type === "value-atword" && node.value.endsWith("[")) || + (node.type === "value-word" && node.value.startsWith("]")) + ) + ) { + return { + type: "value-atword", + value: ast.groups.map((node) => node.value).join(""), + group: { + open: null, + close: null, + groups: [], + type: "value-paren_group", + }, + }; + } } clean.ignoredProperties = ignoredProperties; diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index 44d11d502..ca5719e93 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -621,7 +621,26 @@ function genericPrint(path, options, print) { } // Ignore `@` in Less (i.e. `@@var;`) - if (iNode.type === "value-atword" && iNode.value === "") { + if ( + iNode.type === "value-atword" && + (iNode.value === "" || + /* + @var[ @notVarNested ][notVar] + ^^^^^ + */ + iNode.value.endsWith("[")) + ) { + continue; + } + + /* + @var[ @notVarNested ][notVar] + ^^^^^^^^^ + */ + if ( + iNextNode.type === "value-word" && + iNextNode.value.startsWith("]") + ) { continue; } diff --git a/tests/format/less/case/__snapshots__/jsfmt.spec.js.snap b/tests/format/less/case/__snapshots__/jsfmt.spec.js.snap index 9abe3bd1d..f67031abd 100644 --- a/tests/format/less/case/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/less/case/__snapshots__/jsfmt.spec.js.snap @@ -389,9 +389,15 @@ printWidth: 80 canChangeCase: @var[@notVarNested][notVar]; canChangeCase: @var[ @notVarNested][notVar]; canChangeCase: @var[@notVarNested ][notVar]; + canChangeCase: @var[ @notVarNested ][notVar]; + canChangeCase: @var[@notVarNested][notVar]; canChangeCase: @var[@notVarNested][ notVar]; canChangeCase: @var[@notVarNested][notVar ]; + canChangeCase: @var[@notVarNested][ notVar ]; canChangeCase: @var[notVar]; + canChangeCase: @var[ notVar]; + canChangeCase: @var[notVar ]; + canChangeCase: @var[ notVar ]; } =====================================output===================================== @@ -453,11 +459,17 @@ printWidth: 80 }; @not-var { - canchangecase: @var[ @notVarNested][notVar]; - canchangecase: @var[ @notVarNested][notVar]; - canchangecase: @var[ @notVarNested ][notVar]; - canchangecase: @var[ @notVarNested][ notVar]; - canchangecase: @var[ @notVarNested][notVar ]; + canchangecase: @var[@notVarNested][notVar]; + canchangecase: @var[@notVarNested][notVar]; + canchangecase: @var[@notVarNested][notVar]; + canchangecase: @var[@notVarNested][notVar]; + canchangecase: @var[@notVarNested][notVar]; + canchangecase: @var[@notVarNested][notVar]; + canchangecase: @var[@notVarNested][notVar]; + canchangecase: @var[@notVarNested][notVar]; + canchangecase: @var[notVar]; + canchangecase: @var[notVar]; + canchangecase: @var[notVar]; canchangecase: @var[notVar]; } diff --git a/tests/format/less/case/variable.less b/tests/format/less/case/variable.less index 29fdd9052..599c34754 100644 --- a/tests/format/less/case/variable.less +++ b/tests/format/less/case/variable.less @@ -59,7 +59,13 @@ canChangeCase: @var[@notVarNested][notVar]; canChangeCase: @var[ @notVarNested][notVar]; canChangeCase: @var[@notVarNested ][notVar]; + canChangeCase: @var[ @notVarNested ][notVar]; + canChangeCase: @var[@notVarNested][notVar]; canChangeCase: @var[@notVarNested][ notVar]; canChangeCase: @var[@notVarNested][notVar ]; + canChangeCase: @var[@notVarNested][ notVar ]; canChangeCase: @var[notVar]; + canChangeCase: @var[ notVar]; + canChangeCase: @var[notVar ]; + canChangeCase: @var[ notVar ]; } From aaf919014fbdb3c05590f818428de4dcc6899c9c Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Sat, 7 Jan 2023 16:43:44 +0800 Subject: [PATCH 05/12] Fix comments after directive (#14081) --- changelog_unreleased/javascript/14081.md | 13 + src/language-js/print/literal.js | 14 +- src/language-js/print/misc.js | 19 + src/language-js/printer-estree.js | 28 +- .../comments/__snapshots__/jsfmt.spec.js.snap | 569 ++++++++++++++++++ .../js/directives/comments/jsfmt.spec.js | 55 ++ tests/format/markdown/auto-link/jsfmt.spec.js | 1 + 7 files changed, 672 insertions(+), 27 deletions(-) create mode 100644 changelog_unreleased/javascript/14081.md create mode 100644 tests/format/js/directives/comments/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/format/js/directives/comments/jsfmt.spec.js diff --git a/changelog_unreleased/javascript/14081.md b/changelog_unreleased/javascript/14081.md new file mode 100644 index 000000000..92a794cbc --- /dev/null +++ b/changelog_unreleased/javascript/14081.md @@ -0,0 +1,13 @@ +#### Fix comments after directive (#14081 by @fisker) + + +```jsx +// Input +"use strict" /* comment */; + +// Prettier stable (with other js parsers except `babel`) +Error: Comment "comment" was not printed. Please report this error! + +// Prettier main + +``` diff --git a/src/language-js/print/literal.js b/src/language-js/print/literal.js index a614bd5f4..252cf4925 100644 --- a/src/language-js/print/literal.js +++ b/src/language-js/print/literal.js @@ -1,6 +1,7 @@ "use strict"; const { printString, printNumber } = require("../../common/util.js"); const { replaceTextEndOfLine } = require("../../document/doc-utils.js"); +const { printDirective } = require("./misc.js"); function printLiteral(path, options /*, print*/) { const node = path.getNode(); @@ -41,7 +42,9 @@ function printLiteral(path, options /*, print*/) { } if (typeof value === "string") { - return replaceTextEndOfLine(printString(node.raw, options)); + return isDirective(path) + ? printDirective(node.raw, options) + : replaceTextEndOfLine(printString(node.raw, options)); } return String(value); @@ -49,6 +52,15 @@ function printLiteral(path, options /*, print*/) { } } +function isDirective(path) { + if (path.getName() !== "expression") { + return; + } + + const parent = path.getParentNode(); + return parent.type === "ExpressionStatement" && parent.directive; +} + function printBigInt(raw) { return raw.toLowerCase(); } diff --git a/src/language-js/print/misc.js b/src/language-js/print/misc.js index 3d5a7d0f8..44ae0ce9c 100644 --- a/src/language-js/print/misc.js +++ b/src/language-js/print/misc.js @@ -93,6 +93,24 @@ function printRestSpread(path, options, print) { return ["...", print("argument"), printTypeAnnotation(path, options, print)]; } +function printDirective(rawText, options) { + const rawContent = rawText.slice(1, -1); + + // Check for the alternate quote, to determine if we're allowed to swap + // the quotes on a DirectiveLiteral. + if (rawContent.includes('"') || rawContent.includes("'")) { + return rawText; + } + + const enclosingQuote = options.singleQuote ? "'" : '"'; + + // Directives are exact code unit sequences, which means that you can't + // change the escape sequences they use. + // See https://github.com/prettier/prettier/issues/1555 + // and https://tc39.github.io/ecma262/#directive-prologue + return enclosingQuote + rawContent + enclosingQuote; +} + module.exports = { printOptionalToken, printDefiniteToken, @@ -102,4 +120,5 @@ module.exports = { printTypeAnnotation, printRestSpread, adjustClause, + printDirective, }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 75e8a71f8..6d76502f7 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -23,7 +23,6 @@ const { isLineComment, isNextLineEmpty, needsHardlineAfterDanglingComment, - rawText, hasIgnoreComment, isCallExpression, isMemberExpression, @@ -47,6 +46,7 @@ const { adjustClause, printRestSpread, printDefiniteToken, + printDirective, } = require("./print/misc.js"); const { printImportDeclaration, @@ -215,11 +215,6 @@ function printPathNoParens(path, options, print, args) { case "EmptyStatement": return ""; case "ExpressionStatement": { - // Detect Flow and TypeScript directives - if (node.directive) { - return [printDirective(node.expression, options), semi]; - } - if ( options.parser === "__vue_event_binding" || options.parser === "__vue_ts_event_binding" @@ -429,7 +424,7 @@ function printPathNoParens(path, options, print, args) { case "Directive": return [print("value"), semi]; // Babel 6 case "DirectiveLiteral": - return printDirective(node, options); + return printDirective(node.extra.raw, options); case "UnaryExpression": parts.push(node.operator); @@ -813,25 +808,6 @@ function printPathNoParens(path, options, print, args) { } } -function printDirective(node, options) { - const raw = rawText(node); - const rawContent = raw.slice(1, -1); - - // Check for the alternate quote, to determine if we're allowed to swap - // the quotes on a DirectiveLiteral. - if (rawContent.includes('"') || rawContent.includes("'")) { - return raw; - } - - const enclosingQuote = options.singleQuote ? "'" : '"'; - - // Directives are exact code unit sequences, which means that you can't - // change the escape sequences they use. - // See https://github.com/prettier/prettier/issues/1555 - // and https://tc39.github.io/ecma262/#directive-prologue - return enclosingQuote + rawContent + enclosingQuote; -} - function canAttachComment(node) { return ( node.type && diff --git a/tests/format/js/directives/comments/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/directives/comments/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..62f891b2f --- /dev/null +++ b/tests/format/js/directives/comments/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,569 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`snippet: #0 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +/* comment */ 'use strict'; +=====================================output===================================== +/* comment */ "use strict" + +================================================================================ +`; + +exports[`snippet: #0 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +/* comment */ 'use strict'; +=====================================output===================================== +/* comment */ "use strict"; + +================================================================================ +`; + +exports[`snippet: #1 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +function foo() { + /* comment */ 'use strict'; +} +=====================================output===================================== +function foo() { + /* comment */ "use strict" +} + +================================================================================ +`; + +exports[`snippet: #1 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +function foo() { + /* comment */ 'use strict'; +} +=====================================output===================================== +function foo() { + /* comment */ "use strict"; +} + +================================================================================ +`; + +exports[`snippet: #2 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +'use strict' /* comment */; +=====================================output===================================== +"use strict" /* comment */ + +================================================================================ +`; + +exports[`snippet: #2 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +'use strict' /* comment */; +=====================================output===================================== +"use strict" /* comment */; + +================================================================================ +`; + +exports[`snippet: #3 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +function foo() { + 'use strict' /* comment */; +} +=====================================output===================================== +function foo() { + "use strict" /* comment */ +} + +================================================================================ +`; + +exports[`snippet: #3 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +function foo() { + 'use strict' /* comment */; +} +=====================================output===================================== +function foo() { + "use strict" /* comment */; +} + +================================================================================ +`; + +exports[`snippet: #4 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +// comment +'use strict'; +=====================================output===================================== +// comment +"use strict" + +================================================================================ +`; + +exports[`snippet: #4 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// comment +'use strict'; +=====================================output===================================== +// comment +"use strict"; + +================================================================================ +`; + +exports[`snippet: #5 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +function foo() { + // comment + 'use strict'; +} +=====================================output===================================== +function foo() { + // comment + "use strict" +} + +================================================================================ +`; + +exports[`snippet: #5 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +function foo() { + // comment + 'use strict'; +} +=====================================output===================================== +function foo() { + // comment + "use strict"; +} + +================================================================================ +`; + +exports[`snippet: #6 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +'use strict' // comment +=====================================output===================================== +"use strict" // comment + +================================================================================ +`; + +exports[`snippet: #6 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +'use strict' // comment +=====================================output===================================== +"use strict"; // comment + +================================================================================ +`; + +exports[`snippet: #7 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +function foo() { + 'use strict' // comment +} +=====================================output===================================== +function foo() { + "use strict" // comment +} + +================================================================================ +`; + +exports[`snippet: #7 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +function foo() { + 'use strict' // comment +} +=====================================output===================================== +function foo() { + "use strict"; // comment +} + +================================================================================ +`; + +exports[`snippet: #8 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +'use strict'; +/* comment */ +(function () {})(); +=====================================output===================================== +"use strict" +/* comment */ +;(function () {})() + +================================================================================ +`; + +exports[`snippet: #8 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +'use strict'; +/* comment */ +(function () {})(); +=====================================output===================================== +"use strict"; +/* comment */ +(function () {})(); + +================================================================================ +`; + +exports[`snippet: #9 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +function foo() { + 'use strict'; + /* comment */ + (function () {})(); +} +=====================================output===================================== +function foo() { + "use strict" + /* comment */ + ;(function () {})() +} + +================================================================================ +`; + +exports[`snippet: #9 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +function foo() { + 'use strict'; + /* comment */ + (function () {})(); +} +=====================================output===================================== +function foo() { + "use strict"; + /* comment */ + (function () {})(); +} + +================================================================================ +`; + +exports[`snippet: #10 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +/* comment */ +'use strict'; +(function () {})(); +=====================================output===================================== +/* comment */ +"use strict" +;(function () {})() + +================================================================================ +`; + +exports[`snippet: #10 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +/* comment */ +'use strict'; +(function () {})(); +=====================================output===================================== +/* comment */ +"use strict"; +(function () {})(); + +================================================================================ +`; + +exports[`snippet: #11 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +function foo() { + /* comment */ + 'use strict'; + (function () {})(); +} +=====================================output===================================== +function foo() { + /* comment */ + "use strict" + ;(function () {})() +} + +================================================================================ +`; + +exports[`snippet: #11 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +function foo() { + /* comment */ + 'use strict'; + (function () {})(); +} +=====================================output===================================== +function foo() { + /* comment */ + "use strict"; + (function () {})(); +} + +================================================================================ +`; + +exports[`snippet: #12 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +'use strict'; +// comment +(function () {})(); +=====================================output===================================== +"use strict" +// comment +;(function () {})() + +================================================================================ +`; + +exports[`snippet: #12 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +'use strict'; +// comment +(function () {})(); +=====================================output===================================== +"use strict"; +// comment +(function () {})(); + +================================================================================ +`; + +exports[`snippet: #13 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +function foo() { + 'use strict'; + // comment + (function () {})(); +} +=====================================output===================================== +function foo() { + "use strict" + // comment + ;(function () {})() +} + +================================================================================ +`; + +exports[`snippet: #13 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +function foo() { + 'use strict'; + // comment + (function () {})(); +} +=====================================output===================================== +function foo() { + "use strict"; + // comment + (function () {})(); +} + +================================================================================ +`; + +exports[`snippet: #14 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +// comment +'use strict'; +(function () {})(); +=====================================output===================================== +// comment +"use strict" +;(function () {})() + +================================================================================ +`; + +exports[`snippet: #14 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// comment +'use strict'; +(function () {})(); +=====================================output===================================== +// comment +"use strict"; +(function () {})(); + +================================================================================ +`; + +exports[`snippet: #15 - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +function foo() { + // comment + 'use strict'; + (function () {})(); +} +=====================================output===================================== +function foo() { + // comment + "use strict" + ;(function () {})() +} + +================================================================================ +`; + +exports[`snippet: #15 format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +function foo() { + // comment + 'use strict'; + (function () {})(); +} +=====================================output===================================== +function foo() { + // comment + "use strict"; + (function () {})(); +} + +================================================================================ +`; diff --git a/tests/format/js/directives/comments/jsfmt.spec.js b/tests/format/js/directives/comments/jsfmt.spec.js new file mode 100644 index 000000000..e85b3df3e --- /dev/null +++ b/tests/format/js/directives/comments/jsfmt.spec.js @@ -0,0 +1,55 @@ +const { outdent } = require("outdent"); +const indent = (text) => + text + .split("\n") + .map((line) => (line ? ` ${line}` : line)) + .join("\n"); +// TODO: Remove this when we drop support for Node.js v10 +// eslint-disable-next-line unicorn/prefer-spread +const flat = (array) => [].concat(...array); + +const snippets = flat( + [ + "/* comment */ 'use strict';", + "'use strict' /* comment */;", + outdent` + // comment + 'use strict'; + `, + outdent` + 'use strict' // comment + `, + outdent` + 'use strict'; + /* comment */ + (function () {})(); + `, + outdent` + /* comment */ + 'use strict'; + (function () {})(); + `, + outdent` + 'use strict'; + // comment + (function () {})(); + `, + outdent` + // comment + 'use strict'; + (function () {})(); + `, + ].map((code) => [ + code, + outdent` + function foo() { + ${indent(code)} + } + `, + ]) +); + +run_spec({ dirname: __dirname, snippets }, ["babel", "flow", "typescript"]); +run_spec({ dirname: __dirname, snippets }, ["babel", "flow", "typescript"], { + semi: false, +}); diff --git a/tests/format/markdown/auto-link/jsfmt.spec.js b/tests/format/markdown/auto-link/jsfmt.spec.js index 176a31f18..8f65afa30 100644 --- a/tests/format/markdown/auto-link/jsfmt.spec.js +++ b/tests/format/markdown/auto-link/jsfmt.spec.js @@ -3,6 +3,7 @@ * @param {Array>} array * @returns {Array} */ +// TODO: Remove this when we drop support for Node.js v10 // eslint-disable-next-line unicorn/prefer-spread const flat = (array) => [].concat(...array); From ac88438d654be6e2285e1cab8a6aa3d9a84ac875 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 7 Jan 2023 20:15:48 +0900 Subject: [PATCH 06/12] Release 2.8.2 --- .github/ISSUE_TEMPLATE/formatting.md | 2 +- .github/ISSUE_TEMPLATE/integration.md | 2 +- CHANGELOG.md | 461 ++++++++++++++++++ docs/browser.md | 30 +- package.json | 2 +- .../versioned_docs/version-stable/browser.md | 30 +- 6 files changed, 494 insertions(+), 33 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/formatting.md b/.github/ISSUE_TEMPLATE/formatting.md index 4299ace0e..340fab2a4 100644 --- a/.github/ISSUE_TEMPLATE/formatting.md +++ b/.github/ISSUE_TEMPLATE/formatting.md @@ -26,7 +26,7 @@ Don't fill the form below manually! Let a program create a report for you: --> -**Prettier 2.8.1** +**Prettier 2.8.2** [Playground link](https://prettier.io/playground/#.....) ```sh diff --git a/.github/ISSUE_TEMPLATE/integration.md b/.github/ISSUE_TEMPLATE/integration.md index a7477dbe9..b397119d2 100644 --- a/.github/ISSUE_TEMPLATE/integration.md +++ b/.github/ISSUE_TEMPLATE/integration.md @@ -20,7 +20,7 @@ BEFORE SUBMITTING AN ISSUE: **Environments:** -- Prettier Version: 2.8.1 +- Prettier Version: 2.8.2 - Running Prettier via: - Runtime: - Operating System: diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b9bd9142..e87fe40b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,464 @@ +# 2.8.2 + +[diff](https://github.com/prettier/prettier/compare/2.8.1...2.8.2) + +#### Don't lowercase link references ([#13155](https://github.com/prettier/prettier/pull/13155) by [@DerekNonGeneric](https://github.com/DerekNonGeneric) & [@fisker](https://github.com/fisker)) + + +```markdown + +We now don't strictly follow the release notes format suggested by [Keep a Changelog]. + +[Keep a Changelog]: https://example.com/ + + +We now don't strictly follow the release notes format suggested by [Keep a Changelog]. + +[keep a changelog]: https://example.com/ + + + + +``` + +#### Preserve self-closing tags ([#13691](https://github.com/prettier/prettier/pull/13691) by [@dcyriller](https://github.com/dcyriller)) + + +```hbs +{{! Input }} +
+
+ + + + + + + +{{! Prettier 2.8.1 }} +
+
+ + + + + + + +{{! Prettier 2.8.2 }} +
+
+ + + + + + +``` + +#### Allow custom "else if"-like blocks with block params ([#13930](https://github.com/prettier/prettier/pull/13930) by [@jamescdavis](https://github.com/jamescdavis)) + +#13507 added support for custom block keywords used with `else`, but failed to allow block params. This updates printer-glimmer to allow block params with custom "else if"-like blocks. + + +```hbs +{{! Input }} +{#when isAtWork as |work|}} + Ship that + {{work}}! +{{else when isReading as |book|}} + You can finish + {{book}} + eventually... +{{else}} + Go to bed! +{{/when}} + +{{! Prettier 2.8.1 }} +{{#when isAtWork as |work|}} + Ship that + {{work}}! +{{else when isReading}} + You can finish + {{book}} + eventually... +{{else}} + Go to bed! +{{/when}} + +{{! Prettier 2.8.2 }} +{#when isAtWork as |work|}} + Ship that + {{work}}! +{{else when isReading as |book|}} + You can finish + {{book}} + eventually... +{{else}} + Go to bed! +{{/when}} +``` + +#### Preserve empty lines between nested SCSS maps ([#13931](https://github.com/prettier/prettier/pull/13931) by [@jneander](https://github.com/jneander)) + + +```scss +/* Input */ +$map: ( + 'one': ( + 'key': 'value', + ), + + 'two': ( + 'key': 'value', + ), +) + +/* Prettier 2.8.1 */ +$map: ( + 'one': ( + 'key': 'value', + ), + 'two': ( + 'key': 'value', + ), +) + +/* Prettier 2.8.2 */ +$map: ( + 'one': ( + 'key': 'value', + ), + + 'two': ( + 'key': 'value', + ), +) +``` + +#### Fix missing parentheses when an expression statement starts with `let[` ([#14000](https://github.com/prettier/prettier/pull/14000), [#14044](https://github.com/prettier/prettier/pull/14044) by [@fisker](https://github.com/fisker), [@thorn0](https://github.com/thorn0)) + + +```jsx +// Input +(let[0] = 2); + +// Prettier 2.8.1 +let[0] = 2; + +// Prettier 2.8.1 (second format) +SyntaxError: Unexpected token (1:5) +> 1 | let[0] = 2; + | ^ + 2 | + +// Prettier 2.8.2 +(let)[0] = 2; +``` + +#### Fix semicolon duplicated at the end of LESS file ([#14007](https://github.com/prettier/prettier/pull/14007) by [@mvorisek](https://github.com/mvorisek)) + + +```less +// Input +@variable: { + field: something; +}; + +// Prettier 2.8.1 +@variable: { + field: something; +}; ; + +// Prettier 2.8.2 +@variable: { + field: something; +}; +``` + +#### Fix no space after unary minus when followed by opening parenthesis in LESS ([#14008](https://github.com/prettier/prettier/pull/14008) by [@mvorisek](https://github.com/mvorisek)) + + +```less +// Input +.unary_minus_single { + margin: -(@a); +} + +.unary_minus_multi { + margin: 0 -(@a); +} + +.binary_minus { + margin: 0 - (@a); +} + +// Prettier 2.8.1 +.unary_minus_single { + margin: - (@a); +} + +.unary_minus_multi { + margin: 0 - (@a); +} + +.binary_minus { + margin: 0 - (@a); +} + +// Prettier 2.8.2 +.unary_minus_single { + margin: -(@a); +} + +.unary_minus_multi { + margin: 0 -(@a); +} + +.binary_minus { + margin: 0 - (@a); +} +``` + +#### Do not change case of property name if inside a variable declaration in LESS ([#14034](https://github.com/prettier/prettier/pull/14034) by [@mvorisek](https://github.com/mvorisek)) + + +```less +// Input +@var: { + preserveCase: 0; +}; + +// Prettier 2.8.1 +@var: { + preservecase: 0; +}; + +// Prettier 2.8.2 +@var: { + preserveCase: 0; +}; +``` + +#### Fix formatting for auto-accessors with comments ([#14038](https://github.com/prettier/prettier/pull/14038) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +class A { + @dec() + // comment + accessor b; +} + +// Prettier 2.8.1 +class A { + @dec() + accessor // comment + b; +} + +// Prettier 2.8.1 (second format) +class A { + @dec() + accessor; // comment + b; +} + +// Prettier 2.8.2 +class A { + @dec() + // comment + accessor b; +} +``` + +#### Add parentheses for TSTypeQuery to improve readability ([#14042](https://github.com/prettier/prettier/pull/14042) by [@onishi-kohei](https://github.com/onishi-kohei)) + + +```tsx +// Input +a as (typeof node.children)[number] +a as (typeof node.children)[] +a as ((typeof node.children)[number])[] + +// Prettier 2.8.1 +a as typeof node.children[number]; +a as typeof node.children[]; +a as typeof node.children[number][]; + +// Prettier 2.8.2 +a as (typeof node.children)[number]; +a as (typeof node.children)[]; +a as (typeof node.children)[number][]; +``` + +#### Fix displacing of comments in default switch case ([#14047](https://github.com/prettier/prettier/pull/14047) by [@thorn0](https://github.com/thorn0)) + +It was a regression in Prettier 2.6.0. + + +```jsx +// Input +switch (state) { + default: + result = state; // no change + break; +} + +// Prettier 2.8.1 +switch (state) { + default: // no change + result = state; + break; +} + +// Prettier 2.8.2 +switch (state) { + default: + result = state; // no change + break; +} +``` + +#### Support type annotations on auto accessors via `babel-ts` ([#14049](https://github.com/prettier/prettier/pull/14049) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +[The bug that `@babel/parser` cannot parse auto accessors with type annotations](https://github.com/babel/babel/issues/15205) has been fixed. So we now support it via `babel-ts` parser. + + +```tsx +class Foo { + accessor prop: number; +} +``` + +#### Fix formatting of empty type parameters ([#14073](https://github.com/prettier/prettier/pull/14073) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +const foo: bar = () => baz; + +// Prettier 2.8.1 +Error: Comment "comment" was not printed. Please report this error! + +// Prettier 2.8.2 +const foo: bar = () => baz; +``` + +#### Add parentheses to head of `ExpressionStatement` instead of the whole statement ([#14077](https://github.com/prettier/prettier/pull/14077) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +({}).toString.call(foo) === "[object Array]" + ? foo.forEach(iterateArray) + : iterateObject(foo); + +// Prettier 2.8.1 +({}.toString.call(foo) === "[object Array]" + ? foo.forEach(iterateArray) + : iterateObject(foo)); + +// Prettier 2.8.2 +({}).toString.call(foo.forEach) === "[object Array]" + ? foo.forEach(iterateArray) + : iterateObject(foo); +``` + +#### Fix comments after directive ([#14081](https://github.com/prettier/prettier/pull/14081) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +"use strict" /* comment */; + +// Prettier 2.8.1 (with other js parsers except `babel`) +Error: Comment "comment" was not printed. Please report this error! + +// Prettier 2.8.2 + +``` + +#### Fix formatting for comments inside JSX attribute ([#14082](https://github.com/prettier/prettier/pull/14082) with by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +function MyFunctionComponent() { + +} + +// Prettier 2.8.1 +Error: Comment "old" was not printed. Please report this error! + +// Prettier 2.8.2 +function MyFunctionComponent() { + ; +} +``` + +#### Quote numeric keys for json-stringify parser ([#14083](https://github.com/prettier/prettier/pull/14083) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +{0: 'value'} + +// Prettier 2.8.1 +{ + 0: "value" +} + +// Prettier 2.8.2 +{ + "0": "value" +} +``` + +#### Fix removing commas from function arguments in maps ([#14089](https://github.com/prettier/prettier/pull/14089) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```scss +/* Input */ +$foo: map-fn( + ( + "#{prop}": inner-fn($first, $second), + ) +); + +/* Prettier 2.8.1 */ +$foo: map-fn(("#{prop}": inner-fn($first $second))); + +/* Prettier 2.8.2 */ +$foo: map-fn( + ( + "#{prop}": inner-fn($first, $second), + ) +); + +``` + +#### Do not insert space in LESS property access ([#14103](https://github.com/prettier/prettier/pull/14103) by [@fisker](https://github.com/fisker)) + + +```less +// Input +a { + color: @colors[@white]; +} + +// Prettier 2.8.1 +a { + color: @colors[ @white]; +} + +// Prettier 2.8.2 + +``` + # 2.8.1 [diff](https://github.com/prettier/prettier/compare/2.8.0...2.8.1) diff --git a/docs/browser.md b/docs/browser.md index d5637b9ef..1db441def 100644 --- a/docs/browser.md +++ b/docs/browser.md @@ -20,8 +20,8 @@ Required options: - **`plugins`**: Unlike the `format` function from the [Node.js-based API](api.md#prettierformatsource--options), this function doesn’t load plugins automatically. The `plugins` option is required because all the parsers included in the Prettier package come as plugins (for reasons of file size). These plugins are files named - - `parser-*.js` in and - - `parser-*.mjs` in + - `parser-*.js` in and + - `parser-*.mjs` in You need to load the ones that you’re going to use and pass them to `prettier.format` using the `plugins` option. @@ -32,8 +32,8 @@ See below for examples. ### Global ```html - - + + - + +