diff --git a/eslint/babel-eslint-parser/src/analyze-scope.cjs b/eslint/babel-eslint-parser/src/analyze-scope.cjs index 1a271c499c5a..ea8f7f31429c 100644 --- a/eslint/babel-eslint-parser/src/analyze-scope.cjs +++ b/eslint/babel-eslint-parser/src/analyze-scope.cjs @@ -213,8 +213,30 @@ class Referencer extends OriginalReferencer { } _visitClassProperty(node) { - this._visitTypeAnnotation(node.typeAnnotation); - this.visitProperty(node); + const { computed, key, typeAnnotation, value } = node; + + if (computed) this.visit(key); + this._visitTypeAnnotation(typeAnnotation); + + if (value) { + if (this.scopeManager.__nestClassFieldInitializerScope) { + this.scopeManager.__nestClassFieldInitializerScope(value); + } else { + // Given that ESLint 7 didn't have a "class field initializer" scope, + // we create a plain method scope. Semantics are the same. + this.scopeManager.__nestScope( + new Scope( + this.scopeManager, + "function", + this.scopeManager.__currentScope, + value, + true, + ), + ); + } + this.visit(value); + this.close(value); + } } _visitDeclareX(node) { diff --git a/eslint/babel-eslint-tests/test/integration/eslint/verify.js b/eslint/babel-eslint-tests/test/integration/eslint/verify.js index 5690052c5b17..6a4ac126a8d5 100644 --- a/eslint/babel-eslint-tests/test/integration/eslint/verify.js +++ b/eslint/babel-eslint-tests/test/integration/eslint/verify.js @@ -1749,6 +1749,17 @@ describe("verify", () => { { "no-unused-vars": 1 }, ); }); + + it("no-use-before-define allows referencing the class in a field", () => { + verifyAndAssertMessages( + ` + class C { + d = C.name; + } + `, + { "no-use-before-define": 1 }, + ); + }); }); describe("private field declarations", () => { @@ -1774,6 +1785,17 @@ describe("verify", () => { ); }); + it("no-use-before-define allows referencing the class in a field", () => { + verifyAndAssertMessages( + ` + class C { + #d = C.name; + } + `, + { "no-use-before-define": 1 }, + ); + }); + it("type annotations should work", () => { verifyAndAssertMessages( `class C {