From e3b0d3d2ea5f76e6339243d8dcae7a9a14f0f3de Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sat, 7 May 2022 14:18:42 +0800 Subject: [PATCH 1/2] feat(eslint-plugin): [no-empty-function] new allow option overrideMethods --- .../docs/rules/no-empty-function.md | 19 +++++++++++++- .../src/rules/no-empty-function.ts | 17 ++++++++++++- .../tests/rules/no-empty-function.test.ts | 25 +++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/no-empty-function.md b/packages/eslint-plugin/docs/rules/no-empty-function.md index db450a46121..77d6bb2f107 100644 --- a/packages/eslint-plugin/docs/rules/no-empty-function.md +++ b/packages/eslint-plugin/docs/rules/no-empty-function.md @@ -28,7 +28,8 @@ This rule adds the following options: type AdditionalAllowOptionEntries = | 'private-constructors' | 'protected-constructors' - | 'decoratedFunctions'; + | 'decoratedFunctions' + | 'overrideMethods'; type AllowOptionEntries = | BaseNoEmptyFunctionAllowOptionEntries @@ -77,6 +78,22 @@ class Foo { } ``` +### allow: `overrideMethods` + +Examples of correct code for the `{ "allow": ["overrideMethods"] }` option: + +```ts +abstract class Base { + protected greet(): void { + console.log('Hello!'); + } +} + +class Foo extends Base { + protected override greet(): void {} +} +``` + ## How to Use ```jsonc diff --git a/packages/eslint-plugin/src/rules/no-empty-function.ts b/packages/eslint-plugin/src/rules/no-empty-function.ts index 806312b2117..da27bd80466 100644 --- a/packages/eslint-plugin/src/rules/no-empty-function.ts +++ b/packages/eslint-plugin/src/rules/no-empty-function.ts @@ -30,6 +30,7 @@ const schema = util.deepMerge( 'asyncFunctions', 'asyncMethods', 'decoratedFunctions', + 'overrideMethods', ], }, }, @@ -63,6 +64,7 @@ export default util.createRule({ ); const isAllowedPrivateConstructors = allow.includes('private-constructors'); const isAllowedDecoratedFunctions = allow.includes('decoratedFunctions'); + const isAllowedOverrideMethods = allow.includes('overrideMethods'); /** * Check if the method body is empty @@ -138,12 +140,25 @@ export default util.createRule({ return false; } + function isAllowedEmptyOverrideMethod( + node: TSESTree.FunctionExpression, + ): boolean { + if (isAllowedOverrideMethods && isBodyEmpty(node)) { + return ( + node.parent?.type === AST_NODE_TYPES.MethodDefinition && + node.parent.override === true + ); + } + return false; + } + return { ...rules, FunctionExpression(node): void { if ( isAllowedEmptyConstructor(node) || - isAllowedEmptyDecoratedFunctions(node) + isAllowedEmptyDecoratedFunctions(node) || + isAllowedEmptyOverrideMethod(node) ) { return; } diff --git a/packages/eslint-plugin/tests/rules/no-empty-function.test.ts b/packages/eslint-plugin/tests/rules/no-empty-function.test.ts index d9f37deaaf1..7d29b0fa5a2 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-function.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-function.test.ts @@ -72,6 +72,14 @@ class Foo { `, options: [{ allow: ['decoratedFunctions'] }], }, + { + code: ` +class Foo extends Base { + override foo() {} +} + `, + options: [{ allow: ['overrideMethods'] }], + }, ], invalid: [ @@ -192,5 +200,22 @@ class Foo { }, ], }, + { + code: ` +class Foo extends Base { + override foo() {} +} + `, + errors: [ + { + messageId: 'unexpected', + data: { + name: "method 'foo'", + }, + line: 3, + column: 18, + }, + ], + }, ], }); From 12fff1d6726543213ec1ef721dabdb8036bd60d5 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 12 May 2022 10:48:12 -0400 Subject: [PATCH 2/2] Update packages/eslint-plugin/src/rules/no-empty-function.ts --- .../eslint-plugin/src/rules/no-empty-function.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-empty-function.ts b/packages/eslint-plugin/src/rules/no-empty-function.ts index da27bd80466..d3a9f74b770 100644 --- a/packages/eslint-plugin/src/rules/no-empty-function.ts +++ b/packages/eslint-plugin/src/rules/no-empty-function.ts @@ -143,13 +143,12 @@ export default util.createRule({ function isAllowedEmptyOverrideMethod( node: TSESTree.FunctionExpression, ): boolean { - if (isAllowedOverrideMethods && isBodyEmpty(node)) { - return ( - node.parent?.type === AST_NODE_TYPES.MethodDefinition && - node.parent.override === true - ); - } - return false; + return ( + isAllowedOverrideMethods && + isBodyEmpty(node) && + node.parent?.type === AST_NODE_TYPES.MethodDefinition && + node.parent.override === true + ); } return {