From d2fecde3156576eaa749ed31c90a6af5f3c03a0a Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Sat, 29 Oct 2022 23:12:40 +0900 Subject: [PATCH 1/4] fix(eslint-plugin): [no-extra-parens] handle type assertion in extends clause --- packages/eslint-plugin/src/rules/no-extra-parens.ts | 13 ++++++++++++- .../tests/rules/no-extra-parens.test.ts | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-extra-parens.ts b/packages/eslint-plugin/src/rules/no-extra-parens.ts index 3a4a5973074..9b4a12cf71a 100644 --- a/packages/eslint-plugin/src/rules/no-extra-parens.ts +++ b/packages/eslint-plugin/src/rules/no-extra-parens.ts @@ -141,7 +141,18 @@ export default util.createRule({ }, BinaryExpression: binaryExp, CallExpression: callExp, - // ClassDeclaration + ClassDeclaration(node) { + if (node.superClass?.type === AST_NODE_TYPES.TSAsExpression) { + return rules.ClassDeclaration({ + ...node, + superClass: { + ...node.superClass, + type: AST_NODE_TYPES.SequenceExpression as any, + }, + }); + } + return rules.ClassDeclaration(node); + }, // ClassExpression ConditionalExpression(node) { // reduces the precedence of the node so the rule thinks it needs to be wrapped diff --git a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts index 6a9e87111aa..379b93b8305 100644 --- a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts @@ -141,6 +141,7 @@ t.true((me.get as SinonStub).calledWithExactly('/foo', other)); t.true((me.get).calledWithExactly('/foo', other)); (requestInit.headers as Headers).get('Cookie'); ( requestInit.headers).get('Cookie'); +class Foo extends (Bar as any) {} `, parserOptions: { ecmaFeatures: { @@ -254,6 +255,7 @@ new a((1)); a<(A)>((1)); async function f(arg: Promise) { await (arg); } async function f(arg: any) { await ((arg as Promise)); } +class Foo extends ((Bar as any)) {} `, output: ` a = b * c; @@ -267,6 +269,7 @@ new a(1); a<(A)>(1); async function f(arg: Promise) { await arg; } async function f(arg: any) { await (arg as Promise); } +class Foo extends (Bar as any) {} `, errors: [ { @@ -324,6 +327,11 @@ async function f(arg: any) { await (arg as Promise); } line: 12, column: 37, }, + { + messageId: 'unexpected', + line: 13, + column: 20, + }, ], }), ...batchedSingleLineTests({ From 0a93e9f42b4917564d55ae997fb1a65a415d4872 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Sat, 29 Oct 2022 23:54:24 +0900 Subject: [PATCH 2/4] Add test cases --- packages/eslint-plugin/tests/rules/no-extra-parens.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts index 379b93b8305..9e730c8e553 100644 --- a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts @@ -256,6 +256,7 @@ a<(A)>((1)); async function f(arg: Promise) { await (arg); } async function f(arg: any) { await ((arg as Promise)); } class Foo extends ((Bar as any)) {} +class Foo extends (Bar) {} `, output: ` a = b * c; @@ -270,6 +271,7 @@ a<(A)>(1); async function f(arg: Promise) { await arg; } async function f(arg: any) { await (arg as Promise); } class Foo extends (Bar as any) {} +class Foo extends Bar {} `, errors: [ { @@ -332,6 +334,11 @@ class Foo extends (Bar as any) {} line: 13, column: 20, }, + { + messageId: 'unexpected', + line: 14, + column: 19, + }, ], }), ...batchedSingleLineTests({ From f9d980fc0a9753802d27a8228c591ff0c9478a88 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Sun, 30 Oct 2022 00:01:05 +0900 Subject: [PATCH 3/4] Handle class expression --- .../eslint-plugin/src/rules/no-extra-parens.ts | 13 ++++++++++++- .../tests/rules/no-extra-parens.test.ts | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-extra-parens.ts b/packages/eslint-plugin/src/rules/no-extra-parens.ts index 9b4a12cf71a..a44276a0a76 100644 --- a/packages/eslint-plugin/src/rules/no-extra-parens.ts +++ b/packages/eslint-plugin/src/rules/no-extra-parens.ts @@ -153,7 +153,18 @@ export default util.createRule({ } return rules.ClassDeclaration(node); }, - // ClassExpression + ClassExpression(node) { + if (node.superClass?.type === AST_NODE_TYPES.TSAsExpression) { + return rules.ClassExpression({ + ...node, + superClass: { + ...node.superClass, + type: AST_NODE_TYPES.SequenceExpression as any, + }, + }); + } + return rules.ClassExpression(node); + }, ConditionalExpression(node) { // reduces the precedence of the node so the rule thinks it needs to be wrapped if (util.isTypeAssertion(node.test)) { diff --git a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts index 9e730c8e553..0960c7e4082 100644 --- a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts @@ -142,6 +142,7 @@ t.true((me.get).calledWithExactly('/foo', other)); (requestInit.headers as Headers).get('Cookie'); ( requestInit.headers).get('Cookie'); class Foo extends (Bar as any) {} +const foo = class extends (Bar as any) {} `, parserOptions: { ecmaFeatures: { @@ -257,6 +258,8 @@ async function f(arg: Promise) { await (arg); } async function f(arg: any) { await ((arg as Promise)); } class Foo extends ((Bar as any)) {} class Foo extends (Bar) {} +const foo = class extends ((Bar as any)) {} +const foo = class extends (Bar) {} `, output: ` a = b * c; @@ -272,6 +275,8 @@ async function f(arg: Promise) { await arg; } async function f(arg: any) { await (arg as Promise); } class Foo extends (Bar as any) {} class Foo extends Bar {} +const foo = class extends (Bar as any) {} +const foo = class extends Bar {} `, errors: [ { @@ -339,6 +344,16 @@ class Foo extends Bar {} line: 14, column: 19, }, + { + messageId: 'unexpected', + line: 15, + column: 28, + }, + { + messageId: 'unexpected', + line: 16, + column: 27, + }, ], }), ...batchedSingleLineTests({ From a45d11302b22822b7465901540cd6e58e1ee8279 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Sun, 30 Oct 2022 00:11:38 +0900 Subject: [PATCH 4/4] Add test cases --- packages/eslint-plugin/tests/rules/no-extra-parens.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts index 0960c7e4082..369f55101f2 100644 --- a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts @@ -141,7 +141,9 @@ t.true((me.get as SinonStub).calledWithExactly('/foo', other)); t.true((me.get).calledWithExactly('/foo', other)); (requestInit.headers as Headers).get('Cookie'); ( requestInit.headers).get('Cookie'); +class Foo {} class Foo extends (Bar as any) {} +const foo = class {}; const foo = class extends (Bar as any) {} `, parserOptions: {