diff --git a/docs/src/_data/further_reading_links.json b/docs/src/_data/further_reading_links.json index dc81f7f1640..333cb8e48a3 100644 --- a/docs/src/_data/further_reading_links.json +++ b/docs/src/_data/further_reading_links.json @@ -698,5 +698,12 @@ "logo": "https://eslint.org/apple-touch-icon.png", "title": "Interesting bugs caught by no-constant-binary-expression - ESLint - Pluggable JavaScript Linter", "description": "A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease." + }, + "https://github.com/tc39/proposal-class-static-block": { + "domain": "github.com", + "url": "https://github.com/tc39/proposal-class-static-block", + "logo": "https://github.com/fluidicon.png", + "title": "GitHub - tc39/proposal-class-static-block: ECMAScript class static initialization blocks", + "description": "ECMAScript class static initialization blocks. Contribute to tc39/proposal-class-static-block development by creating an account on GitHub." } } \ No newline at end of file diff --git a/docs/src/rules/no-empty-static-block.md b/docs/src/rules/no-empty-static-block.md new file mode 100644 index 00000000000..283a4e21b77 --- /dev/null +++ b/docs/src/rules/no-empty-static-block.md @@ -0,0 +1,56 @@ +--- +title: no-empty-static-block +layout: doc +rule_type: suggestion +related_rules: +- no-empty +- no-empty-function +further_reading: +- https://github.com/tc39/proposal-class-static-block +--- + +Empty static blocks, while not technically errors, usually occur due to refactoring that wasn't completed. They can cause confusion when reading code. + +## Rule Details + +This rule disallows empty static blocks. This rule ignores static blocks which contain a comment. + +Examples of **incorrect** code for this rule: + +::: incorrect + +```js +/*eslint no-empty-static-block: "error"*/ + +class Foo { + static {} +} +``` + +::: + +Examples of **correct** code for this rule: + +:::correct + +```js +/*eslint no-empty-static-block: "error"*/ + +class Foo { + static { + bar(); + } +} + +class Foo { + static { + // comment + } +} +``` + +::: + +## When Not To Use It + +This rule should not be used in environments prior to ES2022. diff --git a/lib/rules/index.js b/lib/rules/index.js index 565648c09e8..f729887d068 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -123,6 +123,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({ "no-empty-character-class": () => require("./no-empty-character-class"), "no-empty-function": () => require("./no-empty-function"), "no-empty-pattern": () => require("./no-empty-pattern"), + "no-empty-static-block": () => require("./no-empty-static-block"), "no-eq-null": () => require("./no-eq-null"), "no-eval": () => require("./no-eval"), "no-ex-assign": () => require("./no-ex-assign"), diff --git a/lib/rules/no-empty-static-block.js b/lib/rules/no-empty-static-block.js new file mode 100644 index 00000000000..ab710628824 --- /dev/null +++ b/lib/rules/no-empty-static-block.js @@ -0,0 +1,47 @@ +/** + * @fileoverview Rule to disallow empty static blocks. + * @author Sosuke Suzuki + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** @type {import('../shared/types').Rule} */ +module.exports = { + meta: { + type: "suggestion", + + docs: { + description: "Disallow empty static blocks", + recommended: false, + url: "https://eslint.org/docs/rules/no-empty-static-block" + }, + + schema: [], + + messages: { + unexpected: "Unexpected empty static block." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + StaticBlock(node) { + if (node.body.length === 0) { + const closingBrace = sourceCode.getLastToken(node); + + if (sourceCode.getCommentsBefore(closingBrace).length === 0) { + context.report({ + node, + messageId: "unexpected" + }); + } + } + } + }; + } +}; diff --git a/tests/lib/rules/no-empty-static-block.js b/tests/lib/rules/no-empty-static-block.js new file mode 100644 index 00000000000..592c840ff3d --- /dev/null +++ b/tests/lib/rules/no-empty-static-block.js @@ -0,0 +1,51 @@ +/** + * @fileoverview Tests for no-empty-static-block rule. + * @author Sosuke Suzuki + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require("../../../lib/rules/no-empty-static-block"), + { RuleTester } = require("../../../lib/rule-tester"); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ + parserOptions: { ecmaVersion: 2022 } +}); + +ruleTester.run("no-empty-static-block", rule, { + valid: [ + "class Foo { static { bar(); } }", + "class Foo { static { /* comments */ } }", + "class Foo { static {\n// comment\n} }", + "class Foo { static { bar(); } static { bar(); } }" + ], + invalid: [ + { + code: "class Foo { static {} }", + errors: [{ messageId: "unexpected" }] + }, + { + code: "class Foo { static { } }", + errors: [{ messageId: "unexpected" }] + }, + { + code: "class Foo { static { \n\n } }", + errors: [{ messageId: "unexpected" }] + }, + { + code: "class Foo { static { bar(); } static {} }", + errors: [{ messageId: "unexpected" }] + }, + { + code: "class Foo { static // comment\n {} }", + errors: [{ messageId: "unexpected" }] + } + ] +}); diff --git a/tools/rule-types.json b/tools/rule-types.json index 9867d6b2f33..ed6a8123d21 100644 --- a/tools/rule-types.json +++ b/tools/rule-types.json @@ -110,6 +110,7 @@ "no-empty-character-class": "problem", "no-empty-function": "suggestion", "no-empty-pattern": "problem", + "no-empty-static-block": "suggestion", "no-eq-null": "suggestion", "no-eval": "suggestion", "no-ex-assign": "problem",