diff --git a/.github/ISSUE_TEMPLATE/formatting.md b/.github/ISSUE_TEMPLATE/formatting.md index 14ee37160172..5de791af3545 100644 --- a/.github/ISSUE_TEMPLATE/formatting.md +++ b/.github/ISSUE_TEMPLATE/formatting.md @@ -26,7 +26,7 @@ Tip! Don't write this stuff manually. --> -**Prettier 1.18.2** +**Prettier 1.19.1** [Playground link](https://prettier.io/playground/#.....) ```sh # Options (if any): diff --git a/.github/ISSUE_TEMPLATE/integration.md b/.github/ISSUE_TEMPLATE/integration.md index 2c3f5e852154..ac867bf61dc9 100644 --- a/.github/ISSUE_TEMPLATE/integration.md +++ b/.github/ISSUE_TEMPLATE/integration.md @@ -19,7 +19,7 @@ BEFORE SUBMITTING AN ISSUE: --> **Environments:** -- Prettier Version: 1.18.2 +- Prettier Version: 1.19.1 - Running Prettier via: - Runtime: - Operating System: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index aee7178f6a5a..6ef9e89f75e3 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -5,7 +5,7 @@ - [ ] I’ve added tests to confirm my change works. - [ ] (If changing the API or CLI) I’ve documented the changes I’ve made (in the `docs/` directory) -- [ ] (If the change is user-facing) I’ve added my changes to the `CHANGELOG.unreleased.md` file following the template. +- [ ] (If the change is user-facing) I’ve added my changes to `changelog_unreleased/*/pr-XXXX.md` file following `changelog_unreleased/TEMPLATE.md`. - [ ] I’ve read the [contributing guidelines](https://github.com/prettier/prettier/blob/master/CONTRIBUTING.md). **✨[Try the playground for this PR](https://prettier.io/playground-redirect)✨** diff --git a/CHANGELOG.md b/CHANGELOG.md index 57342784afe6..173dd0113044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,53 @@ +# 1.19.1 + +[diff](https://github.com/prettier/prettier/compare/1.19.0...1.19.1) + +### CLI + +#### Fix `--stdin` regression in 1.19.0 ([#6894](https://github.com/prettier/prettier/pull/6894) by [@lydell](https://github.com/lydell)) + + +``` +// Prettier stable +$ echo "test" | prettier --stdin --parser babel +[error] regeneratorRuntime is not defined + +// Prettier master +$ echo "test" | prettier --stdin --parser babel +test; +``` + +### TypeScript + +#### Fix formatting of union type as arrow function return type ([#6896](https://github.com/prettier/prettier/pull/6896) by [@thorn0](https://github.com/thorn0)) + + +```jsx +// Input +export const getVehicleDescriptor = async ( + vehicleId: string, +): Promise => {} + +// Prettier stable +export const getVehicleDescriptor = async ( + vehicleId: string +): Promise<| Collections.Parts.PrintedCircuitBoardAssembly["attributes"] +| undefined> => {}; + +// Prettier master +export const getVehicleDescriptor = async ( + vehicleId: string +): Promise< + Collections.Parts.PrintedCircuitBoardAssembly["attributes"] | undefined +> => {}; +``` + +# 1.19.0 + +[diff](https://github.com/prettier/prettier/compare/1.18.2...1.19.0) + +🔗 [Release Notes](https://prettier.io/blog/2019/11/09/1.19.0.html) + # 1.18.2 [diff](https://github.com/prettier/prettier/compare/1.18.1...1.18.2) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 40df469c28ef..5c2dd799c864 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,5 +1,6 @@ trigger: - master + - next - release-* variables: diff --git a/changelog_unreleased/TEMPLATE.md b/changelog_unreleased/TEMPLATE.md new file mode 100644 index 000000000000..a7ebe3c0aaa9 --- /dev/null +++ b/changelog_unreleased/TEMPLATE.md @@ -0,0 +1,39 @@ + + +#### Title ([#XXXX](https://github.com/prettier/prettier/pull/XXXX) by [@user](https://github.com/user)) + +Optional description if it makes sense. + + +```jsx +// Input +(foo ?? baz) || baz; + +// Prettier stable +foo ?? baz || baz; + +// Prettier master +(foo ?? baz) || baz; +``` diff --git a/changelog_unreleased/angular/.gitkeep b/changelog_unreleased/angular/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/api/.gitkeep b/changelog_unreleased/api/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/cli/.gitkeep b/changelog_unreleased/cli/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/css/.gitkeep b/changelog_unreleased/css/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/flow/.gitkeep b/changelog_unreleased/flow/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/graphql/.gitkeep b/changelog_unreleased/graphql/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/handlebars/.gitkeep b/changelog_unreleased/handlebars/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/html/.gitkeep b/changelog_unreleased/html/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/javascript/.gitkeep b/changelog_unreleased/javascript/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/json/.gitkeep b/changelog_unreleased/json/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/less/.gitkeep b/changelog_unreleased/less/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/lwc/.gitkeep b/changelog_unreleased/lwc/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/markdown/.gitkeep b/changelog_unreleased/markdown/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/mdx/.gitkeep b/changelog_unreleased/mdx/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/scss/.gitkeep b/changelog_unreleased/scss/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/typescript/.gitkeep b/changelog_unreleased/typescript/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/vue/.gitkeep b/changelog_unreleased/vue/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/changelog_unreleased/yaml/.gitkeep b/changelog_unreleased/yaml/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/cspell.json b/cspell.json index 724cc709de6e..2dcef816911a 100644 --- a/cspell.json +++ b/cspell.json @@ -288,6 +288,7 @@ "React's", "readline", "readlines", + "rebalance", "rebeccapurple", "recurse", "recurses", @@ -337,6 +338,7 @@ "superset", "supertypes", "swac", + "systemjs", "tdeekens", "templating", "tempy", @@ -362,6 +364,7 @@ "unparenthesized", "unparseable", "unpause", + "unpkg", "unrestrict", "untracked", "valourous", @@ -396,4 +399,4 @@ "ve{2,}r{2,}y", "ve+r+y+long\\w*" ] -} \ No newline at end of file +} diff --git a/docs/browser.md b/docs/browser.md index 80b627925943..676e5952dbfe 100644 --- a/docs/browser.md +++ b/docs/browser.md @@ -3,7 +3,7 @@ id: browser title: Browser --- -Run Prettier in the browser with the `standalone.js` UMD bundle shipped in the NPM package (starting in version 1.13). The new UMD bundle only formats the code and has no support for config files, ignore files, CLI usage, or automatic loading of plugins. +Run Prettier in the browser with the `standalone.js` UMD bundle shipped in the NPM package (starting in version 1.13). The UMD bundle only formats the code and has no support for config files, ignore files, CLI usage, or automatic loading of plugins. ### `prettier.format(code, options)` @@ -15,12 +15,14 @@ See [Usage](#usage) below for examples. ### Global - ```html - - - + + ``` @@ -40,8 +42,8 @@ prettier.format("query { }", { ```js define([ - "https://unpkg.com/prettier@1.13.0/standalone.js", - "https://unpkg.com/prettier@1.13.0/parser-graphql.js" + "https://unpkg.com/prettier@1.19.1/standalone.js", + "https://unpkg.com/prettier@1.19.1/parser-graphql.js" ], (prettier, ...plugins) => { prettier.format("query { }", { parser: "graphql", plugins }); }); @@ -60,7 +62,7 @@ This syntax doesn't necessarily work in the browser, but it can be used when bun ### Worker ```js -importScripts("https://unpkg.com/prettier@1.13.0/standalone.js"); -importScripts("https://unpkg.com/prettier@1.13.0/parser-graphql.js"); +importScripts("https://unpkg.com/prettier@1.19.1/standalone.js"); +importScripts("https://unpkg.com/prettier@1.19.1/parser-graphql.js"); prettier.format("query { }", { parser: "graphql", plugins: prettierPlugins }); ``` diff --git a/docs/integrating-with-linters.md b/docs/integrating-with-linters.md index 57fa98f72a63..3264d4293c4f 100644 --- a/docs/integrating-with-linters.md +++ b/docs/integrating-with-linters.md @@ -124,7 +124,7 @@ Then in `tslint.json`: ### Disable formatting rules -[`stylelint-config-prettier`](https://github.com/prettier/stylelint-config-prettier) is a config that disables rules that conflict with Prettier. Add it to your `devDependencies`, then extend from it within your `.stylelintrc` configuration. Make sure to put it last in the `extends` array, so it gets the chance to override other configs. +[`stylelint-config-prettier`](https://github.com/prettier/stylelint-config-prettier) is a config that disables rules that conflict with Prettier. Add it to your [`devDependencies`], then extend from it within your `.stylelintrc` configuration. Make sure to put it last in the `extends` array, so it gets the chance to override other configs. ```bash yarn add --dev stylelint-config-prettier diff --git a/docs/rationale.md b/docs/rationale.md index 84ff29dbaba3..67115f6798d3 100644 --- a/docs/rationale.md +++ b/docs/rationale.md @@ -132,9 +132,11 @@ One final thing: TC39 has [not yet decided if decorators come before or after `e ```js @decorator -export class Foo { } +export class Foo {} -export @decorator class Foo { } +export +@decorator +class Foo {} ``` ### Semicolons diff --git a/package.json b/package.json index f3c4273c9090..7536c355f2e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prettier", - "version": "1.18.2", + "version": "1.20.0-dev", "description": "Prettier is an opinionated code formatter", "bin": { "prettier": "./bin/prettier.js" @@ -16,7 +16,7 @@ "dependencies": { "@angular/compiler": "8.2.13", "@babel/code-frame": "7.5.5", - "@babel/parser": "7.7.2", + "@babel/parser": "7.7.3", "@glimmer/syntax": "0.41.0", "@iarna/toml": "2.2.3", "@typescript-eslint/typescript-estree": "2.6.1", @@ -35,8 +35,8 @@ "esutils": "2.0.3", "find-parent-dir": "0.3.0", "find-project-root": "1.1.1", - "flow-parser": "0.111.1", - "get-stream": "5.1.0", + "flow-parser": "0.111.3", + "get-stream": "4.1.0", "globby": "6.1.0", "graphql": "14.5.8", "html-element-attributes": "2.2.0", @@ -69,19 +69,19 @@ "string-width": "4.1.0", "typescript": "3.7.2", "unicode-regex": "3.0.0", - "unified": "8.4.1", + "unified": "8.4.2", "vnopts": "1.0.2", "yaml-unist-parser": "1.1.1" }, "devDependencies": { - "@babel/core": "7.7.0", + "@babel/core": "7.7.2", "@babel/preset-env": "7.7.1", "@rollup/plugin-alias": "2.2.0", - "@rollup/plugin-replace": "2.2.0", + "@rollup/plugin-replace": "2.2.1", "babel-loader": "8.0.6", "benchmark": "2.1.4", "builtin-modules": "3.1.0", - "codecov": "codecov/codecov-node#e427d900309adb50746a39a50aa7d80071a5ddd0", + "codecov": "3.6.1", "cross-env": "6.0.3", "eslint": "6.6.0", "eslint-config-prettier": "6.5.0", @@ -94,9 +94,9 @@ "jest-junit": "9.0.0", "jest-snapshot-serializer-ansi": "1.0.0", "jest-snapshot-serializer-raw": "1.1.0", - "jest-watch-typeahead": "0.4.0", + "jest-watch-typeahead": "0.4.2", "mkdirp": "0.5.1", - "prettier": "1.18.2", + "prettier": "1.19.1", "prettylint": "1.0.0", "rimraf": "3.0.0", "rollup": "1.26.3", @@ -130,6 +130,6 @@ "build": "node --max-old-space-size=3072 ./scripts/build/build.js", "build-docs": "node ./scripts/build-docs.js", "check-deps": "node ./scripts/check-deps.js", - "spellcheck": "npx -p cspell@4.0.31 cspell {bin,scripts,src}/**/*.js {docs,website/blog}/**/*.md CHANGELOG.unreleased.md" + "spellcheck": "npx -p cspell@4.0.31 cspell {bin,scripts,src}/**/*.js {docs,website/blog,changelog_unreleased}/**/*.md" } } diff --git a/scripts/build/build.js b/scripts/build/build.js index 40add9f49058..ad5c9fca8602 100644 --- a/scripts/build/build.js +++ b/scripts/build/build.js @@ -99,7 +99,7 @@ async function run(params) { await execa("rm", ["-rf", ".cache"]); } - const bundleCache = new Cache(".cache/", "v18"); + const bundleCache = new Cache(".cache/", "v19"); await bundleCache.load(); console.log(chalk.inverse(" Building packages ")); diff --git a/scripts/build/rollup-plugins/executable.js b/scripts/build/rollup-plugins/executable.js index 2c60a65ee9d7..c643c4042f96 100644 --- a/scripts/build/rollup-plugins/executable.js +++ b/scripts/build/rollup-plugins/executable.js @@ -6,13 +6,17 @@ const path = require("path"); module.exports = function() { let banner; let entry; + let file; return { name: "executable", - options(options) { - entry = path.resolve(options.input); - return options; + options(inputOptions) { + entry = path.resolve(inputOptions.input); + }, + + generateBundle(outputOptions) { + file = outputOptions.file; }, load(id) { @@ -36,12 +40,9 @@ module.exports = function() { } }, - writeBundle(bundle) { - if (banner) { - const files = Object.keys(bundle); - files.forEach(file => { - fs.chmodSync(bundle[file].facadeModuleId, 0o755 & ~process.umask()); - }); + writeBundle() { + if (banner && file) { + fs.chmodSync(file, 0o755 & ~process.umask()); } } }; diff --git a/scripts/release/README.md b/scripts/release/README.md index 5a15bb7234be..3dbb26c5b7d8 100644 --- a/scripts/release/README.md +++ b/scripts/release/README.md @@ -3,8 +3,6 @@ ## Usage ```sh -# set environment variable GITHUB_API_TOKEN if it's a patch release -# since we need to get merged PRs from GitHub to generate changelog node ./scripts/release/release.js --version NEW_VERSION ``` diff --git a/scripts/release/steps/update-changelog.js b/scripts/release/steps/update-changelog.js index 4ad5ee3dfd32..d45d5b1b1c34 100644 --- a/scripts/release/steps/update-changelog.js +++ b/scripts/release/steps/update-changelog.js @@ -57,7 +57,7 @@ module.exports = async function({ version, previousVersion }) { dedent(chalk` {yellow.bold A manual step is necessary.} - You can copy the entries from {bold CHANGELOG.unreleased.md} to {bold CHANGELOG.md} + You can copy the entries from {bold changelog_unreleased/*/pr-*.md} to {bold CHANGELOG.md} and update it accordingly. You don't need to commit the file, the script will take care of that. diff --git a/scripts/release/steps/update-version.js b/scripts/release/steps/update-version.js index b9c932f63fce..32723b44b1d9 100644 --- a/scripts/release/steps/update-version.js +++ b/scripts/release/steps/update-version.js @@ -16,6 +16,11 @@ async function bump({ version }) { content.replace(/^(- Prettier Version: ).*?$/m, `$1${version}`) ); + // Update unpkg link in docs + processFile("docs/browser.md", content => + content.replace(/(\/\/unpkg\.com\/prettier@)(?:.*?)\//g, `$1${version}/`) + ); + await execa("yarn", ["update-stable-docs"], { cwd: "./website" }); diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index 9d4af917fc44..e67e41e14b39 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -593,7 +593,8 @@ function genericPrint(path, options, print) { (isAdditionNode(iNode) || isSubtractionNode(iNode)) && i === 0 && (iNextNode.type === "value-number" || iNextNode.isHex) && - (parentParentNode && isColorAdjusterFuncNode(parentParentNode)) && + parentParentNode && + isColorAdjusterFuncNode(parentParentNode) && !hasEmptyRawBefore(iNextNode); const requireSpaceBeforeOperator = diff --git a/src/language-html/printer-html.js b/src/language-html/printer-html.js index ba073a41cd2e..ebf2ce56bad5 100644 --- a/src/language-html/printer-html.js +++ b/src/language-html/printer-html.js @@ -207,10 +207,10 @@ function genericPrint(path, options, print) { const shouldHugContent = node.children.length === 1 && node.firstChild.type === "interpolation" && - (node.firstChild.isLeadingSpaceSensitive && - !node.firstChild.hasLeadingSpaces) && - (node.lastChild.isTrailingSpaceSensitive && - !node.lastChild.hasTrailingSpaces); + node.firstChild.isLeadingSpaceSensitive && + !node.firstChild.hasLeadingSpaces && + node.lastChild.isTrailingSpaceSensitive && + !node.lastChild.hasTrailingSpaces; const attrGroupId = Symbol("element-attr-group-id"); return concat([ group( diff --git a/src/language-html/utils.js b/src/language-html/utils.js index b5417be12a23..0b7827312d2c 100644 --- a/src/language-html/utils.js +++ b/src/language-html/utils.js @@ -276,9 +276,9 @@ function forceBreakContent(node) { node.children.some(child => hasNonTextChild(child)))) || (node.firstChild && node.firstChild === node.lastChild && - (hasLeadingLineBreak(node.firstChild) && - (!node.lastChild.isTrailingSpaceSensitive || - hasTrailingLineBreak(node.lastChild)))) + hasLeadingLineBreak(node.firstChild) && + (!node.lastChild.isTrailingSpaceSensitive || + hasTrailingLineBreak(node.lastChild))) ); } @@ -385,7 +385,11 @@ function inferScriptParser(node) { } if (node.name === "style") { - if (!node.attrMap.lang || node.attrMap.lang === "postcss") { + if ( + !node.attrMap.lang || + node.attrMap.lang === "postcss" || + node.attrMap.lang === "css" + ) { return "css"; } diff --git a/src/language-js/clean.js b/src/language-js/clean.js index 2801323f8a06..77b4b9f1b9d2 100644 --- a/src/language-js/clean.js +++ b/src/language-js/clean.js @@ -37,6 +37,11 @@ function clean(ast, newObj, parent) { return null; } + // We remove unneeded parens around same-operator LogicalExpressions + if (isUnbalancedLogicalTree(newObj)) { + return rebalanceLogicalTree(newObj); + } + // (TypeScript) Ignore `static` in `constructor(static p) {}` // and `export` in `constructor(export p) {}` if ( @@ -194,4 +199,32 @@ function clean(ast, newObj, parent) { } } +function isUnbalancedLogicalTree(newObj) { + return ( + newObj.type === "LogicalExpression" && + newObj.right.type === "LogicalExpression" && + newObj.operator === newObj.right.operator + ); +} + +function rebalanceLogicalTree(newObj) { + if (isUnbalancedLogicalTree(newObj)) { + return rebalanceLogicalTree({ + type: "LogicalExpression", + operator: newObj.operator, + left: rebalanceLogicalTree({ + type: "LogicalExpression", + operator: newObj.operator, + left: newObj.left, + right: newObj.right.left, + loc: {} + }), + right: newObj.right.right, + loc: {} + }); + } + + return newObj; +} + module.exports = clean; diff --git a/src/language-js/comments.js b/src/language-js/comments.js index 6f339594189d..5447b7f7af9e 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -428,7 +428,8 @@ function handleClassComments( enclosingNode && (enclosingNode.type === "ClassDeclaration" || enclosingNode.type === "ClassExpression") && - (enclosingNode.decorators && enclosingNode.decorators.length > 0) && + enclosingNode.decorators && + enclosingNode.decorators.length > 0 && !(followingNode && followingNode.type === "Decorator") ) { if (!enclosingNode.decorators || enclosingNode.decorators.length === 0) { @@ -573,8 +574,8 @@ function handleCommentInEmptyParens(text, enclosingNode, comment, options) { } if ( enclosingNode && - (enclosingNode.type === "MethodDefinition" && - enclosingNode.value.params.length === 0) + enclosingNode.type === "MethodDefinition" && + enclosingNode.value.params.length === 0 ) { addDanglingComment(enclosingNode.value, comment); return true; diff --git a/src/language-js/embed.js b/src/language-js/embed.js index dca4f6c44f70..0e5454648eb8 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -161,11 +161,10 @@ function embed(path, print, textToDoc, options) { */ if ( parentParent && - (parentParent.type === "TaggedTemplateExpression" && - parent.quasis.length === 1 && - (parentParent.tag.type === "Identifier" && - (parentParent.tag.name === "md" || - parentParent.tag.name === "markdown"))) + parentParent.type === "TaggedTemplateExpression" && + parent.quasis.length === 1 && + parentParent.tag.type === "Identifier" && + (parentParent.tag.name === "md" || parentParent.tag.name === "markdown") ) { const text = parent.quasis[0].value.raw.replace( /((?:\\\\)*)\\`/g, diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index aa356c2e8f6a..6e92bda88e11 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -339,8 +339,13 @@ function needsParens(path, options) { (node.type === "TSTypeAssertion" || node.type === "TSAsExpression") ); - case "BinaryExpression": - case "LogicalExpression": { + case "LogicalExpression": + if (node.type === "LogicalExpression") { + return parent.operator !== node.operator; + } + // else fallthrough + + case "BinaryExpression": { if (!node.operator && node.type !== "TSTypeAssertion") { return true; } @@ -354,17 +359,6 @@ function needsParens(path, options) { return true; } - if ( - (po === "??" && (no === "||" || no === "&&")) || - (no === "??" && (po === "||" || po === "&&")) - ) { - return true; - } - - if (po === "||" && no === "&&") { - return true; - } - if (pp === np && name === "right") { assert.strictEqual(parent.right, node); return true; diff --git a/src/language-js/parser-babylon.js b/src/language-js/parser-babylon.js index 333e6af4cbf3..8fa8c0c8690f 100644 --- a/src/language-js/parser-babylon.js +++ b/src/language-js/parser-babylon.js @@ -8,7 +8,7 @@ const hasPragma = require("./pragma").hasPragma; const locFns = require("./loc"); const postprocess = require("./postprocess"); -function babelOptions(extraOptions, extraPlugins) { +function babelOptions(extraOptions, extraPlugins = []) { return Object.assign( { sourceType: "module", @@ -41,7 +41,8 @@ function babelOptions(extraOptions, extraPlugins) { "logicalAssignment", "classPrivateMethods", "v8intrinsic", - "partialApplication" + "partialApplication", + ["decorators", { decoratorsBeforeExport: false }] ].concat(extraPlugins) }, extraOptions @@ -53,28 +54,9 @@ function createParse(parseMethod, extraPlugins) { // Inline the require to avoid loading all the JS if we don't use it const babel = require("@babel/parser"); - const combinations = [ - babelOptions( - { strictMode: true }, - ["decorators-legacy"].concat(extraPlugins) - ), - babelOptions( - { strictMode: false }, - ["decorators-legacy"].concat(extraPlugins) - ), - babelOptions( - { strictMode: true }, - [["decorators", { decoratorsBeforeExport: false }]].concat(extraPlugins) - ), - babelOptions( - { strictMode: false }, - [["decorators", { decoratorsBeforeExport: false }]].concat(extraPlugins) - ) - ]; - let ast; try { - ast = tryCombinations(babel[parseMethod].bind(null, text), combinations); + ast = babel[parseMethod](text, babelOptions({}, extraPlugins)); } catch (error) { throw createError( // babel error prints (l:c) with cols that are zero indexed @@ -97,20 +79,6 @@ const parse = createParse("parse", ["flow"]); const parseFlow = createParse("parse", [["flow", { all: true, enums: true }]]); const parseExpression = createParse("parseExpression"); -function tryCombinations(fn, combinations) { - let error; - for (let i = 0; i < combinations.length; i++) { - try { - return fn(combinations[i]); - } catch (_error) { - if (!error) { - error = _error; - } - } - } - throw error; -} - function parseJson(text, parsers, opts) { const ast = parseExpression(text, parsers, opts); diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index d3dba1d68ba1..14a3fa9dacd1 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -597,9 +597,9 @@ function printPathNoParens(path, options, print, args) { (n === parent.body && parent.type === "ArrowFunctionExpression") || (n !== parent.body && parent.type === "ForStatement") || (parent.type === "ConditionalExpression" && - (parentParent.type !== "ReturnStatement" && - parentParent.type !== "CallExpression" && - parentParent.type !== "OptionalCallExpression")); + parentParent.type !== "ReturnStatement" && + parentParent.type !== "CallExpression" && + parentParent.type !== "OptionalCallExpression"); const shouldIndentIfInlining = parent.type === "AssignmentExpression" || @@ -1625,8 +1625,8 @@ function printPathNoParens(path, options, print, args) { case "NumericLiteral": // Babel 6 Literal split return printNumber(n.extra.raw); case "BigIntLiteral": - // babel: n.extra.raw, typescript: n.raw - return (n.extra ? n.extra.raw : n.raw).toLowerCase(); + // babel: n.extra.raw, typescript: n.raw, flow: n.bigint + return (n.bigint || (n.extra ? n.extra.raw : n.raw)).toLowerCase(); case "BooleanLiteral": // Babel 6 Literal split case "StringLiteral": // Babel 6 Literal split case "Literal": { @@ -3601,10 +3601,10 @@ function printPathNoParens(path, options, print, args) { isNgForOf(n, index, parentNode) || (((index === 1 && (n.key.name === "then" || n.key.name === "else")) || (index === 2 && - (n.key.name === "else" && - parentNode.body[index - 1].type === - "NGMicrosyntaxKeyedExpression" && - parentNode.body[index - 1].key.name === "then"))) && + n.key.name === "else" && + parentNode.body[index - 1].type === + "NGMicrosyntaxKeyedExpression" && + parentNode.body[index - 1].key.name === "then")) && parentNode.body[0].type === "NGMicrosyntaxExpression"); return concat([ path.call(print, "key"), @@ -4450,12 +4450,12 @@ function printExportDeclaration(path, options, print) { if ( isDefault && - (decl.declaration.type !== "ClassDeclaration" && - decl.declaration.type !== "FunctionDeclaration" && - decl.declaration.type !== "TSInterfaceDeclaration" && - decl.declaration.type !== "DeclareClass" && - decl.declaration.type !== "DeclareFunction" && - decl.declaration.type !== "TSDeclareFunction") + decl.declaration.type !== "ClassDeclaration" && + decl.declaration.type !== "FunctionDeclaration" && + decl.declaration.type !== "TSInterfaceDeclaration" && + decl.declaration.type !== "DeclareClass" && + decl.declaration.type !== "DeclareFunction" && + decl.declaration.type !== "TSDeclareFunction" ) { parts.push(semi); } @@ -4587,10 +4587,13 @@ function printTypeParameters(path, options, print, paramsKey) { (n[paramsKey][0].type === "TSTypeReference" && shouldHugType(n[paramsKey][0].typeName)) || n[paramsKey][0].type === "NullableTypeAnnotation" || + // See https://github.com/prettier/prettier/pull/6467 for the context. (greatGreatGrandParent && greatGreatGrandParent.type === "VariableDeclarator" && grandparent && grandparent.type === "TSTypeAnnotation" && + n[paramsKey][0].type !== "TSUnionType" && + n[paramsKey][0].type !== "UnionTypeAnnotation" && n[paramsKey][0].type !== "TSConditionalType" && n[paramsKey][0].type !== "TSMappedType"))); @@ -5140,7 +5143,7 @@ function separatorNoWhitespace( if ( (childNode.type === "JSXElement" && !childNode.closingElement) || - (nextNode && (nextNode.type === "JSXElement" && !nextNode.closingElement)) + (nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement) ) { return child.length === 1 ? softline : hardline; } diff --git a/src/language-yaml/utils.js b/src/language-yaml/utils.js index 777568ca4b88..4a1e8d74c68a 100644 --- a/src/language-yaml/utils.js +++ b/src/language-yaml/utils.js @@ -217,8 +217,13 @@ function getFlowScalarLineContents(nodeType, content, options) { index !== 0 && rawLineContents[index - 1].length !== 0 && lineContentWords.length !== 0 && - !// trailing backslash in quoteDouble should be preserved - (nodeType === "quoteDouble" && getLast(getLast(reduced)).endsWith("\\")) + !( + // trailing backslash in quoteDouble should be preserved + ( + nodeType === "quoteDouble" && + getLast(getLast(reduced)).endsWith("\\") + ) + ) ? reduced.concat([reduced.pop().concat(lineContentWords)]) : reduced.concat([lineContentWords]), [] diff --git a/tests/big-int/__snapshots__/jsfmt.spec.js.snap b/tests/big-int/__snapshots__/jsfmt.spec.js.snap index 5409b1c5474a..9d91dfc22862 100644 --- a/tests/big-int/__snapshots__/jsfmt.spec.js.snap +++ b/tests/big-int/__snapshots__/jsfmt.spec.js.snap @@ -2,7 +2,7 @@ exports[`literal.js 1`] = ` ====================================options===================================== -parsers: ["babel", "typescript"] +parsers: ["babel", "typescript", "flow"] printWidth: 80 | printWidth =====================================input====================================== diff --git a/tests/big-int/jsfmt.spec.js b/tests/big-int/jsfmt.spec.js index 858ac91aadcc..61966a7d00c3 100644 --- a/tests/big-int/jsfmt.spec.js +++ b/tests/big-int/jsfmt.spec.js @@ -1 +1 @@ -run_spec(__dirname, ["babel", "typescript"]); +run_spec(__dirname, ["babel", "typescript", "flow"]); diff --git a/tests/decorators/__snapshots__/jsfmt.spec.js.snap b/tests/decorators/__snapshots__/jsfmt.spec.js.snap index 19d833f836e6..c62a7faa8fed 100644 --- a/tests/decorators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/decorators/__snapshots__/jsfmt.spec.js.snap @@ -150,6 +150,32 @@ class Yo { ================================================================================ `; +exports[`mixed.js 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +// https://github.com/prettier/prettier/issues/6747 + +@foo +export default class MyComponent { + @task + *foo() { + } +} +=====================================output===================================== +// https://github.com/prettier/prettier/issues/6747 + +@foo +export default class MyComponent { + @task + *foo() {} +} + +================================================================================ +`; + exports[`mobx.js 1`] = ` ====================================options===================================== parsers: ["babel"] diff --git a/tests/decorators/mixed.js b/tests/decorators/mixed.js new file mode 100644 index 000000000000..1263401f638b --- /dev/null +++ b/tests/decorators/mixed.js @@ -0,0 +1,8 @@ +// https://github.com/prettier/prettier/issues/6747 + +@foo +export default class MyComponent { + @task + *foo() { + } +} \ No newline at end of file diff --git a/tests/html_vue/__snapshots__/jsfmt.spec.js.snap b/tests/html_vue/__snapshots__/jsfmt.spec.js.snap index 648d73daf513..88dc26011b1d 100644 --- a/tests/html_vue/__snapshots__/jsfmt.spec.js.snap +++ b/tests/html_vue/__snapshots__/jsfmt.spec.js.snap @@ -2102,6 +2102,326 @@ semi: false ================================================================================ `; +exports[`style.vue 1`] = ` +====================================options===================================== +parsers: ["vue"] +printWidth: 80 + | printWidth +=====================================input====================================== + + + + + + + + + + + + + + + + +=====================================output===================================== + + + + + + + + + + + + + + +================================================================================ +`; + +exports[`style.vue 2`] = ` +====================================options===================================== +parsers: ["vue"] +printWidth: 80 +trailingComma: "es5" + | printWidth +=====================================input====================================== + + + + + + + + + + + + + + + + +=====================================output===================================== + + + + + + + + + + + + + + +================================================================================ +`; + +exports[`style.vue 3`] = ` +====================================options===================================== +parsers: ["vue"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== + + + + + + + + + + + + + + + + +=====================================output===================================== + + + + + + + + + + + + + + +================================================================================ +`; + exports[`tag-name.vue 1`] = ` ====================================options===================================== parsers: ["vue"] diff --git a/tests/html_vue/style.vue b/tests/html_vue/style.vue new file mode 100644 index 000000000000..96d75d5a25f6 --- /dev/null +++ b/tests/html_vue/style.vue @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + diff --git a/tests/logical_expressions/__snapshots__/jsfmt.spec.js.snap b/tests/logical_expressions/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000000..4feb449407ae --- /dev/null +++ b/tests/logical_expressions/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,77 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`logical_expression_operators.js 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// Same operators do not require parens +(foo && bar) && baz; +foo && (bar && baz); +foo && ((bar && baz) && qux); +foo && (bar && (baz && qux)); +foo && (bar && ((baz && qux) && xyz)); +foo && (bar && (baz && (qux && xyz))); + +(foo || bar) || baz; +foo || (bar || baz); +foo || ((bar || baz) || qux); +foo || (bar || (baz || qux)); +foo || (bar || ((baz || qux) || xyz)); +foo || (bar || (baz || (qux || xyz))); + +(foo ?? bar) ?? baz; +foo ?? (bar ?? baz); +foo ?? ((bar ?? baz) ?? qux); +foo ?? (bar ?? (baz ?? qux)); +foo ?? (bar ?? ((baz ?? qux) ?? xyz)); +foo ?? (bar ?? (baz ?? (qux ?? xyz))); + +// Explicitly parenthesized && and || requires parens +(foo && bar) || baz; +(foo || bar) && baz; + +foo && (bar || baz); +foo || (bar && baz); + +// Implicitly parenthesized && and || requires parens +foo && bar || baz; +foo || bar && baz; + +=====================================output===================================== +// Same operators do not require parens +foo && bar && baz; +foo && bar && baz; +foo && bar && baz && qux; +foo && bar && baz && qux; +foo && bar && baz && qux && xyz; +foo && bar && baz && qux && xyz; + +foo || bar || baz; +foo || bar || baz; +foo || bar || baz || qux; +foo || bar || baz || qux; +foo || bar || baz || qux || xyz; +foo || bar || baz || qux || xyz; + +foo ?? bar ?? baz; +foo ?? bar ?? baz; +foo ?? bar ?? baz ?? qux; +foo ?? bar ?? baz ?? qux; +foo ?? bar ?? baz ?? qux ?? xyz; +foo ?? bar ?? baz ?? qux ?? xyz; + +// Explicitly parenthesized && and || requires parens +(foo && bar) || baz; +(foo || bar) && baz; + +foo && (bar || baz); +foo || (bar && baz); + +// Implicitly parenthesized && and || requires parens +(foo && bar) || baz; +foo || (bar && baz); + +================================================================================ +`; diff --git a/tests/logical_expressions/jsfmt.spec.js b/tests/logical_expressions/jsfmt.spec.js new file mode 100644 index 000000000000..eb85eda6bd02 --- /dev/null +++ b/tests/logical_expressions/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["babel", "flow", "typescript"]); diff --git a/tests/logical_expressions/logical_expression_operators.js b/tests/logical_expressions/logical_expression_operators.js new file mode 100644 index 000000000000..64d5ccc8e735 --- /dev/null +++ b/tests/logical_expressions/logical_expression_operators.js @@ -0,0 +1,32 @@ +// Same operators do not require parens +(foo && bar) && baz; +foo && (bar && baz); +foo && ((bar && baz) && qux); +foo && (bar && (baz && qux)); +foo && (bar && ((baz && qux) && xyz)); +foo && (bar && (baz && (qux && xyz))); + +(foo || bar) || baz; +foo || (bar || baz); +foo || ((bar || baz) || qux); +foo || (bar || (baz || qux)); +foo || (bar || ((baz || qux) || xyz)); +foo || (bar || (baz || (qux || xyz))); + +(foo ?? bar) ?? baz; +foo ?? (bar ?? baz); +foo ?? ((bar ?? baz) ?? qux); +foo ?? (bar ?? (baz ?? qux)); +foo ?? (bar ?? ((baz ?? qux) ?? xyz)); +foo ?? (bar ?? (baz ?? (qux ?? xyz))); + +// Explicitly parenthesized && and || requires parens +(foo && bar) || baz; +(foo || bar) && baz; + +foo && (bar || baz); +foo || (bar && baz); + +// Implicitly parenthesized && and || requires parens +foo && bar || baz; +foo || bar && baz; diff --git a/tests/nullish_coalescing/__snapshots__/jsfmt.spec.js.snap b/tests/nullish_coalescing/__snapshots__/jsfmt.spec.js.snap index 2da5a898b8f8..ca1915929060 100644 --- a/tests/nullish_coalescing/__snapshots__/jsfmt.spec.js.snap +++ b/tests/nullish_coalescing/__snapshots__/jsfmt.spec.js.snap @@ -36,7 +36,7 @@ const x = (foo, bar = foo ?? bar) => {}; foo ? bar ?? foo : baz; -foo ?? (bar ?? baz); +foo ?? bar ?? baz; foo ?? bar ?? baz; // Mixing ?? and (&& or ||) requires parens diff --git a/tests/typescript_generic/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_generic/__snapshots__/jsfmt.spec.js.snap index 3009a3eb7513..30c3a0efaba7 100644 --- a/tests/typescript_generic/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript_generic/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,38 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`arrow-return-type.ts 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +export const getVehicleDescriptor = async ( + vehicleId: string, +): Promise< + Descriptor | undefined +> => {} + + +export const getVehicleDescriptor = async ( + vehicleId: string, +): Promise< + Collections.Parts.PrintedCircuitBoardAssembly['attributes'] | undefined +> => {} + +=====================================output===================================== +export const getVehicleDescriptor = async ( + vehicleId: string +): Promise => {}; + +export const getVehicleDescriptor = async ( + vehicleId: string +): Promise< + Collections.Parts.PrintedCircuitBoardAssembly["attributes"] | undefined +> => {}; + +================================================================================ +`; + exports[`object-method.ts 1`] = ` ====================================options===================================== parsers: ["typescript"] diff --git a/tests/typescript_generic/arrow-return-type.ts b/tests/typescript_generic/arrow-return-type.ts new file mode 100644 index 000000000000..0d05ca494782 --- /dev/null +++ b/tests/typescript_generic/arrow-return-type.ts @@ -0,0 +1,12 @@ +export const getVehicleDescriptor = async ( + vehicleId: string, +): Promise< + Descriptor | undefined +> => {} + + +export const getVehicleDescriptor = async ( + vehicleId: string, +): Promise< + Collections.Parts.PrintedCircuitBoardAssembly['attributes'] | undefined +> => {} diff --git a/tests_integration/__tests__/__snapshots__/format.js.snap b/tests_integration/__tests__/__snapshots__/format.js.snap index e25b72a35c66..91d17660b515 100644 --- a/tests_integration/__tests__/__snapshots__/format.js.snap +++ b/tests_integration/__tests__/__snapshots__/format.js.snap @@ -1,5 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`'Adjacent JSX' error should not be swallowed by Babel's error recovery 1`] = ` +"Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...? (2:1) + 1 | +> 2 | + | ^" +`; + exports[`html parser should handle CRLF correctly 1`] = `"\\"\\\\r\\\\n\\""`; exports[`markdown parser should handle CRLF correctly 1`] = `"\\"\`\`\`\\\\r\\\\n\\\\r\\\\n\\\\r\\\\n\`\`\`\\\\r\\\\n\\""`; diff --git a/tests_integration/__tests__/__snapshots__/schema.js.snap b/tests_integration/__tests__/__snapshots__/schema.js.snap index 26b422c704a4..fffd5fdd7449 100644 --- a/tests_integration/__tests__/__snapshots__/schema.js.snap +++ b/tests_integration/__tests__/__snapshots__/schema.js.snap @@ -367,6 +367,11 @@ in order for it to be formatted.", "description": "Indent with tabs instead of spaces.", "type": "boolean", }, + "vueIndentScriptAndStyle": Object { + "default": false, + "description": "Indent script and style tags in Vue files.", + "type": "boolean", + }, }, "type": "object", }, diff --git a/tests_integration/__tests__/__snapshots__/support-info.js.snap b/tests_integration/__tests__/__snapshots__/support-info.js.snap index 8df224c939e9..5a8351f885b7 100644 --- a/tests_integration/__tests__/__snapshots__/support-info.js.snap +++ b/tests_integration/__tests__/__snapshots__/support-info.js.snap @@ -645,7 +645,19 @@ exports[`API getSupportInfo() with version 1.16.0 -> undefined 1`] = ` \\"default\\": Infinity, \\"range\\": Object { \\"end\\": Infinity, - \\"start\\": 0," + \\"start\\": 0, +@@ -220,7 +233,11 @@ + }, + \\"useTabs\\": Object { + \\"default\\": false, + \\"type\\": \\"boolean\\", + }, ++ \\"vueIndentScriptAndStyle\\": Object { ++ \\"default\\": false, ++ \\"type\\": \\"boolean\\", + }, ++ }, + }" `; exports[`CLI --support-info (stderr) 1`] = `""`; @@ -1400,6 +1412,15 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"pluginDefaults\\": {}, \\"since\\": \\"1.0.0\\", \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"HTML\\", + \\"default\\": false, + \\"description\\": \\"Indent script and style tags in Vue files.\\", + \\"name\\": \\"vueIndentScriptAndStyle\\", + \\"pluginDefaults\\": {}, + \\"since\\": \\"1.19.0\\", + \\"type\\": \\"boolean\\" } ] } diff --git a/tests_integration/__tests__/format.js b/tests_integration/__tests__/format.js index d81c5a822eed..9221de2f1a00 100644 --- a/tests_integration/__tests__/format.js +++ b/tests_integration/__tests__/format.js @@ -53,3 +53,8 @@ test("should work with foo plugin instance", () => { `"\\"{\\\\\\"tabWidth\\\\\\":8,\\\\\\"bracketSpacing\\\\\\":false}\\""` ); }); + +test("'Adjacent JSX' error should not be swallowed by Babel's error recovery", () => { + const input = "\n"; + expect(() => prettier.format(input)).toThrowErrorMatchingSnapshot(); +}); diff --git a/tests_integration/__tests__/infer-parser.js b/tests_integration/__tests__/infer-parser.js index 071b896c0f0e..3acaf440d328 100644 --- a/tests_integration/__tests__/infer-parser.js +++ b/tests_integration/__tests__/infer-parser.js @@ -165,9 +165,11 @@ describe("--write and --list-different with unknown path and no parser", () => { }); describe("multiple files", () => { - runPrettier("cli/infer-parser/", ["--list-different", "--write", "*"]).test( - { status: 0 } - ); + runPrettier("cli/infer-parser/", [ + "--list-different", + "--write", + "*" + ]).test({ status: 0 }); }); }); diff --git a/website/blog/2017-05-03-1.3.0.md b/website/blog/2017-05-03-1.3.0.md index bfad69c5adac..6026f8e48991 100644 --- a/website/blog/2017-05-03-1.3.0.md +++ b/website/blog/2017-05-03-1.3.0.md @@ -468,10 +468,10 @@ In 1.0, we made class be inline inside of arrow functions. It turns out that it ```js // Before -export default (ViewComponent: Function, ContainerComponent: Function) => class - extends React.Component { - static propTypes = {}; -}; +export default (ViewComponent: Function, ContainerComponent: Function) => + class extends React.Component { + static propTypes = {}; + }; // After export default (ViewComponent: Function, ContainerComponent: Function) => diff --git a/CHANGELOG.unreleased.md b/website/blog/2019-11-09-1.19.0.md similarity index 63% rename from CHANGELOG.unreleased.md rename to website/blog/2019-11-09-1.19.0.md index c6406f02ffbb..d66c706fef5a 100644 --- a/CHANGELOG.unreleased.md +++ b/website/blog/2019-11-09-1.19.0.md @@ -1,50 +1,24 @@ - -#### Category: Title ([#PR] by [@user]) +## Highlights -Description +### Vue -``` -// Input -Code Sample - -// Output (Prettier stable) -Code Sample - -// Output (Prettier master) -Code Sample -``` - -Details: - - Description: optional if the `Title` is enough to explain everything. - -Examples: +#### Add `--vue-indent-script-and-style` ([#6157] by [@kamilic]) -#### TypeScript: Correctly handle `//` in TSX ([#5728] by [@JamesHenry]) +The new [`--vue-indent-script-and-style`](https://prettier.io/docs/en/options.html#vue-files-script-and-style-tags-indentation) option controls whether or not to indent the code inside ` - - - - - - - -``` - -#### TypeScript: Correctly format long one-line mapped types in one pass ([#6420] by [@sosukesuzuki]) - -Previously, when Prettier formatted long one-line mapped types, it would break the line but didn’t add a semicolon until you ran Prettier again, which means Prettier’s idempotence rule was broken. Now, Prettier adds the semicolon in the first run. - - -```ts -// Input -type FooBar = { [P in keyof T]: T[P] extends Something ? Something : T[P] } - -// Prettier (stable) -type FooBar = { - [P in keyof T]: T[P] extends Something ? Something : T[P] -}; - -// Prettier (master) -type FooBar = { - [P in keyof T]: T[P] extends Something ? Something : T[P]; -}; -``` - -#### JavaScript: Fix formatting of object destructuring with parameter decorators ([#6411] by [@sosukesuzuki]) - -Previously, Prettier formatted decorators for destructured parameters in a weird way. Now, parameter decorators are placed just above the parameter they belong to. +#### Fix formatting of object destructuring with parameter decorators ([#6411] by [@sosukesuzuki]) ```js @@ -814,7 +792,7 @@ class Class { ) {} } -// Prettier (stable) +// Prettier 1.18 class Class { method(@decorator { @@ -822,7 +800,7 @@ class Class { }) {} } -// Prettier (master) +// Prettier 1.19 class Class { method( @decorator @@ -831,7 +809,7 @@ class Class { } ``` -#### JavaScript: Handle empty object patterns with type annotations in function parameters ([#6438] by [@bakkot]) +#### Handle empty object patterns with type annotations in function parameters ([#6438] by [@bakkot]) ```js @@ -839,18 +817,18 @@ class Class { const f = ({}: MyVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongType) => {}; function g({}: Foo) {} -// Output (Prettier stable) +// Prettier 1.18 const f = ({ , }: MyVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongType) => {}; function g({ }: Foo) {} -// Output (Prettier master) +// Prettier 1.19 const f = ({}: MyVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongType) => {}; function g({}: Foo) {} ``` -#### JavaScript: Put a closing parenthesis onto a new line after binary expressions within function calls ([#6441] by [@sosukesuzuki]) +#### Put a closing parenthesis onto a new line after binary expressions within function calls ([#6441] by [@sosukesuzuki]) ```js @@ -863,14 +841,14 @@ function g({}: Foo) {} eeeeeeeeeeeeeeeeeeeeeeeee )(); -// Prettier (stable) +// Prettier 1.18 (aaaaaaaaaaaaaaaaaaaaaaaaa && bbbbbbbbbbbbbbbbbbbbbbbbb && ccccccccccccccccccccccccc && ddddddddddddddddddddddddd && eeeeeeeeeeeeeeeeeeeeeeeee)(); -// Prettier (master) +// Prettier 1.19 ( aaaaaaaaaaaaaaaaaaaaaaaaa && bbbbbbbbbbbbbbbbbbbbbbbbb && @@ -880,25 +858,25 @@ function g({}: Foo) {} )(); ``` -#### JavaScript: Fix formatting of long named exports ([#6446] by [@sosukesuzuki]) +#### Fix formatting of long named exports ([#6446] by [@sosukesuzuki]) -Now, Prettier formats them the same way it formats named imports. +Now, Prettier formats named exports the same way as named imports. ```js // Input export { fooooooooooooooooooooooooooooooooooooooooooooooooo } from "fooooooooooooooooooooooooooooo"; -// Prettier (stable) +// Prettier 1.18 export { fooooooooooooooooooooooooooooooooooooooooooooooooo } from "fooooooooooooooooooooooooooooo"; -// Prettier (master) +// Prettier 1.19 export { fooooooooooooooooooooooooooooooooooooooooooooooooo } from "fooooooooooooooooooooooooooooo"; ``` -#### JavaScript: Fix bad formatting for multi-line optional chaining with comment ([#6506] by [@sosukesuzuki]) +#### Fix bad formatting for multi-line optional chaining with comment ([#6506] by [@sosukesuzuki]) ```js @@ -909,14 +887,14 @@ return a // Comment ?.d() -// Prettier (stable) +// Prettier 1.18 return a .b() .c() ?.// Comment d(); -// Prettier (master) +// Prettier 1.19 return ( a .b() @@ -926,7 +904,7 @@ return ( ); ``` -#### JavaScript: Fix inconsistent indentation in switch statement ([#6514] by [@sosukesuzuki]) +#### Fix inconsistent indentation in switch statement ([#6514] by [@sosukesuzuki]) ```js @@ -937,7 +915,7 @@ switch ($veryLongAndVeryVerboseVariableName && $anotherVeryLongAndVeryVerboseVar switch ($longButSlightlyShorterVariableName && $anotherSlightlyShorterVariableName) { } -// Prettier (stable) +// Prettier 1.18 switch ( $veryLongAndVeryVerboseVariableName && $anotherVeryLongAndVeryVerboseVariableName @@ -949,76 +927,21 @@ switch ( ) { } -// Prettier (master) +// Prettier 1.19 switch ( $veryLongAndVeryVerboseVariableName && $anotherVeryLongAndVeryVerboseVariableName ) { } - -switch ( - $longButSlightlyShorterVariableName && - $anotherSlightlyShorterVariableName -) { -} -``` - -#### TypeScript: Keep type parameters inline for type annotations in variable declarations ([#6467] by [@sosukesuzuki]) - - -```ts -// Input -const fooooooooooooooo: SomeThing = looooooooooooooooooooooooooooooongNameFunc(); - -// Prettier (stable) -const fooooooooooooooo: SomeThing< - boolean -> = looooooooooooooooooooooooooooooongNameFunc(); - -// Prettier (master) -const fooooooooooooooo: SomeThing = looooooooooooooooooooooooooooooongNameFunc(); -``` - -#### Handlebars: Fix `--single-quote` option on HTML attributes ([#6377] by [@dcyriller]) - -Previously, the flag was not applied on HTML attributes. - - -```hbs - -
- - -
- - -
-``` - -#### TypeScript: Sometimes double parentheses around types were removed incorrectly ([#6604] by [@sosukesuzuki]) - - -```ts -// Input -type A = 0 extends ((1 extends 2 ? 3 : 4)) ? 5 : 6; -type B = ((0 extends 1 ? 2 : 3)) extends 4 ? 5 : 6; -type C = ((number | string))["toString"]; -type D = ((keyof T1))["foo"]; - -// Prettier (stable) -type A = 0 extends 1 extends 2 ? 3 : 4 ? 5 : 6; -type B = 0 extends 1 ? 2 : 3 extends 4 ? 5 : 6; -type C = number | string["toString"]; -type D = keyof T1["foo"]; - -// Prettier (master) -type A = 0 extends (1 extends 2 ? 3 : 4) ? 5 : 6; -type B = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6; -type C = (number | string)["toString"]; -type D = (keyof T1)["foo"]; + +switch ( + $longButSlightlyShorterVariableName && + $anotherSlightlyShorterVariableName +) { +} ``` -#### JavaScript: Support formatting code with V8 intrinsics ([#6496] by [@rreverser]) +#### Support formatting code with V8 intrinsics ([#6496] by [@rreverser]) ```js @@ -1029,33 +952,19 @@ function doSmth() { foo ) } -// Prettier (stable) +// Prettier 1.18 SyntaxError: Unexpected token (2:13) 1 | function doSmth() { > 2 | %DebugPrint | ^ -// Prettier (master) +// Prettier 1.19 function doSmth() { %DebugPrint(foo); } ``` -#### TypeScript: Sometimes removing parentheses around JSX made the code unparseable ([#6640] by [@sosukesuzuki]) - - -```tsx -// Input -().toString(); - -// Prettier (stable) -.toString(): - -// Prettier (master) -().toString(); -``` - -#### JavaScript: Object destructuring in method parameters always broke into multiple lines ([#6646] by [@ericsakmar]) +#### Object destructuring in method parameters always broke into multiple lines ([#6646] by [@ericsakmar]) ```js @@ -1075,7 +984,7 @@ class A { } } -// Prettier (stable) +// Prettier 1.18 const obj = { func( id, @@ -1106,7 +1015,7 @@ class A { } } -// Prettier (master) +// Prettier 1.19 const obj = { func(id, { blog: { title } }) { return id + title; @@ -1123,21 +1032,182 @@ class A { } ``` -#### Angular: Put a closing parenthesis onto a new line after ternaries passed to pipes ([#5682] by [@selvazhagan]) +#### Numeric separators were removed from BigInt literals ([#6796] by [@thorn0]) + + +```js +// Input +const bigints = [200_000n, 0x0000_000An, 0b0111_1111n]; + +// Prettier 1.18 +const bigints = [200000n, 0x0000000an, 0b01111111n]; + +// Prettier 1.19 +const bigints = [200_000n, 0x0000_000an, 0b0111_1111n]; +``` + +#### Better formatting for inline `await` expression nested in calls ([#6856] by [@thorn0]) + + +```js +// Input +async function f() { + const admins = (await(db.select('*').from('admins').leftJoin('bla').where('id', 'in', [1,2,3,4]))).map(({id, name})=>({id, name})) +} + +// Prettier 1.18 +async function f() { + const admins = (await db + .select("*") + .from("admins") + .leftJoin("bla") + .where("id", "in", [1, 2, 3, 4])).map(({ id, name }) => ({ id, name })); +} + +// Prettier 1.19 +async function f() { + const admins = ( + await db + .select("*") + .from("admins") + .leftJoin("bla") + .where("id", "in", [1, 2, 3, 4]) + ).map(({ id, name }) => ({ id, name })); +} +``` + +### HTML + +#### Don't wrap `template` elements on lines shorter than `printWidth` ([#6284] by [@sosukesuzuki]) + +Previously, even if the line length was shorter than `printWidth`, Prettier would break the line with a `template` element. + + +```html + + + + + + + + +``` + +#### Script tags are now treated as blocks for the purposes of formatting ([#6423] by [@thorn0]) + +Previously, in the [whitespace-sensitive mode](https://prettier.io/docs/en/options.html#html-whitespace-sensitivity), they were formatted as if they were inline. + + +```html + + + + + + + + + +``` + +#### Add support for `!` and other entities ([#6785] by [@lydell] and [@ikatyang]) + +Previously, Prettier only supported the most common HTML entities, such as ` ` and `"`. Now, Prettier supports every HTML entity in the HTML spec, such as `!` and `⋔`. + + +```html + +

