diff --git a/docs/developer-guide/scope-manager-interface.md b/docs/developer-guide/scope-manager-interface.md index 10ea7446ef4..2762f74eace 100644 --- a/docs/developer-guide/scope-manager-interface.md +++ b/docs/developer-guide/scope-manager-interface.md @@ -77,7 +77,7 @@ Those members are defined but not used in ESLint. #### type * **Type:** `string` -* **Description:** The type of this scope. This is one of `"block"`, `"catch"`, `"class"`, `"class-field-initializer"`, `"for"`, `"function"`, `"function-expression-name"`, `"global"`, `"module"`, `"switch"`, `"with"`. +* **Description:** The type of this scope. This is one of `"block"`, `"catch"`, `"class"`, `"class-field-initializer"`, `"class-static-block"`, `"for"`, `"function"`, `"function-expression-name"`, `"global"`, `"module"`, `"switch"`, `"with"`. #### isStrict @@ -97,9 +97,9 @@ Those members are defined but not used in ESLint. #### variableScope * **Type:** `Scope` -* **Description:** The nearest ancestor whose `type` is one of `"class-field-initializer"`, `"function"`, `"module"`, or `"program"` . For the aforementioned scopes this is a self-reference. +* **Description:** The nearest ancestor whose `type` is one of `"class-field-initializer"`, `"class-static-block"`, `"function"`, `"global"`, or `"module"`. For the aforementioned scopes this is a self-reference. -> This represents the lowest enclosing function or top-level scope. Class field initializers are implicit functions. Historically, this was the scope which hosts variables that are defined by `var` declarations, and thus the name `variableScope`. +> This represents the lowest enclosing function or top-level scope. Class field initializers and class static blocks are implicit functions. Historically, this was the scope which hosts variables that are defined by `var` declarations, and thus the name `variableScope`. #### block diff --git a/package.json b/package.json index 1b555897697..697da3abf5a 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "doctrine": "^3.0.0", "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^6.0.0", + "eslint-scope": "^7.0.0", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.1.0", "espree": "^9.0.0", diff --git a/tests/lib/rules/no-shadow.js b/tests/lib/rules/no-shadow.js index 036c6526258..13c4c1100d6 100644 --- a/tests/lib/rules/no-shadow.js +++ b/tests/lib/rules/no-shadow.js @@ -58,7 +58,12 @@ ruleTester.run("no-shadow", rule, { { code: "var Object = 0;", options: [{ builtinGlobals: true }] }, { code: "var top = 0;", options: [{ builtinGlobals: true }], env: { browser: true } }, { code: "function foo(cb) { (function (cb) { cb(42); })(cb); }", options: [{ allow: ["cb"] }] }, - { code: "class C { foo; foo() { let foo; } }", parserOptions: { ecmaVersion: 2022 } } + { code: "class C { foo; foo() { let foo; } }", parserOptions: { ecmaVersion: 2022 } }, + { code: "class C { static { var x; } static { var x; } }", parserOptions: { ecmaVersion: 2022 } }, + { code: "class C { static { let x; } static { let x; } }", parserOptions: { ecmaVersion: 2022 } }, + { code: "class C { static { var x; { var x; /* redeclaration */ } } }", parserOptions: { ecmaVersion: 2022 } }, + { code: "class C { static { { var x; } { var x; /* redeclaration */ } } }", parserOptions: { ecmaVersion: 2022 } }, + { code: "class C { static { { let x; } { let x; } } }", parserOptions: { ecmaVersion: 2022 } } ], invalid: [ { @@ -716,6 +721,144 @@ ruleTester.run("no-shadow", rule, { line: 1, column: 31 }] + }, + { + code: "class C { static { let a; { let a; } } }", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "a", + shadowedLine: 1, + shadowedColumn: 24 + }, + type: "Identifier", + line: 1, + column: 33 + }] + }, + { + code: "class C { static { var C; } }", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "C", + shadowedLine: 1, + shadowedColumn: 7 + }, + type: "Identifier", + line: 1, + column: 24 + }] + }, + { + code: "class C { static { let C; } }", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "C", + shadowedLine: 1, + shadowedColumn: 7 + }, + type: "Identifier", + line: 1, + column: 24 + }] + }, + { + code: "var a; class C { static { var a; } }", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "a", + shadowedLine: 1, + shadowedColumn: 5 + }, + type: "Identifier", + line: 1, + column: 31 + }] + }, + { + code: "class C { static { var a; } } var a;", + options: [{ hoist: "all" }], + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "a", + shadowedLine: 1, + shadowedColumn: 35 + }, + type: "Identifier", + line: 1, + column: 24 + }] + }, + { + code: "class C { static { let a; } } let a;", + options: [{ hoist: "all" }], + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "a", + shadowedLine: 1, + shadowedColumn: 35 + }, + type: "Identifier", + line: 1, + column: 24 + }] + }, + { + code: "class C { static { var a; } } let a;", + options: [{ hoist: "all" }], + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "a", + shadowedLine: 1, + shadowedColumn: 35 + }, + type: "Identifier", + line: 1, + column: 24 + }] + }, + { + code: "class C { static { var a; class D { static { var a; } } } }", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "a", + shadowedLine: 1, + shadowedColumn: 24 + }, + type: "Identifier", + line: 1, + column: 50 + }] + }, + { + code: "class C { static { let a; class D { static { let a; } } } }", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ + messageId: "noShadow", + data: { + name: "a", + shadowedLine: 1, + shadowedColumn: 24 + }, + type: "Identifier", + line: 1, + column: 50 + }] } ] }); diff --git a/tests/lib/rules/no-undef.js b/tests/lib/rules/no-undef.js index 43697ec957d..956bbc991ab 100644 --- a/tests/lib/rules/no-undef.js +++ b/tests/lib/rules/no-undef.js @@ -91,6 +91,67 @@ ruleTester.run("no-undef", rule, { { code: "import.meta", parserOptions: { ecmaVersion: 2020, sourceType: "module" } + }, + + // class static blocks + { + code: "let a; class C { static {} } a;", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ messageId: "undef", data: { name: "a" } }] + }, + { + code: "var a; class C { static {} } a;", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ messageId: "undef", data: { name: "a" } }] + }, + { + code: "a; class C { static {} } var a;", + parserOptions: { ecmaVersion: 2022 }, + errors: [{ messageId: "undef", data: { name: "a" } }] + }, + { + code: "class C { static { C; } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "const C = class { static { C; } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { a; } } var a;", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { a; } } let a;", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { var a; a; } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { a; var a; } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { a; { var a; } } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { let a; a; } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { a; let a; } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { function a() {} a; } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } + }, + { + code: "class C { static { a; function a() {} } }", + parserOptions: { ecmaVersion: 2022, sourceType: "module" } } ], invalid: [ @@ -114,6 +175,99 @@ ruleTester.run("no-undef", rule, { ecmaVersion: 2018 }, errors: [{ messageId: "undef", data: { name: "b" } }] + }, + + // class static blocks + { + code: "class C { static { a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" } }] + }, + { + code: "class C { static { { let a; } a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 31 }] + }, + { + code: "class C { static { { function a() {} } a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 40 }] + }, + { + code: "class C { static { function foo() { var a; } a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 47 }] + }, + { + code: "class C { static { var a; } static { a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 38 }] + }, + { + code: "class C { static { let a; } static { a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 38 }] + }, + { + code: "class C { static { function a(){} } static { a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 46 }] + }, + { + code: "class C { static { var a; } foo() { a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 37 }] + }, + { + code: "class C { static { let a; } foo() { a; } }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 37 }] + }, + { + code: "class C { static { var a; } [a]; }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 30 }] + }, + { + code: "class C { static { let a; } [a]; }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 30 }] + }, + { + code: "class C { static { function a() {} } [a]; }", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 39 }] + }, + { + code: "class C { static { var a; } } a;", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [{ messageId: "undef", data: { name: "a" }, column: 31 }] } ] });