fix(javascript): add necessary parentheses for decorators (#5785)
This commit is contained in:
4 files changed
+81
-5
No files matched your search
@@ -76,5 +76,33 @@ Examples:
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- JavaScript: Add necessary parentheses for decorators ([#5785] by [@ikatyang])
|
||||||
|
|
||||||
|
Parentheses for decorators with nested call expressions are optional for legacy decorators
|
||||||
|
but they're required for decorators in the current [proposal](https://tc39.github.io/proposal-decorators/#sec-syntax).
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
```js
|
||||||
|
// Input
|
||||||
|
class X {
|
||||||
|
@(computed().volatile())
|
||||||
|
prop
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output (Prettier stable)
|
||||||
|
class X {
|
||||||
|
@computed().volatile()
|
||||||
|
prop
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output (Prettier master)
|
||||||
|
class X {
|
||||||
|
@(computed().volatile())
|
||||||
|
prop
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[@ikatyang]: https://github.com/ikatyang
|
||||||
[@simenb]: https://github.com/SimenB
|
[@simenb]: https://github.com/SimenB
|
||||||
[#5778]: https://github.com/prettier/prettier/pull/5778
|
[#5778]: https://github.com/prettier/prettier/pull/5778
|
||||||
|
[#5785]: https://github.com/prettier/prettier/pull/5785
|
||||||
@@ -127,6 +127,35 @@ function needsParens(path, options) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parent.type === "Decorator" && parent.expression === node) {
|
||||||
|
let hasCallExpression = false;
|
||||||
|
let hasMemberExpression = false;
|
||||||
|
let current = node;
|
||||||
|
while (current) {
|
||||||
|
switch (current.type) {
|
||||||
|
case "MemberExpression":
|
||||||
|
hasMemberExpression = true;
|
||||||
|
current = current.object;
|
||||||
|
break;
|
||||||
|
case "CallExpression":
|
||||||
|
if (
|
||||||
|
/** @(x().y) */ hasMemberExpression ||
|
||||||
|
/** @(x().y()) */ hasCallExpression
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
hasCallExpression = true;
|
||||||
|
current = current.callee;
|
||||||
|
break;
|
||||||
|
case "Identifier":
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(parent.type === "ArrowFunctionExpression" &&
|
(parent.type === "ArrowFunctionExpression" &&
|
||||||
parent.body === node &&
|
parent.body === node &&
|
||||||
@@ -276,11 +305,6 @@ function needsParens(path, options) {
|
|||||||
parent.left === node &&
|
parent.left === node &&
|
||||||
(node.type === "TSTypeAssertion" || node.type === "TSAsExpression")
|
(node.type === "TSTypeAssertion" || node.type === "TSAsExpression")
|
||||||
);
|
);
|
||||||
case "Decorator":
|
|
||||||
return (
|
|
||||||
parent.expression === node &&
|
|
||||||
(node.type === "TSTypeAssertion" || node.type === "TSAsExpression")
|
|
||||||
);
|
|
||||||
|
|
||||||
case "BinaryExpression":
|
case "BinaryExpression":
|
||||||
case "LogicalExpression": {
|
case "LogicalExpression": {
|
||||||
|
|||||||
@@ -311,6 +311,26 @@ const foo = {
|
|||||||
================================================================================
|
================================================================================
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`parens.js 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["babel"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
class X {
|
||||||
|
@(computed().volatile())
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
class X {
|
||||||
|
@(computed().volatile())
|
||||||
|
x;
|
||||||
|
}
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`redux.js 1`] = `
|
exports[`redux.js 1`] = `
|
||||||
====================================options=====================================
|
====================================options=====================================
|
||||||
parsers: ["babel"]
|
parsers: ["babel"]
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
class X {
|
||||||
|
@(computed().volatile())
|
||||||
|
x
|
||||||
|
}
|
||||||
Reference in new issue
Block a user