Hi!

+ + + + +

Hi!

+``` + +#### Add JSON script types ([#6293] by [@ascorbic]) + + +```html + + + + + + + + + + + + + + + + +``` + +### Angular + +#### Put a closing parenthesis onto a new line after ternaries passed to pipes ([#5682] by [@selvazhagan]) ```html {{ (isCustomDiscount ? 'DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT' : 'DISCOUNTS__DISCOUNT_TRAINING_HEADER__DISCOUNT') | translate }} - + {{ (isCustomDiscount ? "DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT" : "DISCOUNTS__DISCOUNT_TRAINING_HEADER__DISCOUNT") | translate }} - + {{ (isCustomDiscount ? "DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT" @@ -1146,7 +1216,38 @@ class A { }} ``` -#### Handlebars: Fix handling of whitespace and line breaks ([#6354] by [@chadian]) +#### Add formatting for `i18n` attributes ([#6695] by [@voithos]) + +Prettier will auto-wrap the contents of `i18n` attributes once they exceed the line length. + + +```html + +

+ Hello! +

+ + +

+ Hello! +

+ + +

+ Hello! +

+``` + +### Handlebars + +#### Fix handling of whitespace and line breaks ([#6354] by [@chadian]) This fixes a variety of whitespace and line break use cases within Handlebars and Glimmer templates. @@ -1162,7 +1263,7 @@ Some sentence with {{dynamic}} expressions. sometimes{{nogaps}}areimportant {{name}} is your name - + {{name}} Some sentence with @@ -1178,276 +1279,354 @@ areimportant {{name}} is your name - + {{name}} -Some sentence with {{dynamic}} expressions. +Some sentence with {{dynamic}} expressions. + + + +sometimes{{nogaps}}areimportant + +{{name}} is your name +``` + +#### Avoid adding unwanted line breaks between text and mustaches ([#6186] by [@gavinjoyce]) + +Previously, Prettier added line breaks between text and mustaches which resulted in unwanted whitespace in rendered output. + + +```hbs + +

Your username is @{{name}}

+

Hi {{firstName}} {{lastName}}

+ + +

+ Your username is @ + {{name}} +

+

+ Hi + {{firstName}} + {{lastName}} +

+ + +

+ Your username is @{{name}} +

+

+ Hi {{firstName}} {{lastName}} +

+``` + +#### Improve comment formatting ([#6206] by [@gavinjoyce]) + + +```hbs + +
+ {{! Foo }} + {{#if @foo}} + Foo + {{/if}} + + {{! Bar }} + {{#if @bar}} + Bar + {{/if}} +
+ + +
+ {{! Foo }} + {{#if @foo}} + Foo + {{/if}}{{! Bar }}{{#if @bar}} + Bar + {{/if}} +
+ + +
+ {{! Foo }} + {{#if @foo}} + Foo + {{/if}} + {{! Bar }} + {{#if @bar}} + Bar + {{/if}} +
+``` + +#### Preserve HTML entities ([#6234] by [@gavinjoyce]) + + +```hbs + +

+ Some escaped characters: < > & +

+ + +

+ Some escaped characters: < > & +

+ + +

+ Some escaped characters: < > & +

+``` + +#### Fix `--single-quote` option on HTML attributes ([#6377] by [@dcyriller]) + +Previously, the flag was not applied on HTML attributes. + + +```hbs + +
+ + +
+ + +
+``` + +#### Break long interpolations ([#6249] by [@jjaffeux]) + +```hbs + +{{my-component foo="bar" bar="baz" action=(action "almostTheMaximumLengthxxxx") +}} + +{{my-component foo="bar" bar="baz" action=(action "almostTheMaximumLengthxxxx") +}} -sometimes{{nogaps}}areimportant - -{{name}} is your name + +{{my-component + foo="bar" + bar="baz" + action=(action "almostTheMaximumLengthxxxx") +}} ``` -#### Angular: Add formatting for `i18n` attributes ([#6695] by [@voithos]) +### MDX -Prettier will auto-wrap the contents of `i18n` attributes once they exceed the line length. +#### Text following JSX was trimmed incorrectly ([#6340] by [@JounQin]) -```html +```md -

- Hello! -

+ + test test + 123 - -

- Hello! -

+ + + test test +123 - -

- Hello! -

+ + + test test + 123 ``` -#### JavaScript: Break arrays of arrays/objects if each element has more than one element/property ([#6694] by [@sosukesuzuki]) +#### Adjacent JSX elements should be allowed ([#6332] by [@JounQin]) -```js +```jsx // Input -test.each([ - { a: "1", b: 1 }, - { a: "2", b: 2 }, - { a: "3", b: 3 } -])("test", ({ a, b }) => { - expect(Number(a)).toBe(b); -}); -[[0, 1, 2], [0, 1, 2]]; -new Map([ - [A, B], - [C, D], - [E, F], - [G, H], - [I, J], - [K, L], - [M, N] -]); + + test test +123 -// Output (Prettier stable) -test.each([{ a: "1", b: 1 }, { a: "2", b: 2 }, { a: "3", b: 3 }])( - "test", - ({ a, b }) => { - expect(Number(a)).toBe(b); - } -); -[[0, 1, 2], [0, 1, 2]] -new Map([[A, B], [C, D], [E, F], [G, H], [I, J], [K, L], [M, N]]); +// Prettier 1.18 +SyntaxError: Unexpected token (3:9) + 1 | + 2 | test test +> 3 | 123 + | ^ -// Output (Prettier master) -test.each([ - { a: "1", b: 1 }, - { a: "2", b: 2 }, - { a: "3", b: 3 } -])("test", ({ a, b }) => { - expect(Number(a)).toBe(b); -}); -[ - [0, 1, 2], - [0, 1, 2] -]; -new Map([ - [A, B], - [C, D], - [E, F], - [G, H], - [I, J], - [K, L], - [M, N] -]); +// Prettier 1.19 + + test test +123 + + +// Input + + test test + + + test test +123 + +// Prettier 1.18 +SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...? (4:1) + 2 | test test + 3 |
+> 4 | + | ^ + 5 | test test + 6 | 123 + +// Prettier 1.19 + + test test + + + test test +123 ``` -#### TypeScript: Keep semi for a class property before index signature when no-semi is enabled ([#6728] by [@sosukesuzuki]) +### Vue -Attempting to format Prettier’s output again used to result in a syntax error. +#### Format `style[lang="css"]` ([#6875] by [@fisker]) + +Previously, ` -// Output (Prettier stable) -export class User { - id: number = 2 - [key: string]: any + + -// Output (Prettier master) -export class User { - id: number = 2; - [key: string]: any -} + + ``` -#### Flow: Parentheses around arrow functions' return types that have `FunctionTypeAnnotation` nested in `ObjectTypeAnnotation` ([#6717] by [@sosukesuzuki]) +### Less -This is a workaround for a [bug](https://github.com/facebook/flow/pull/8163) in the Flow parser. Without the parentheses, the parser throws an error. +#### Don't lowercase variable names and remove whitespace between variable and colon ([#6778] by [@fisker]) -```js + +```less // Input -const example1 = (): { p: (string => string) } => (0: any); +@FoO : bar; -// Output (Prettier stable) -const example1 = (): { p: string => string } => (0: any); +// Prettier 1.18 +@foo : bar; -// Output (Prettier master) -const example1 = (): ({ p: string => string }) => (0: any); +// Prettier 1.19 +@FoO: bar; ``` -#### CLI: Handle errors when reading stdin ([#6708] by [@andersk] and [@lydell]) +### API + +#### Add `resolveConfig` option to `getFileInfo()` ([#6666] by [@kaicataldo]) + +Add a `resolveConfig: boolean` option to `prettier.getFileInfo()` that, when set to `true`, will resolve the configuration for the given file path. This allows consumers to take any overridden parsers into account. + +### CLI + +#### Handle errors when reading stdin ([#6708] by [@andersk] and [@lydell]) If you had an error in your `.prettierrc` Prettier used to crash when formatting stdin. Such errors are now handled properly. ``` -# Prettier stable +# Prettier 1.18 $ prettier --parser babel < test.js (node:21531) UnhandledPromiseRejectionWarning: Error: Invalid printWidth value. Expected an integer, but received "nope". - at _loop (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:7887:63) - at Normalizer._applyNormalization (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:8000:13) - at applyNormalization (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:7817:49) - at Normalizer.normalize (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:7823:9) - at normalizeOptions$1 (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:8760:31) - at Object.normalizeApiOptions (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:8918:10) - at getOptionsForFile (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:44160:69) - at /home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:44214:22 + at _loop (/home/you/project/node_modules/prettier/bin-prettier.js:7887:63) + at Normalizer._applyNormalization (/home/you/project/node_modules/prettier/bin-prettier.js:8000:13) + at applyNormalization (/home/you/project/node_modules/prettier/bin-prettier.js:7817:49) + at Normalizer.normalize (/home/you/project/node_modules/prettier/bin-prettier.js:7823:9) + at normalizeOptions$1 (/home/you/project/node_modules/prettier/bin-prettier.js:8760:31) + at Object.normalizeApiOptions (/home/you/project/node_modules/prettier/bin-prettier.js:8918:10) + at getOptionsForFile (/home/you/project/node_modules/prettier/bin-prettier.js:44160:69) + at /home/you/project/node_modules/prettier/bin-prettier.js:44214:22 at process._tickCallback (internal/process/next_tick.js:68:7) (node:21531) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:21531) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. -# Prettier master +# Prettier 1.19 $ prettier --parser babel < test.js [error] Invalid printWidth value. Expected an integer, but received "nope". ``` -#### CLI: Gracefully handle nonexistent paths passed to --stdin-filepath ([#6687] by [@voithos]) +#### Gracefully handle nonexistent paths passed to `--stdin-filepath` ([#6687] by [@voithos] and [@lydell]) -Previously, if you passed a nonexistent subdirectory to --stdin-filepath, Prettier would throw an error. Now, Prettier gracefully handles this. +Previously, if you passed a nonexistent subdirectory to `--stdin-filepath`, Prettier would throw an error. Now, Prettier gracefully handles this. ``` -# Prettier stable +# Prettier 1.18 $ prettier --stdin-filepath does/not/exist.js < test.js -[error] Invalid configuration file: ENOENT: no such file or directory, scandir '/home/lydell/forks/prettier/does/not' +[error] Invalid configuration file: ENOENT: no such file or directory, scandir '/home/you/project/does/not' -# Prettier master +# Prettier 1.19 $ prettier --stdin-filepath does/not/exist.js < test.js test; ``` -#### JavaScript: Numeric separators were removed from BigInt literals ([#6796] by [@thorn0]) - - -```js -// Input -const bigints = [200_000n, 0x0000_000An, 0b0111_1111n]; - -// Output (Prettier stable) -const bigints = [200000n, 0x0000000an, 0b01111111n]; - -// Output (Prettier master) -const bigints = [200_000n, 0x0000_000an, 0b0111_1111n]; -``` - -#### VS Code: add support for .mongo files ([#6848] by [@aymericbouzy]) +#### Config should not be evaluated for ignored files ([#6233] by [@jamesreggio]) -When using the Azure Cosmos DB extension for VS Code, you can create .mongo files to write MongoDB queries, which use Javascript syntax. This change allows VS Code to format your file using Prettier. +Prior to this change, the CLI would resolve the config for a file before checking it against the ignored list. If the config was invalid, the CLI would report a failure. -```js -db.users.find({ someField: { $exists: true } }); -``` +This change relocates the config-resolution phase until after the file is confirmed to not be ignored. -#### JavaScript: Better formatting for inline `await` expression nested in calls ([#6856] by [@thorn0]) +#### Display invalid config filename in error message ([#6865] by [@fisker]) -```js -// Input -async function f() { - const admins = (await(db.select('*').from('admins').leftJoin('bla').where('id', 'in', [1,2,3,4]))).map(({id, name})=>({id, name})) -} - -// Output (Prettier stable) -async function f() { - const admins = (await db - .select("*") - .from("admins") - .leftJoin("bla") - .where("id", "in", [1, 2, 3, 4])).map(({ id, name }) => ({ id, name })); -} - -// Output (Prettier master) -async function f() { - const admins = ( - await db - .select("*") - .from("admins") - .leftJoin("bla") - .where("id", "in", [1, 2, 3, 4]) - ).map(({ id, name }) => ({ id, name })); -} ``` - -#### CLI: Display invalid config filename in error message ([#6865] by [@fisker]) - - -```bash # Input $ prettier filename.js --config .invalid-config -# Output (Prettier stable) +# Prettier 1.18 Invalid configuration file: ... -# Output (Prettier master) +# Prettier 1.19 Invalid configuration file `.invalid-config`: ... ``` -#### Less: don't lowercase variable names, remove whitespace between variable and colon ([#6778] by [@fisker]) +### Other - -```less -// Input -@FoO : bar; +Thanks to [@fisker] for updating lots of Prettier’s dependencies! -// Output (Prettier stable) -@foo : bar; +#### VS Code: add support for .mongo files ([#6848] by [@aymericbouzy]) -// Output (Prettier master) -@FoO: bar; +When using the Azure Cosmos DB extension for VS Code, you can create .mongo files to write MongoDB queries, which use Javascript syntax. This change allows VS Code to format your file using Prettier. + +```js +db.users.find({ someField: { $exists: true } }); ``` [#5682]: https://github.com/prettier/prettier/pull/5682 -[#6657]: https://github.com/prettier/prettier/pull/6657 [#5910]: https://github.com/prettier/prettier/pull/5910 [#6033]: https://github.com/prettier/prettier/pull/6033 +[#6157]: https://github.com/prettier/prettier/pull/6157 [#6186]: https://github.com/prettier/prettier/pull/6186 [#6206]: https://github.com/prettier/prettier/pull/6206 [#6209]: https://github.com/prettier/prettier/pull/6209 [#6217]: https://github.com/prettier/prettier/pull/6217 +[#6233]: https://github.com/prettier/prettier/pull/6233 [#6234]: https://github.com/prettier/prettier/pull/6234 [#6236]: https://github.com/prettier/prettier/pull/6236 +[#6249]: https://github.com/prettier/prettier/pull/6249 [#6270]: https://github.com/prettier/prettier/pull/6270 [#6284]: https://github.com/prettier/prettier/pull/6284 -[#6785]: https://github.com/prettier/prettier/pull/6785 [#6289]: https://github.com/prettier/prettier/pull/6289 +[#6293]: https://github.com/prettier/prettier/pull/6293 [#6301]: https://github.com/prettier/prettier/pull/6301 [#6307]: https://github.com/prettier/prettier/pull/6307 [#6332]: https://github.com/prettier/prettier/pull/6332 @@ -1462,10 +1641,11 @@ Invalid configuration file `.invalid-config`: ... [#6412]: https://github.com/prettier/prettier/pull/6412 [#6420]: https://github.com/prettier/prettier/pull/6420 [#6423]: https://github.com/prettier/prettier/pull/6423 -[#6438]: https://github.com/prettier/prettier/pull/6411 +[#6438]: https://github.com/prettier/prettier/pull/6438 [#6441]: https://github.com/prettier/prettier/pull/6441 [#6446]: https://github.com/prettier/prettier/pull/6446 [#6467]: https://github.com/prettier/prettier/pull/6467 +[#6471]: https://github.com/prettier/prettier/pull/6471 [#6496]: https://github.com/prettier/prettier/pull/6496 [#6506]: https://github.com/prettier/prettier/pull/6506 [#6514]: https://github.com/prettier/prettier/pull/6514 @@ -1473,40 +1653,53 @@ Invalid configuration file `.invalid-config`: ... [#6605]: https://github.com/prettier/prettier/pull/6605 [#6640]: https://github.com/prettier/prettier/pull/6640 [#6646]: https://github.com/prettier/prettier/pull/6646 +[#6657]: https://github.com/prettier/prettier/pull/6657 [#6666]: https://github.com/prettier/prettier/pull/6666 [#6673]: https://github.com/prettier/prettier/pull/6673 -[#6695]: https://github.com/prettier/prettier/pull/6695 +[#6687]: https://github.com/prettier/prettier/pull/6687 [#6694]: https://github.com/prettier/prettier/pull/6694 +[#6695]: https://github.com/prettier/prettier/pull/6695 +[#6708]: https://github.com/prettier/prettier/pull/6708 [#6717]: https://github.com/prettier/prettier/pull/6717 [#6728]: https://github.com/prettier/prettier/pull/6728 -[#6708]: https://github.com/prettier/prettier/pull/6708 -[#6687]: https://github.com/prettier/prettier/pull/6687 -[#6796]: https://github.com/prettier/prettier/pull/6796 [#6778]: https://github.com/prettier/prettier/pull/6778 +[#6785]: https://github.com/prettier/prettier/pull/6785 +[#6796]: https://github.com/prettier/prettier/pull/6796 +[#6816]: https://github.com/prettier/prettier/pull/6816 +[#6833]: https://github.com/prettier/prettier/pull/6833 [#6848]: https://github.com/prettier/prettier/pull/6848 [#6856]: https://github.com/prettier/prettier/pull/6856 -[#6865]: https://github.com/prettier/prettier/pull/6865 [#6863]: https://github.com/prettier/prettier/pull/6863 +[#6864]: https://github.com/prettier/prettier/pull/6864 +[#6865]: https://github.com/prettier/prettier/pull/6865 +[#6875]: https://github.com/prettier/prettier/pull/6875 +[@andersk]: https://github.com/andersk +[@ascorbic]: https://github.com/ascorbic +[@aymericbouzy]: https://github.com/aymericbouzy +[@bakkot]: https://gibhub.com/bakkot [@brainkim]: https://github.com/brainkim +[@chadian]: https://github.com/chadian +[@cryrivers]: https://github.com/Cryrivers +[@dcyriller]: https://github.com/dcyriller [@duailibe]: https://github.com/duailibe -[@gavinjoyce]: https://github.com/gavinjoyce -[@sosukesuzuki]: https://github.com/sosukesuzuki +[@ericsakmar]: https://github.com/ericsakmar +[@fisker]: https://github.com/fisker [@g-harel]: https://github.com/g-harel +[@gavinjoyce]: https://github.com/gavinjoyce +[@gkz]: https://github.com/gkz +[@ikatyang]: https://github.com/ikatyang/ +[@jamesreggio]: https://github.com/jamesreggio +[@jjaffeux]: https://github.com/jjaffeux [@jounqin]: https://github.com/JounQin -[@bakkot]: https://gibhub.com/bakkot -[@thorn0]: https://github.com/thorn0 -[@dcyriller]: https://github.com/dcyriller +[@jridgewell]: https://github.com/jridgewell +[@kaicataldo]: https://github.com/kaicataldo +[@kamilic]: https://github.com/kamilic +[@lydell]: https://github.com/lydell +[@mattleff]: https://github.com/mattleff [@rreverser]: https://github.com/RReverser -[@ericsakmar]: https://github.com/ericsakmar +[@selvazhagan]: https://github.com/selvazhagan +[@sosukesuzuki]: https://github.com/sosukesuzuki [@squidfunk]: https://github.com/squidfunk +[@thorn0]: https://github.com/thorn0 [@vjeux]: https://github.com/vjeux -[@selvazhagan]: https://github.com/selvazhagan -[@chadian]: https://github.com/chadian -[@kaicataldo]: https://github.com/kaicataldo -[@cryrivers]: https://github.com/Cryrivers [@voithos]: https://github.com/voithos -[@andersk]: https://github.com/andersk -[@lydell]: https://github.com/lydell -[@aymericbouzy]: https://github.com/aymericbouzy -[@fisker]: https://github.com/fisker -[@jridgewell]: https://github.com/jridgewell diff --git a/website/package.json b/website/package.json index 6e38555cb2c1..09f458bbe842 100644 --- a/website/package.json +++ b/website/package.json @@ -19,7 +19,7 @@ "react-dom": "16.11.0" }, "devDependencies": { - "@babel/preset-env": "7.6.3", + "@babel/preset-env": "7.7.1", "@babel/preset-react": "7.7.0", "@sandhose/prettier-animated-logo": "1.0.3", "babel-loader": "8.0.6", diff --git a/website/versioned_docs/version-stable/api.md b/website/versioned_docs/version-stable/api.md index cb814f647d8d..6b2ff844b35e 100644 --- a/website/versioned_docs/version-stable/api.md +++ b/website/versioned_docs/version-stable/api.md @@ -50,7 +50,7 @@ prettier.resolveConfig(filePath).then(options => { }); ``` -If `options.editorconfig` is `true` and an [`.editorconfig` file](http://editorconfig.org/) is in your project, Prettier will parse it and convert its properties to the corresponding prettier configuration. This configuration will be overridden by `.prettierrc`, etc. Currently, the following EditorConfig properties are supported: +If `options.editorconfig` is `true` and an [`.editorconfig` file](https://editorconfig.org/) is in your project, Prettier will parse it and convert its properties to the corresponding prettier configuration. This configuration will be overridden by `.prettierrc`, etc. Currently, the following EditorConfig properties are supported: - `end_of_line` - `indent_style` @@ -101,6 +101,8 @@ Setting `options.ignorePath` (`string`) and `options.withNodeModules` (`boolean` Providing [plugin](plugins.md) paths in `options.plugins` (`string[]`) helps extract `inferredParser` for files that are not supported by Prettier core. +When setting `options.resolveConfig` (`boolean`, default `false`), Prettier will resolve the configuration for the given `filePath`. This is useful, for example, when the `inferredParser` might be overridden for a subset of files. + Use `prettier.getFileInfo.sync(filePath [, options])` if you'd like to use sync version. ## `prettier.getSupportInfo([version])` diff --git a/website/versioned_docs/version-stable/browser.md b/website/versioned_docs/version-stable/browser.md index 03fd05eb0f07..22c1f0741184 100644 --- a/website/versioned_docs/version-stable/browser.md +++ b/website/versioned_docs/version-stable/browser.md @@ -4,7 +4,7 @@ title: Browser original_id: browser --- -Run Prettier in the browser with the `standalone.js` UMD bundle shipped in the NPM package (starting in version 1.13). The new UMD bundle only formats the code and has no support for config files, ignore files, CLI usage, or automatic loading of plugins. +Run Prettier in the browser with the `standalone.js` UMD bundle shipped in the NPM package (starting in version 1.13). The UMD bundle only formats the code and has no support for config files, ignore files, CLI usage, or automatic loading of plugins. ### `prettier.format(code, options)` @@ -16,12 +16,14 @@ See [Usage](#usage) below for examples. ### Global - ```html - - - + + ``` @@ -41,8 +43,8 @@ prettier.format("query { }", { ```js define([ - "https://unpkg.com/prettier@1.13.0/standalone.js", - "https://unpkg.com/prettier@1.13.0/parser-graphql.js" + "https://unpkg.com/prettier@1.19.1/standalone.js", + "https://unpkg.com/prettier@1.19.1/parser-graphql.js" ], (prettier, ...plugins) => { prettier.format("query { }", { parser: "graphql", plugins }); }); @@ -61,7 +63,7 @@ This syntax doesn't necessarily work in the browser, but it can be used when bun ### Worker ```js -importScripts("https://unpkg.com/prettier@1.13.0/standalone.js"); -importScripts("https://unpkg.com/prettier@1.13.0/parser-graphql.js"); +importScripts("https://unpkg.com/prettier@1.19.1/standalone.js"); +importScripts("https://unpkg.com/prettier@1.19.1/parser-graphql.js"); prettier.format("query { }", { parser: "graphql", plugins: prettierPlugins }); ``` diff --git a/website/versioned_docs/version-stable/cli.md b/website/versioned_docs/version-stable/cli.md index 9b483dd37235..dc0136310f13 100644 --- a/website/versioned_docs/version-stable/cli.md +++ b/website/versioned_docs/version-stable/cli.md @@ -18,7 +18,7 @@ In practice, this may look something like: prettier --single-quote --trailing-comma es5 --write "{app,__{tests,mocks}__}/**/*.js" ``` -Don't forget the quotes around the globs! The quotes make sure that Prettier expands the globs rather than your shell, for cross-platform usage. The [glob syntax from the `fast-glob` module](https://github.com/mrmlnc/fast-glob/blob/master/README.md#pattern-syntax) is used. +Don't forget the quotes around the globs! The quotes make sure that Prettier expands the globs rather than your shell, for cross-platform usage. The [glob syntax from the glob module](https://github.com/isaacs/node-glob/blob/master/README.md#glob-primer) is used. Prettier CLI will ignore files located in `node_modules` directory. To opt-out from this behavior use `--with-node-modules` flag. @@ -149,8 +149,6 @@ Prettier CLI will ignore files located in `node_modules` directory. To opt-out f This rewrites all processed files in place. This is comparable to the `eslint --fix` workflow. -To avoid re-checking unchanged files, use the `--only-changed` flag. - ## `--loglevel` Change the level of logging for the CLI. Valid options are: diff --git a/website/versioned_docs/version-stable/comparison.md b/website/versioned_docs/version-stable/comparison.md index f356e2eec3b6..8d02eff6bef0 100644 --- a/website/versioned_docs/version-stable/comparison.md +++ b/website/versioned_docs/version-stable/comparison.md @@ -8,10 +8,10 @@ original_id: comparison Linters have two categories of rules: -**Formatting rules**: eg: [max-len](http://eslint.org/docs/rules/max-len), [no-mixed-spaces-and-tabs](http://eslint.org/docs/rules/no-mixed-spaces-and-tabs), [keyword-spacing](http://eslint.org/docs/rules/keyword-spacing), [comma-style](http://eslint.org/docs/rules/comma-style)... +**Formatting rules**: eg: [max-len](https://eslint.org/docs/rules/max-len), [no-mixed-spaces-and-tabs](https://eslint.org/docs/rules/no-mixed-spaces-and-tabs), [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing), [comma-style](https://eslint.org/docs/rules/comma-style)... Prettier alleviates the need for this whole category of rules! Prettier is going to reprint the entire program from scratch in a consistent way, so it's not possible for the programmer to make a mistake there anymore :) -**Code-quality rules**: eg [no-unused-vars](http://eslint.org/docs/rules/no-unused-vars), [no-extra-bind](http://eslint.org/docs/rules/no-extra-bind), [no-implicit-globals](http://eslint.org/docs/rules/no-implicit-globals), [prefer-promise-reject-errors](http://eslint.org/docs/rules/prefer-promise-reject-errors)... +**Code-quality rules**: eg [no-unused-vars](https://eslint.org/docs/rules/no-unused-vars), [no-extra-bind](https://eslint.org/docs/rules/no-extra-bind), [no-implicit-globals](https://eslint.org/docs/rules/no-implicit-globals), [prefer-promise-reject-errors](https://eslint.org/docs/rules/prefer-promise-reject-errors)... Prettier does nothing to help with those kind of rules. They are also the most important ones provided by linters as they are likely to catch real bugs with your code! diff --git a/website/versioned_docs/version-stable/configuration.md b/website/versioned_docs/version-stable/configuration.md index 9028ed59ed3c..384c82f81dd0 100644 --- a/website/versioned_docs/version-stable/configuration.md +++ b/website/versioned_docs/version-stable/configuration.md @@ -64,7 +64,7 @@ singleQuote = true Overrides let you have different configuration for certain file extensions, folders and specific files. -Prettier borrows ESLint’s [override format](http://eslint.org/docs/user-guide/configuring#example-configuration). +Prettier borrows ESLint’s [override format](https://eslint.org/docs/user-guide/configuring#example-configuration). JSON: diff --git a/website/versioned_docs/version-stable/index.md b/website/versioned_docs/version-stable/index.md index 0de7d5d10abf..c373e77e5f59 100644 --- a/website/versioned_docs/version-stable/index.md +++ b/website/versioned_docs/version-stable/index.md @@ -19,7 +19,7 @@ Prettier is an opinionated code formatter with support for: - [Markdown](https://commonmark.org/), including [GFM](https://github.github.com/gfm/) and [MDX](https://mdxjs.com/) - [YAML](https://yaml.org/) -It removes all original styling[\*](#footnotes) and ensures that all outputted code conforms to a consistent style. (See this [blog post](http://jlongster.com/A-Prettier-Formatter)) +It removes all original styling[\*](#footnotes) and ensures that all outputted code conforms to a consistent style. (See this [blog post](https://jlongster.com/A-Prettier-Formatter)) Prettier takes your code and reprints it from scratch by taking the line length into account. diff --git a/website/versioned_docs/version-stable/options.md b/website/versioned_docs/version-stable/options.md index 170a96fcf96c..b88cd4aeaaae 100644 --- a/website/versioned_docs/version-stable/options.md +++ b/website/versioned_docs/version-stable/options.md @@ -308,6 +308,21 @@ Valid options: | ------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------- | | `"css"` | --html-whitespace-sensitivity | htmlWhitespaceSensitivity: "" | +## Vue files script and style tags indentation + +_First available in v1.19.0_ + +Whether or not to indent the code inside `