JavaScript: Fix parens logic for optional chaining expressions and closure type casts (#5843)

master
Yang Su 2019-02-11 07:33:56 -08:00 committed by Lucas Duailibe
parent d0dd0329f2
commit 71b815f583
6 changed files with 34 additions and 16 deletions

View File

@ -84,3 +84,22 @@ Examples:
// Output (Prettier master)
<my-element data-for={value}></my-element>
```
- JavaScript: Fix parens logic for optional chaining expressions and closure type casts ([#5843] by [@yangsu])
Logic introduced in #4542 will print parens in the wrong places and produce invalid code for optional chaining expressions (with more than 2 nodes) or closure type casts that end in function calls.
<!-- prettier-ignore -->
```js
// Input
(a?.b[c]).c();
let value = /** @type {string} */ (this.members[0]).functionCall();
// Output (Prettier stable)
a(?.b[c]).c();
let value = /** @type {string} */ this(.members[0]).functionCall();
// Output (Prettier master)
(a?.b[c]).c();
let value = /** @type {string} */ (this.members[0]).functionCall();
```

View File

@ -4926,23 +4926,16 @@ function printMemberChain(path, options, print) {
groups.length >= 2 && !groups[1][0].node.comments && shouldNotWrap(groups);
function printGroup(printedGroup) {
const result = [];
for (let i = 0; i < printedGroup.length; i++) {
// Checks if the next node (i.e. the parent node) needs parens
// and print accordingly
if (printedGroup[i + 1] && printedGroup[i + 1].needsParens) {
result.push(
"(",
printedGroup[i].printed,
printedGroup[i + 1].printed,
")"
);
i++;
} else {
result.push(printedGroup[i].printed);
}
const printed = printedGroup.map(tuple => tuple.printed);
// Checks if the last node (i.e. the parent node) needs parens and print
// accordingly
if (
printedGroup.length > 0 &&
printedGroup[printedGroup.length - 1].needsParens
) {
return concat(["(", ...printed, ")"]);
}
return concat(result);
return concat(printed);
}
function printIndentedGroup(groups) {

View File

@ -339,6 +339,7 @@ let object = {
// preserve parens only for type casts
let assignment = /** @type {string} */ (getValue());
let value = /** @type {string} */ (this.members[0]).functionCall();
functionCall(1 + /** @type {string} */ (value), /** @type {!Foo} */ ({}));
@ -389,6 +390,7 @@ let object = {
// preserve parens only for type casts
let assignment = /** @type {string} */ (getValue());
let value = /** @type {string} */ (this.members[0]).functionCall();
functionCall(1 + /** @type {string} */ (value), /** @type {!Foo} */ ({}));

View File

@ -8,6 +8,7 @@ let object = {
// preserve parens only for type casts
let assignment = /** @type {string} */ (getValue());
let value = /** @type {string} */ (this.members[0]).functionCall();
functionCall(1 + /** @type {string} */ (value), /** @type {!Foo} */ ({}));

View File

@ -25,6 +25,7 @@ delete a?.b;
a?.b[3].c?.(x).d.e?.f[3].g?.(y).h;
(a?.b).c();
(a?.b[c]).c();
(a?.b)?.c.d?.e;
(a ? b : c)?.d;
@ -52,6 +53,7 @@ delete a?.b;
a?.b[3].c?.(x).d.e?.f[3].g?.(y).h;
(a?.b).c();
(a?.b[c]).c();
a?.b?.c.d?.e;
(a ? b : c)?.d;

View File

@ -17,6 +17,7 @@ delete a?.b;
a?.b[3].c?.(x).d.e?.f[3].g?.(y).h;
(a?.b).c();
(a?.b[c]).c();
(a?.b)?.c.d?.e;
(a ? b : c)?.d;