diff --git a/docs/rules/class-methods-use-this.md b/docs/rules/class-methods-use-this.md index 9d3ca7f1940..73efc9dba54 100644 --- a/docs/rules/class-methods-use-this.md +++ b/docs/rules/class-methods-use-this.md @@ -83,6 +83,10 @@ class A { static foo() { // OK. static methods aren't expected to use this. } + + static { + // OK. static blocks are exempt. + } } ``` diff --git a/lib/rules/class-methods-use-this.js b/lib/rules/class-methods-use-this.js index 034ba3abcaf..beb742d93a7 100644 --- a/lib/rules/class-methods-use-this.js +++ b/lib/rules/class-methods-use-this.js @@ -161,8 +161,17 @@ module.exports = { /* * Class field value are implicit functions. */ - "PropertyDefinition:exit": popContext, "PropertyDefinition > *.key:exit": pushContext, + "PropertyDefinition:exit": popContext, + + /* + * Class static blocks are implicit functions. They aren't required to use `this`, + * but we have to push context so that it captures any use of `this` in the static block + * separately from enclosing contexts, because static blocks have their own `this` and it + * shouldn't count as used `this` in enclosing contexts. + */ + StaticBlock: pushContext, + "StaticBlock:exit": popContext, ThisExpression: markThisUsed, Super: markThisUsed, diff --git a/tests/lib/rules/class-methods-use-this.js b/tests/lib/rules/class-methods-use-this.js index 95c1a6f64e6..eeb122f75b0 100644 --- a/tests/lib/rules/class-methods-use-this.js +++ b/tests/lib/rules/class-methods-use-this.js @@ -41,7 +41,8 @@ ruleTester.run("class-methods-use-this", rule, { { code: "class A { #bar() {} }", options: [{ exceptMethods: ["#bar"] }], parserOptions: { ecmaVersion: 2022 } }, { code: "class A { foo = function () {} }", options: [{ enforceForClassFields: false }], parserOptions: { ecmaVersion: 2022 } }, { code: "class A { foo = () => {} }", options: [{ enforceForClassFields: false }], parserOptions: { ecmaVersion: 2022 } }, - { code: "class A { foo() { return class { [this.foo] = 1 }; } }", parserOptions: { ecmaVersion: 2022 } } + { code: "class A { foo() { return class { [this.foo] = 1 }; } }", parserOptions: { ecmaVersion: 2022 } }, + { code: "class A { static {} }", parserOptions: { ecmaVersion: 2022 } } ], invalid: [ { @@ -203,6 +204,13 @@ ruleTester.run("class-methods-use-this", rule, { errors: [ { messageId: "missingThis", data: { name: "method 'foo'" }, column: 11, endColumn: 15 } ] + }, + { + code: "class A { foo () { return class { static { this; } } } }", + parserOptions: { ecmaVersion: 2022 }, + errors: [ + { messageId: "missingThis", data: { name: "method 'foo'" }, column: 11, endColumn: 15 } + ] } ] });