From 012b7a653e8c50a07791213d3083ad65a615ff58 Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Tue, 14 May 2019 19:41:49 -0300 Subject: [PATCH] Prevent adding unnecessary quotes when a computed key exists (#6119) --- CHANGELOG.unreleased.md | 27 ++++ src/language-js/printer-estree.js | 3 +- .../__snapshots__/jsfmt.spec.js.snap | 125 ++++++++++++++++++ tests/quote_props/with-member-expressions.js | 9 ++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 tests/quote_props/with-member-expressions.js diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index ac954688..7118fe12 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -126,6 +126,31 @@ const v = /** @type{string} */ value; const v = /** @type{string} */ (value); ``` +### JavaScript: Prevent adding quotes when using `--quote-props=consistent` and one of the keys were a computed "complex" expression ([#6119] by [@duailibe]) + +Previously, Prettier added unnecessary quotes to keys of an object, or properties and methods of classes, if there was at least one computed key with a "complex" expression (e.g. a member expression). + + +```js +// Input +const obj = { + foo: "", + [foo.bar]: "", +} + +// Output (Prettier stable) +const obj = { + "foo": "", + [foo.bar]: "", +} + +// Output (Prettier master) +const obj = { + foo: "", + [foo.bar]: "", +} +``` + ### Markdown: correctly determine count of backticks in inline code ([#6110] by [@belochub]) By the CommonMark spec, it is required to 'choose a string of `n` backtick characters as delimiters, where the code does not contain any strings of exactly `n` backtick characters.' @@ -155,8 +180,10 @@ This changes the method of finding the required count of backticks from using 2 [#6106]: https://github.com/prettier/prettier/pull/6106 [#6116]: https://github.com/prettier/prettier/pull/6116 [#6110]: https://github.com/prettier/prettier/pull/6110 +[#6119]: https://github.com/prettier/prettier/pull/6119 [@jridgewell]: https://github.com/jridgewell [@jwbay]: https://github.com/jwbay [@brainkim]: https://github.com/brainkim [@sosukesuzuki]: https://github.com/sosukesuzuki [@belochub]: https://github.com/belochub +[@duailibe]: https://github.com/duailibe diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 05089b2e..c4d43a02 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -3610,6 +3610,7 @@ function printPropertyKey(path, options, print) { parent.members ).some( prop => + !prop.computed && prop.key && prop.key.type !== "Identifier" && !isStringPropSafeToCoerceToIdentifier(prop, options) @@ -3632,6 +3633,7 @@ function printPropertyKey(path, options, print) { } if ( + !node.computed && isStringPropSafeToCoerceToIdentifier(node, options) && (options.quoteProps === "as-needed" || (options.quoteProps === "consistent" && !needsQuoteProps.get(parent))) @@ -6399,7 +6401,6 @@ function isStringPropSafeToCoerceToIdentifier(node, options) { return ( isStringLiteral(node.key) && isIdentifierName(node.key.value) && - !node.computed && options.parser !== "json" && !(options.parser === "typescript" && node.type === "ClassProperty") ); diff --git a/tests/quote_props/__snapshots__/jsfmt.spec.js.snap b/tests/quote_props/__snapshots__/jsfmt.spec.js.snap index 2d21433e..13712b0a 100644 --- a/tests/quote_props/__snapshots__/jsfmt.spec.js.snap +++ b/tests/quote_props/__snapshots__/jsfmt.spec.js.snap @@ -377,3 +377,128 @@ const d = { ================================================================================ `; + +exports[`with-member-expressions.js 1`] = ` +====================================options===================================== +parsers: ["flow", "babel"] +printWidth: 80 +quoteProps: "as-needed" + | printWidth +=====================================input====================================== +const obj = { + foo: "", + [foo.bar]: "" +}; + +class Foo { + foo() {} + [foo.bar]() {} +} + +=====================================output===================================== +const obj = { + foo: "", + [foo.bar]: "" +}; + +class Foo { + foo() {} + [foo.bar]() {} +} + +================================================================================ +`; + +exports[`with-member-expressions.js 2`] = ` +====================================options===================================== +parsers: ["flow", "babel"] +printWidth: 80 +quoteProps: "preserve" + | printWidth +=====================================input====================================== +const obj = { + foo: "", + [foo.bar]: "" +}; + +class Foo { + foo() {} + [foo.bar]() {} +} + +=====================================output===================================== +const obj = { + foo: "", + [foo.bar]: "" +}; + +class Foo { + foo() {} + [foo.bar]() {} +} + +================================================================================ +`; + +exports[`with-member-expressions.js 3`] = ` +====================================options===================================== +parsers: ["flow", "babel"] +printWidth: 80 +quoteProps: "consistent" + | printWidth +=====================================input====================================== +const obj = { + foo: "", + [foo.bar]: "" +}; + +class Foo { + foo() {} + [foo.bar]() {} +} + +=====================================output===================================== +const obj = { + foo: "", + [foo.bar]: "" +}; + +class Foo { + foo() {} + [foo.bar]() {} +} + +================================================================================ +`; + +exports[`with-member-expressions.js 4`] = ` +====================================options===================================== +parsers: ["flow", "babel"] +printWidth: 80 +quoteProps: "consistent" +singleQuote: true + | printWidth +=====================================input====================================== +const obj = { + foo: "", + [foo.bar]: "" +}; + +class Foo { + foo() {} + [foo.bar]() {} +} + +=====================================output===================================== +const obj = { + foo: '', + [foo.bar]: '' +}; + +class Foo { + foo() {} + [foo.bar]() {} +} + +================================================================================ +`; diff --git a/tests/quote_props/with-member-expressions.js b/tests/quote_props/with-member-expressions.js new file mode 100644 index 00000000..22c838e4 --- /dev/null +++ b/tests/quote_props/with-member-expressions.js @@ -0,0 +1,9 @@ +const obj = { + foo: "", + [foo.bar]: "" +}; + +class Foo { + foo() {} + [foo.bar]() {} +}