Skip to content

Commit

Permalink
JavaScript: Fix parens logic for optional chaining expressions and cl…
Browse files Browse the repository at this point in the history
…osure type casts (prettier#5843)
  • Loading branch information
Yang Su authored and duailibe committed Feb 11, 2019
1 parent d0dd032 commit 71b815f
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 16 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```
25 changes: 9 additions & 16 deletions src/language-js/printer-estree.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions tests/comments/__snapshots__/jsfmt.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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} */ ({}));
Expand Down Expand Up @@ -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} */ ({}));
Expand Down
1 change: 1 addition & 0 deletions tests/comments/closure-compiler-type-cast.js
Original file line number Diff line number Diff line change
Expand Up @@ -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} */ ({}));

Expand Down
2 changes: 2 additions & 0 deletions tests/optional_chaining/__snapshots__/jsfmt.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions tests/optional_chaining/chaining.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 71b815f

Please sign in to comment.