Fix parentheses for TSInstantiationExpression (#20027)
This commit is contained in:
1 parent
5765169aa1
commit
1b68844e4d
9 files changed
+183
-5
No files matched your search
@@ -0,0 +1,16 @@
|
||||
#### Add missing parentheses for `TSInstantiationExpression` (#20027 by @fisker)
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```tsx
|
||||
// Input
|
||||
new (a?.b<h>)();
|
||||
(a?.b<c>)`foo`;
|
||||
|
||||
// Prettier stable
|
||||
new a?.b<h>();
|
||||
a?.b<c>`foo`;
|
||||
|
||||
// Prettier main
|
||||
new (a?.b<h>)();
|
||||
(a?.b<c>)`foo`;
|
||||
```
|
||||
@@ -8,7 +8,6 @@ function shouldAddParenthesesToChainExpression(path) {
|
||||
const { key, parent } = path;
|
||||
|
||||
return (
|
||||
(key === "expression" && parent.type === "TSNonNullExpression") ||
|
||||
(key === "object" &&
|
||||
parent.type === "MemberExpression" &&
|
||||
!parent.optional) ||
|
||||
@@ -16,7 +15,8 @@ function shouldAddParenthesesToChainExpression(path) {
|
||||
parent.type === "CallExpression" &&
|
||||
!parent.optional) ||
|
||||
(key === "callee" && parent.type === "NewExpression") ||
|
||||
(key === "tag" && parent.type === "TaggedTemplateExpression")
|
||||
(key === "tag" && parent.type === "TaggedTemplateExpression") ||
|
||||
(key === "expression" && parent.type === "TSNonNullExpression")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,14 +56,17 @@ function isBabelOptionalChainRoot(path) {
|
||||
);
|
||||
}
|
||||
|
||||
function isChainExpressionRoot(path) {
|
||||
return path.node.type === "ChainExpression" || isBabelOptionalChainRoot(path);
|
||||
}
|
||||
|
||||
/**
|
||||
@param {AstPath} path
|
||||
@returns {boolean}
|
||||
*/
|
||||
function shouldAddParenthesesToChainElement(path) {
|
||||
return (
|
||||
(path.node.type === "ChainExpression" || isBabelOptionalChainRoot(path)) &&
|
||||
shouldAddParenthesesToChainExpression(path)
|
||||
isChainExpressionRoot(path) && shouldAddParenthesesToChainExpression(path)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -878,7 +878,32 @@ function needsParentheses(path, options) {
|
||||
);
|
||||
|
||||
case "TSInstantiationExpression":
|
||||
return key === "object" && isMemberExpression(parent);
|
||||
/*
|
||||
There are cases not really needed parentheses
|
||||
- `(a<B>)()`
|
||||
- `new (A<B>)()`
|
||||
- ``` (a<B>)`` ```
|
||||
- `class A extends (A<B>) {}`
|
||||
|
||||
However, `typescript-eslint` produces different AST,
|
||||
we simply add parentheses without checking the shape of the expression.
|
||||
|
||||
See https://github.com/typescript-eslint/typescript-eslint/issues/12863
|
||||
See https://github.com/typescript-eslint/typescript-eslint/issues/12012
|
||||
*/
|
||||
if (
|
||||
(key === "object" && isMemberExpression(parent)) ||
|
||||
(key === "callee" && parent.type === "CallExpression") ||
|
||||
(key === "callee" && parent.type === "NewExpression") ||
|
||||
(key === "tag" && parent.type === "TaggedTemplateExpression") ||
|
||||
(key === "superClass" &&
|
||||
(parent.type === "ClassDeclaration" ||
|
||||
parent.type === "ClassExpression"))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "MatchOrPattern":
|
||||
return parent.type === "MatchAsPattern";
|
||||
|
||||
@@ -76,6 +76,14 @@ foo((a?.b)!);
|
||||
(a?.b!()).c?.();
|
||||
(a?.b())!.c?.();
|
||||
|
||||
// \`TSInstantiationExpression\`
|
||||
a<b>();
|
||||
(a<b>)();
|
||||
(a?.b)<c>;
|
||||
(a?.b<c>);
|
||||
(a?.b!)<c>;
|
||||
(a?.b)!<c>;
|
||||
|
||||
=====================================output=====================================
|
||||
// Member expressions
|
||||
(a?.b)!();
|
||||
@@ -148,6 +156,14 @@ a?.b()!?.();
|
||||
(a?.b!()).c?.();
|
||||
(a?.b())!.c?.();
|
||||
|
||||
// \`TSInstantiationExpression\`
|
||||
a<b>();
|
||||
(a<b>)();
|
||||
a?.b<c>;
|
||||
a?.b<c>;
|
||||
a?.b!<c>;
|
||||
(a?.b)!<c>;
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
@@ -543,6 +559,18 @@ new Foo(a?.b!);
|
||||
new ((a?.b!)?.c)();
|
||||
new ((a?.b)!?.c)();
|
||||
|
||||
// \`TSInstantiationExpression\`
|
||||
new a<b>();
|
||||
new (a<b>)();
|
||||
new (a.b<c>)();
|
||||
new (a.b)<c>();
|
||||
new (a?.b<c>)();
|
||||
new (a?.b)<c>();
|
||||
new ((a?.b)!<c>)();
|
||||
new ((a?.b)!)<c>();
|
||||
new ((a?.b!)<c>)();
|
||||
new ((a?.b!))<c>();
|
||||
|
||||
=====================================output=====================================
|
||||
// Member expressions
|
||||
new (a?.b)!();
|
||||
@@ -613,6 +641,18 @@ new Foo(a?.b!);
|
||||
new (a?.b!?.c)();
|
||||
new ((a?.b)!?.c)();
|
||||
|
||||
// \`TSInstantiationExpression\`
|
||||
new a<b>();
|
||||
new (a<b>)();
|
||||
new (a.b<c>)();
|
||||
new a.b<c>();
|
||||
new (a?.b<c>)();
|
||||
new (a?.b)<c>();
|
||||
new ((a?.b)!<c>)();
|
||||
new (a?.b)!<c>();
|
||||
new (a?.b!<c>)();
|
||||
new (a?.b!)<c>();
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
@@ -687,6 +727,18 @@ parsers: ["typescript"]
|
||||
((a?.b!)?.c)\`\`;
|
||||
((a?.b)!?.c)\`\`;
|
||||
|
||||
// \`TSInstantiationExpression\`
|
||||
a<b>\`\`;
|
||||
(a<b>)\`\`;
|
||||
(a.b<c>)\`\`;
|
||||
(a.b)<c>\`\`;
|
||||
(a?.b<c>)\`\`;
|
||||
(a?.b)<c>\`\`;
|
||||
((a?.b)!<c>)\`\`;
|
||||
((a?.b)!)<c>\`\`;
|
||||
((a?.b!)<c>)\`\`;
|
||||
((a?.b!))<c>\`\`;
|
||||
|
||||
=====================================output=====================================
|
||||
// Member expressions
|
||||
(a?.b)!\`\`;
|
||||
@@ -754,6 +806,18 @@ a(b?.c!)\`\`;
|
||||
(a?.b!?.c)\`\`;
|
||||
((a?.b)!?.c)\`\`;
|
||||
|
||||
// \`TSInstantiationExpression\`
|
||||
a<b>\`\`;
|
||||
(a<b>)\`\`;
|
||||
(a.b<c>)\`\`;
|
||||
a.b<c>\`\`;
|
||||
(a?.b<c>)\`\`;
|
||||
(a?.b)<c>\`\`;
|
||||
((a?.b)!<c>)\`\`;
|
||||
(a?.b)!<c>\`\`;
|
||||
(a?.b!<c>)\`\`;
|
||||
(a?.b!)<c>\`\`;
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
|
||||
@@ -68,3 +68,11 @@ foo((a?.b)!);
|
||||
(a?.b())!?.();
|
||||
(a?.b!()).c?.();
|
||||
(a?.b())!.c?.();
|
||||
|
||||
// `TSInstantiationExpression`
|
||||
a<b>();
|
||||
(a<b>)();
|
||||
(a?.b)<c>;
|
||||
(a?.b<c>);
|
||||
(a?.b!)<c>;
|
||||
(a?.b)!<c>;
|
||||
@@ -66,3 +66,15 @@ new Foo(a?.b!);
|
||||
// In optional chaining
|
||||
new ((a?.b!)?.c)();
|
||||
new ((a?.b)!?.c)();
|
||||
|
||||
// `TSInstantiationExpression`
|
||||
new a<b>();
|
||||
new (a<b>)();
|
||||
new (a.b<c>)();
|
||||
new (a.b)<c>();
|
||||
new (a?.b<c>)();
|
||||
new (a?.b)<c>();
|
||||
new ((a?.b)!<c>)();
|
||||
new ((a?.b)!)<c>();
|
||||
new ((a?.b!)<c>)();
|
||||
new ((a?.b!))<c>();
|
||||
@@ -63,3 +63,15 @@
|
||||
// In optional chaining
|
||||
((a?.b!)?.c)``;
|
||||
((a?.b)!?.c)``;
|
||||
|
||||
// `TSInstantiationExpression`
|
||||
a<b>``;
|
||||
(a<b>)``;
|
||||
(a.b<c>)``;
|
||||
(a.b)<c>``;
|
||||
(a?.b<c>)``;
|
||||
(a?.b)<c>``;
|
||||
((a?.b)!<c>)``;
|
||||
((a?.b)!)<c>``;
|
||||
((a?.b!)<c>)``;
|
||||
((a?.b!))<c>``;
|
||||
@@ -150,6 +150,35 @@ a[(Array<string>).name];
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`super-class.ts format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["typescript"]
|
||||
printWidth: 80 (default) |
|
||||
=====================================input======================================
|
||||
class ClassDeclaration_1 extends B<T> {}
|
||||
( class ClassExpresssion_1 extends B<T> {} );
|
||||
class ClassDeclaration_2 extends (B<T>) {}
|
||||
( class ClassExpresssion_2 extends (B<T>) {} );
|
||||
|
||||
// This not really make sense
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/12012
|
||||
class ClassDeclaration_3 extends (B<T>)<T> {}
|
||||
( class ClassExpresssion_3 extends (B<T>)<T> {} );
|
||||
|
||||
=====================================output=====================================
|
||||
class ClassDeclaration_1 extends B<T> {}
|
||||
(class ClassExpresssion_1 extends B<T> {});
|
||||
class ClassDeclaration_2 extends (B<T>) {}
|
||||
(class ClassExpresssion_2 extends (B<T>) {});
|
||||
|
||||
// This not really make sense
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/12012
|
||||
class ClassDeclaration_3 extends (B<T>)<T> {}
|
||||
(class ClassExpresssion_3 extends (B<T>)<T> {});
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`typeof.ts format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["typescript"]
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class ClassDeclaration_1 extends B<T> {}
|
||||
( class ClassExpresssion_1 extends B<T> {} );
|
||||
class ClassDeclaration_2 extends (B<T>) {}
|
||||
( class ClassExpresssion_2 extends (B<T>) {} );
|
||||
|
||||
// This not really make sense
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/12012
|
||||
class ClassDeclaration_3 extends (B<T>)<T> {}
|
||||
( class ClassExpresssion_3 extends (B<T>)<T> {} );
|
||||
Reference in new issue
Block a user