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;
|
const { key, parent } = path;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
(key === "expression" && parent.type === "TSNonNullExpression") ||
|
|
||||||
(key === "object" &&
|
(key === "object" &&
|
||||||
parent.type === "MemberExpression" &&
|
parent.type === "MemberExpression" &&
|
||||||
!parent.optional) ||
|
!parent.optional) ||
|
||||||
@@ -16,7 +15,8 @@ function shouldAddParenthesesToChainExpression(path) {
|
|||||||
parent.type === "CallExpression" &&
|
parent.type === "CallExpression" &&
|
||||||
!parent.optional) ||
|
!parent.optional) ||
|
||||||
(key === "callee" && parent.type === "NewExpression") ||
|
(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
|
@param {AstPath} path
|
||||||
@returns {boolean}
|
@returns {boolean}
|
||||||
*/
|
*/
|
||||||
function shouldAddParenthesesToChainElement(path) {
|
function shouldAddParenthesesToChainElement(path) {
|
||||||
return (
|
return (
|
||||||
(path.node.type === "ChainExpression" || isBabelOptionalChainRoot(path)) &&
|
isChainExpressionRoot(path) && shouldAddParenthesesToChainExpression(path)
|
||||||
shouldAddParenthesesToChainExpression(path)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -878,7 +878,32 @@ function needsParentheses(path, options) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
case "TSInstantiationExpression":
|
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":
|
case "MatchOrPattern":
|
||||||
return parent.type === "MatchAsPattern";
|
return parent.type === "MatchAsPattern";
|
||||||
|
|||||||
@@ -76,6 +76,14 @@ foo((a?.b)!);
|
|||||||
(a?.b!()).c?.();
|
(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>;
|
||||||
|
|
||||||
=====================================output=====================================
|
=====================================output=====================================
|
||||||
// Member expressions
|
// Member expressions
|
||||||
(a?.b)!();
|
(a?.b)!();
|
||||||
@@ -148,6 +156,14 @@ a?.b()!?.();
|
|||||||
(a?.b!()).c?.();
|
(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>;
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -543,6 +559,18 @@ new Foo(a?.b!);
|
|||||||
new ((a?.b!)?.c)();
|
new ((a?.b!)?.c)();
|
||||||
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=====================================
|
=====================================output=====================================
|
||||||
// Member expressions
|
// Member expressions
|
||||||
new (a?.b)!();
|
new (a?.b)!();
|
||||||
@@ -613,6 +641,18 @@ new Foo(a?.b!);
|
|||||||
new (a?.b!?.c)();
|
new (a?.b!?.c)();
|
||||||
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)\`\`;
|
||||||
((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=====================================
|
=====================================output=====================================
|
||||||
// Member expressions
|
// Member expressions
|
||||||
(a?.b)!\`\`;
|
(a?.b)!\`\`;
|
||||||
@@ -754,6 +806,18 @@ a(b?.c!)\`\`;
|
|||||||
(a?.b!?.c)\`\`;
|
(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())!?.();
|
||||||
(a?.b!()).c?.();
|
(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>;
|
||||||
@@ -66,3 +66,15 @@ new Foo(a?.b!);
|
|||||||
// In optional chaining
|
// In optional chaining
|
||||||
new ((a?.b!)?.c)();
|
new ((a?.b!)?.c)();
|
||||||
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
|
// In optional chaining
|
||||||
((a?.b!)?.c)``;
|
((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>``;
|
||||||
@@ -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`] = `
|
exports[`typeof.ts format 1`] = `
|
||||||
====================================options=====================================
|
====================================options=====================================
|
||||||
parsers: ["typescript"]
|
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