Repository: eslint/eslint
Pull request #14899 (2021-08-07 03:38:51)

Chore: add assetions on reporting location in `semi` (refs #12334)
<!--
    Thank you for contributing!

    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

#### Prerequisites checklist

- [x] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/master/CONTRIBUTING.md).

#### What is the purpose of this pull request? (put an "X" next to an item)

<!--
    The following template is intentionally not a markdown checkbox list for the reasons
    explained in https://github.com/eslint/eslint/pull/12848#issuecomment-580302888
-->

[x] Other, please explain: Refs https://github.com/eslint/eslint/issues/12334

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

#### What changes did you make? (Give an overview)

add test assertions on location for `semi`

#### Is there anything you'd like reviewers to focus on?
No


Patch:
diff --git a/.markdownlintignore b/.markdownlintignore
new file mode 100644
index 000000000..1b763b1ba
--- /dev/null
+++ b/.markdownlintignore
@@ -0,0 +1,1 @@
+CHANGELOG.md
diff --git a/Makefile.js b/Makefile.js
index e84d21abf..3ee1b4c1b 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -43,7 +43,7 @@ const { cat, cd, cp, echo, exec, exit, find, ls, mkdir, pwd, rm, test } = requir
 const PERF_MULTIPLIER = 13e6;
 
 const OPEN_SOURCE_LICENSES = [
-    /MIT/u, /BSD/u, /Apache/u, /ISC/u, /WTF/u, /Public Domain/u, /LGPL/u
+    /MIT/u, /BSD/u, /Apache/u, /ISC/u, /WTF/u, /Public Domain/u, /LGPL/u, /Python/u
 ];
 
 //------------------------------------------------------------------------------
@@ -66,7 +66,8 @@ const NODE = "node ", // intentional extra space
     // Files
     RULE_FILES = glob.sync("lib/rules/*.js").filter(filePath => path.basename(filePath) !== "index.js"),
     JSON_FILES = find("conf/").filter(fileType("json")),
-    MARKDOWN_FILES_ARRAY = find("docs/").concat(ls(".")).filter(fileType("md")),
+    MARKDOWNLINT_IGNORED_FILES = fs.readFileSync(path.join(__dirname, ".markdownlintignore"), "utf-8").split("\n"),
+    MARKDOWN_FILES_ARRAY = find("docs/").concat(ls(".")).filter(fileType("md")).filter(file => !MARKDOWNLINT_IGNORED_FILES.includes(file)),
     TEST_FILES = "\"tests/{bin,lib,tools}/**/*.js\"",
     PERF_ESLINTRC = path.join(PERF_TMP_DIR, "eslintrc.yml"),
     PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"),
@@ -213,7 +214,7 @@ function generateRuleIndexPage() {
     // `.rules` will be `undefined` if all rules in category are deprecated.
     categoriesData.categories = categoriesData.categories.filter(category => !!category.rules);
 
-    const output = yaml.safeDump(categoriesData, { sortKeys: true });
+    const output = yaml.dump(categoriesData, { sortKeys: true });
 
     output.to(outputFile);
 }
@@ -389,7 +390,7 @@ function getFirstVersionOfDeletion(filePath) {
  * @private
  */
 function lintMarkdown(files) {
-    const config = yaml.safeLoad(fs.readFileSync(path.join(__dirname, "./.markdownlint.yml"), "utf8")),
+    const config = yaml.load(fs.readFileSync(path.join(__dirname, "./.markdownlint.yml"), "utf8")),
         result = markdownlint.sync({
             files,
             config,
diff --git a/README.md b/README.md
index a429bdf84..3082aeffb 100644
--- a/README.md
+++ b/README.md
@@ -298,7 +298,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <p><a href="https://automattic.com"><img src="https://images.opencollective.com/photomatt/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
 <p><a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="96"></a> <a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://coinbase.com"><img src="https://avatars.githubusercontent.com/u/1885080?v=4" alt="Coinbase" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://retool.com/"><img src="https://images.opencollective.com/retool/98ea68e/logo.png" alt="Retool" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
-<p><a href="https://mobilen.nu"><img src="https://images.opencollective.com/mobilen/e19860d/logo.png" alt="Mobilen" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="null"><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
+<p><a href="https://troypoint.com"><img src="https://images.opencollective.com/troypoint/080f96f/avatar.png" alt="TROYPOINT" height="32"></a> <a href="https://mobilen.nu"><img src="https://images.opencollective.com/mobilen/e19860d/logo.png" alt="Mobilen" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="null"><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
 <!--sponsorsend-->
 
 ## <a name="technology-sponsors"></a>Technology Sponsors
diff --git a/docs/rules/dot-notation.md b/docs/rules/dot-notation.md
index a13049a3f..26c77756c 100644
--- a/docs/rules/dot-notation.md
+++ b/docs/rules/dot-notation.md
@@ -46,6 +46,19 @@ var foo = { "class": "CS 101" }
 var x = foo["class"]; // Property name is a reserved word, square-bracket notation required
 ```
 
+Examples of additional **correct** code for the `{ "allowKeywords": false }` option:
+
+```js
+/*eslint dot-notation: ["error", { "allowKeywords": false }]*/
+
+class C {
+    #in;
+    foo() {
+        this.#in; // Dot notation is required for private identifiers
+    }
+}
+```
+
 ### allowPattern
 
 For example, when preparing data to be sent to an external API, it is often required to use property names that include underscores.  If the `camelcase` rule is in effect, these [snake case](https://en.wikipedia.org/wiki/Snake_case) properties would not be allowed.  By providing an `allowPattern` to the `dot-notation` rule, these snake case properties can be accessed with bracket notation.
diff --git a/docs/rules/func-names.md b/docs/rules/func-names.md
index 27b9cc20f..ea1ba617e 100644
--- a/docs/rules/func-names.md
+++ b/docs/rules/func-names.md
@@ -17,14 +17,14 @@ This rule can enforce or disallow the use of named function expressions.
 This rule has a string option:
 
 * `"always"` (default) requires function expressions to have a name
-* `"as-needed"` requires function expressions to have a name, if the name cannot be assigned automatically in an ES6 environment
+* `"as-needed"` requires function expressions to have a name, if the name isn't assigned automatically per the ECMAScript specification.
 * `"never"` disallows named function expressions, except in recursive functions, where a name is needed
 
 This rule has an object option:
 
 * `"generators": "always" | "as-needed" | "never"`
     * `"always"` require named generators
-    * `"as-needed"` require named generators if the name cannot be assigned automatically in an ES6 environment.
+    * `"as-needed"` require named generators if the name isn't assigned automatically per the ECMAScript specification.
     * `"never"` disallow named generators where possible.
 
 When a value for `generators` is not provided the behavior for generator functions falls back to the base option.
@@ -98,6 +98,13 @@ const cat = {
   meow: function() {}
 }
 
+class C {
+    #bar = function() {};
+    baz = function() {};
+}
+
+quux ??= function() {};
+
 (function bar() {
     // ...
 }())
diff --git a/docs/rules/no-console.md b/docs/rules/no-console.md
index f2fb79ec4..b1e4e601c 100644
--- a/docs/rules/no-console.md
+++ b/docs/rules/no-console.md
@@ -9,7 +9,7 @@ console.error("That shouldn't have happened.");
 
 ## Rule Details
 
-This rule disallows calls to methods of the `console` object.
+This rule disallows calls or assignments to methods of the `console` object.
 
 Examples of **incorrect** code for this rule:
 
@@ -19,6 +19,7 @@ Examples of **incorrect** code for this rule:
 console.log("Log a debug level message.");
 console.warn("Log a warn level message.");
 console.error("Log an error level message.");
+console.log = foo();
 ```
 
 Examples of **correct** code for this rule:
diff --git a/docs/rules/no-extra-parens.md b/docs/rules/no-extra-parens.md
index 68b986eff..b521dcbe2 100644
--- a/docs/rules/no-extra-parens.md
+++ b/docs/rules/no-extra-parens.md
@@ -48,6 +48,14 @@ for (a of (b));
 typeof (a);
 
 (function(){} ? a() : b());
+
+class A {
+    [(x)] = 1;
+}
+
+class B {
+    x = (y + z);
+}
 ```
 
 Examples of **correct** code for this rule with the default `"all"` option:
@@ -72,6 +80,14 @@ for (a of b);
 for (a in b, c);
 
 for (a in b);
+
+class A {
+    [x] = 1;
+}
+
+class B {
+    x = y + z;
+}
 ```
 
 ### conditionalAssign
diff --git a/docs/rules/no-multi-assign.md b/docs/rules/no-multi-assign.md
index 7ef705675..14721dab0 100644
--- a/docs/rules/no-multi-assign.md
+++ b/docs/rules/no-multi-assign.md
@@ -26,12 +26,19 @@ const foo = bar = "baz";
 let a =
     b =
     c;
+
+class Foo {
+    a = b = 10;
+}
+
+a = b = "quux";
 ```
 
 Examples of **correct** code for this rule:
 
 ```js
 /*eslint no-multi-assign: "error"*/
+
 var a = 5;
 var b = 5;
 var c = 5;
@@ -41,13 +48,21 @@ const bar = "baz";
 
 let a = c;
 let b = c;
+
+class Foo {
+    a = 10;
+    b = 10;
+}
+
+a = "quux";
+b = "quux";
 ```
 
 ## Options
 
 This rule has an object option:
 
-* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration. Default is `false`.
+* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration or initializing a class field. Default is `false`.
 
 ### ignoreNonDeclaration
 
@@ -73,6 +88,10 @@ Examples of **incorrect** code for the `{ "ignoreNonDeclaration": true }` option
 let a = b = "baz";
 
 const foo = bar = 1;
+
+class Foo {
+    a = b = 10;
+}
 ```
 
 ## Related Rules
diff --git a/docs/rules/no-useless-computed-key.md b/docs/rules/no-useless-computed-key.md
index 9b3c59284..2d3ddb3d5 100644
--- a/docs/rules/no-useless-computed-key.md
+++ b/docs/rules/no-useless-computed-key.md
@@ -20,7 +20,6 @@ Examples of **incorrect** code for this rule:
 
 ```js
 /*eslint no-useless-computed-key: "error"*/
-/*eslint-env es6*/
 
 var a = { ['0']: 0 };
 var a = { ['0+1,234']: 0 };
@@ -41,6 +40,18 @@ var c = { a: 0 };
 var c = { '0+1,234': 0 };
 ```
 
+Examples of additional **correct** code for this rule:
+
+```js
+/*eslint no-useless-computed-key: "error"*/
+
+var c = {
+    "__proto__": foo, // defines object's prototype
+
+    ["__proto__"]: bar // defines a property named "__proto__"
+};
+```
+
 ## Options
 
 This rule has an object option:
@@ -52,24 +63,64 @@ This rule has an object option:
 By default, this rule does not check class declarations and class expressions,
 as the default value for `enforceForClassMembers` is `false`.
 
-When `enforceForClassMembers` is set to `true`, the rule will also disallow unnecessary computed
-keys inside of class methods, getters and setters.
+When `enforceForClassMembers` is set to `true`, the rule will also disallow unnecessary computed keys inside of class fields, class methods, class getters, and class setters.
 
-Examples of **incorrect** code for `{ "enforceForClassMembers": true }`:
+Examples of **incorrect** code for this rule with the `{ "enforceForClassMembers": true }` option:
 
 ```js
 /*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/
 
 class Foo {
+    ["foo"] = "bar";
+
     [0]() {}
     ['a']() {}
     get ['b']() {}
     set ['c'](value) {}
 
+    static ["foo"] = "bar";
+
     static ['a']() {}
 }
 ```
 
+Examples of **correct** code for this rule with the `{ "enforceForClassMembers": true }` option:
+
+```js
+/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/
+
+class Foo {
+    "foo" = "bar";
+
+    0() {}
+    'a'() {}
+    get 'b'() {}
+    set 'c'(value) {}
+
+    static "foo" = "bar";
+
+    static 'a'() {}
+}
+```
+
+Examples of additional **correct** code for this rule with the `{ "enforceForClassMembers": true }` option:
+
+```js
+/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/
+
+class Foo {
+    ["constructor"]; // instance field named "constructor"
+
+    "constructor"() {} // the constructor of this class
+
+    ["constructor"]() {} // method named "constructor"
+
+    static ["constructor"]; // static field named "constructor"
+
+    static ["prototype"]; // runtime error, it would be a parsing error without `[]`
+}
+```
+
 ## When Not To Use It
 
 If you don't want to be notified about unnecessary computed property keys, you can safely disable this rule.
diff --git a/docs/rules/prefer-destructuring.md b/docs/rules/prefer-destructuring.md
index 7f18559ed..64e914fce 100644
--- a/docs/rules/prefer-destructuring.md
+++ b/docs/rules/prefer-destructuring.md
@@ -62,6 +62,17 @@ Examples of **correct** code when `enforceForRenamedProperties` is enabled:
 var { bar: foo } = object;
 ```
 
+Examples of additional **correct** code when `enforceForRenamedProperties` is enabled:
+
+```javascript
+class C {
+    #x;
+    foo() {
+        const bar = this.#x; // private identifiers are not allowed in destructuring
+    }
+}
+```
+
 An example configuration, with the defaults `array` and `object` filled in, looks like this:
 
 ```json
diff --git a/lib/cli-engine/formatters/tap.js b/lib/cli-engine/formatters/tap.js
index 354872a0c..e4148a3b3 100644
--- a/lib/cli-engine/formatters/tap.js
+++ b/lib/cli-engine/formatters/tap.js
@@ -31,7 +31,7 @@ function outputDiagnostics(diagnostic) {
     const prefix = "  ";
     let output = `${prefix}---\n`;
 
-    output += prefix + yaml.safeDump(diagnostic).split("\n").join(`\n${prefix}`);
+    output += prefix + yaml.dump(diagnostic).split("\n").join(`\n${prefix}`);
     output += "...\n";
     return output;
 }
diff --git a/lib/init/config-file.js b/lib/init/config-file.js
index 4c648ac05..a51f92e1c 100644
--- a/lib/init/config-file.js
+++ b/lib/init/config-file.js
@@ -63,7 +63,7 @@ function writeYAMLConfigFile(config, filePath) {
     // lazy load YAML to improve performance when not used
     const yaml = require("js-yaml");
 
-    const content = yaml.safeDump(config, { sortKeys: true });
+    const content = yaml.dump(config, { sortKeys: true });
 
     fs.writeFileSync(filePath, content, "utf8");
 }
diff --git a/lib/rules/dot-notation.js b/lib/rules/dot-notation.js
index 3aa9f3110..20434f359 100644
--- a/lib/rules/dot-notation.js
+++ b/lib/rules/dot-notation.js
@@ -141,6 +141,7 @@ module.exports = {
                 if (
                     !allowKeywords &&
                     !node.computed &&
+                    node.property.type === "Identifier" &&
                     keywords.indexOf(String(node.property.name)) !== -1
                 ) {
                     context.report({
diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js
index 307e340c9..d06335046 100644
--- a/lib/rules/no-extra-parens.js
+++ b/lib/rules/no-extra-parens.js
@@ -808,13 +808,6 @@ module.exports = {
 
             CallExpression: checkCallNew,
 
-            ClassBody(node) {
-                node.body
-                    .filter(member => member.type === "MethodDefinition" && member.computed && member.key)
-                    .filter(member => hasExcessParensWithPrecedence(member.key, PRECEDENCE_OF_ASSIGNMENT_EXPR))
-                    .forEach(member => report(member.key));
-            },
-
             ConditionalExpression(node) {
                 if (isReturnAssignException(node)) {
                     return;
@@ -1063,6 +1056,12 @@ module.exports = {
                 }
             },
 
+            "MethodDefinition[computed=true]"(node) {
+                if (hasExcessParensWithPrecedence(node.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
+                    report(node.key);
+                }
+            },
+
             NewExpression: checkCallNew,
 
             ObjectExpression(node) {
@@ -1090,6 +1089,16 @@ module.exports = {
                 }
             },
 
+            PropertyDefinition(node) {
+                if (node.computed && hasExcessParensWithPrecedence(node.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
+                    report(node.key);
+                }
+
+                if (node.value && hasExcessParensWithPrecedence(node.value, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
+                    report(node.value);
+                }
+            },
+
             RestElement(node) {
                 const argument = node.argument;
 
diff --git a/lib/rules/no-useless-computed-key.js b/lib/rules/no-useless-computed-key.js
index 08df71265..a66430619 100644
--- a/lib/rules/no-useless-computed-key.js
+++ b/lib/rules/no-useless-computed-key.js
@@ -10,6 +10,76 @@
 
 const astUtils = require("./utils/ast-utils");
 
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+/**
+ * Determines whether the computed key syntax is unnecessarily used for the given node.
+ * In particular, it determines whether removing the square brackets and using the content between them
+ * directly as the key (e.g. ['foo'] -> 'foo') would produce valid syntax and preserve the same behavior.
+ * Valid non-computed keys are only: identifiers, number literals and string literals.
+ * Only literals can preserve the same behavior, with a few exceptions for specific node types:
+ * Property
+ *   - { ["__proto__"]: foo } defines a property named "__proto__"
+ *     { "__proto__": foo } defines object's prototype
+ * PropertyDefinition
+ *   - class C { ["constructor"]; } defines an instance field named "constructor"
+ *     class C { "constructor"; } produces a parsing error
+ *   - class C { static ["constructor"]; } defines a static field named "constructor"
+ *     class C { static "constructor"; } produces a parsing error
+ *   - class C { static ["prototype"]; } produces a runtime error (doesn't break the whole script)
+ *     class C { static "prototype"; } produces a parsing error (breaks the whole script)
+ * MethodDefinition
+ *   - class C { ["constructor"]() {} } defines a prototype method named "constructor"
+ *     class C { "constructor"() {} } defines the constructor
+ *   - class C { static ["prototype"]() {} } produces a runtime error (doesn't break the whole script)
+ *     class C { static "prototype"() {} } produces a parsing error (breaks the whole script)
+ * @param {ASTNode} node The node to check. It can be `Property`, `PropertyDefinition` or `MethodDefinition`.
+ * @returns {void} `true` if the node has useless computed key.
+ */
+function hasUselessComputedKey(node) {
+    if (!node.computed) {
+        return false;
+    }
+
+    const { key } = node;
+
+    if (key.type !== "Literal") {
+        return false;
+    }
+
+    const { value } = key;
+
+    if (typeof value !== "number" && typeof value !== "string") {
+        return false;
+    }
+
+    switch (node.type) {
+        case "Property":
+            return value !== "__proto__";
+
+        case "PropertyDefinition":
+            if (node.static) {
+                return value !== "constructor" && value !== "prototype";
+            }
+
+            return value !== "constructor";
+
+        case "MethodDefinition":
+            if (node.static) {
+                return value !== "prototype";
+            }
+
+            return value !== "constructor";
+
+        /* istanbul ignore next */
+        default:
+            throw new Error(`Unexpected node type: ${node.type}`);
+    }
+
+}
+
 //------------------------------------------------------------------------------
 // Rule Definition
 //------------------------------------------------------------------------------
@@ -51,22 +121,9 @@ module.exports = {
          * @returns {void}
          */
         function check(node) {
-            if (!node.computed) {
-                return;
-            }
-
-            const key = node.key,
-                nodeType = typeof key.value;
-
-            let allowedKey;
-
-            if (node.type === "MethodDefinition") {
-                allowedKey = node.static ? "prototype" : "constructor";
-            } else {
-                allowedKey = "__proto__";
-            }
+            if (hasUselessComputedKey(node)) {
+                const { key } = node;
 
-            if (key.type === "Literal" && (nodeType === "string" || nodeType === "number") && key.value !== allowedKey) {
                 context.report({
                     node,
                     messageId: "unnecessarilyComputedProperty",
diff --git a/lib/rules/prefer-destructuring.js b/lib/rules/prefer-destructuring.js
index f82bb75c1..f76087e52 100644
--- a/lib/rules/prefer-destructuring.js
+++ b/lib/rules/prefer-destructuring.js
@@ -221,7 +221,11 @@ module.exports = {
          * @returns {void}
          */
         function performCheck(leftNode, rightNode, reportNode) {
-            if (rightNode.type !== "MemberExpression" || rightNode.object.type === "Super") {
+            if (
+                rightNode.type !== "MemberExpression" ||
+                rightNode.object.type === "Super" ||
+                rightNode.property.type === "PrivateIdentifier"
+            ) {
                 return;
             }
 
diff --git a/package.json b/package.json
index 98b79a48f..746d6cc70 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
     "escape-string-regexp": "^4.0.0",
     "eslint-scope": "^6.0.0",
     "eslint-utils": "^3.0.0",
-    "eslint-visitor-keys": "^2.1.0",
+    "eslint-visitor-keys": "^3.0.0",
     "espree": "^8.0.0",
     "esquery": "^1.4.0",
     "esutils": "^2.0.2",
@@ -72,7 +72,7 @@
     "import-fresh": "^3.0.0",
     "imurmurhash": "^0.1.4",
     "is-glob": "^4.0.0",
-    "js-yaml": "^3.13.1",
+    "js-yaml": "^4.1.0",
     "json-stable-stringify-without-jsonify": "^1.0.1",
     "levn": "^0.4.1",
     "lodash.merge": "^4.6.2",
@@ -116,8 +116,8 @@
     "karma-webpack": "^5.0.0",
     "lint-staged": "^11.0.0",
     "load-perf": "^0.2.0",
-    "markdownlint": "^0.19.0",
-    "markdownlint-cli": "^0.22.0",
+    "markdownlint": "^0.23.1",
+    "markdownlint-cli": "^0.28.1",
     "memfs": "^3.0.1",
     "mocha": "^8.3.2",
     "mocha-junit-reporter": "^2.0.0",


Test patch:
diff --git a/tests/lib/init/config-file.js b/tests/lib/init/config-file.js
index e9fe62e2c..50a9af1d5 100644
--- a/tests/lib/init/config-file.js
+++ b/tests/lib/init/config-file.js
@@ -60,8 +60,8 @@ describe("ConfigFile", () => {
         [
             ["JavaScript", "foo.js", espree.parse],
             ["JSON", "bar.json", JSON.parse],
-            ["YAML", "foo.yaml", yaml.safeLoad],
-            ["YML", "foo.yml", yaml.safeLoad]
+            ["YAML", "foo.yaml", yaml.load],
+            ["YML", "foo.yml", yaml.load]
         ].forEach(([fileType, filename, validate]) => {
 
             it(`should write a file through fs when a ${fileType} path is passed`, () => {
diff --git a/tests/lib/rules/dot-notation.js b/tests/lib/rules/dot-notation.js
index fed94c128..249faf80e 100644
--- a/tests/lib/rules/dot-notation.js
+++ b/tests/lib/rules/dot-notation.js
@@ -59,7 +59,12 @@ ruleTester.run("dot-notation", rule, {
         "a[void 0];",
         "a[b()];",
         { code: "a[/(?<zero>0)/];", parserOptions: { ecmaVersion: 2018 } },
-        { code: "class C { foo() { this['#a'] } }", parserOptions: { ecmaVersion: 2022 } }
+        { code: "class C { foo() { this['#a'] } }", parserOptions: { ecmaVersion: 2022 } },
+        {
+            code: "class C { #in; foo() { this.#in; } }",
+            options: [{ allowKeywords: false }],
+            parserOptions: { ecmaVersion: 2022 }
+        }
     ],
     invalid: [
         {
diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js
index a14ececc0..5a4dba648 100644
--- a/tests/lib/rules/no-extra-parens.js
+++ b/tests/lib/rules/no-extra-parens.js
@@ -44,7 +44,7 @@ function invalid(code, output, type, line, config) {
 
 const ruleTester = new RuleTester({
     parserOptions: {
-        ecmaVersion: 2021,
+        ecmaVersion: 2022,
         ecmaFeatures: {
             jsx: true
         }
@@ -182,6 +182,25 @@ ruleTester.run("no-extra-parens", rule, {
         "class foo { a(){} [b](){} c(){} [(d,e)](){} }",
         "class foo { [(a,b)](){} c(){} [d](){} e(){} }",
         "const foo = class { constructor(){} a(){} get b(){} set b(bar){} get c(){} set d(baz){} static e(){} }",
+        "class foo { x; }",
+        "class foo { static x; }",
+        "class foo { x = 1; }",
+        "class foo { static x = 1; }",
+        "class foo { #x; }",
+        "class foo { static #x; }",
+        "class foo { static #x = 1; }",
+        "class foo { #x(){} get #y() {} set #y(value) {} static #z(){} static get #q() {} static set #q(value) {} }",
+        "const foo  = class { #x(){} get #y() {} set #y(value) {} static #z(){} static get #q() {} static set #q(value) {} }",
+        "class foo { [(x, y)]; }",
+        "class foo { static [(x, y)]; }",
+        "class foo { [(x, y)] = 1; }",
+        "class foo { static [(x, y)] = 1; }",
+        "class foo { x = (y, z); }",
+        "class foo { static x = (y, z); }",
+        "class foo { #x = (y, z); }",
+        "class foo { static #x = (y, z); }",
+        "class foo { [(1, 2)] = (3, 4) }",
+        "const foo = class { [(1, 2)] = (3, 4) }",
 
         // ExpressionStatement restricted productions
         "({});",
@@ -771,6 +790,26 @@ ruleTester.run("no-extra-parens", rule, {
         invalid("class foo { [(a,b)](){} [(c+d)](){} }", "class foo { [(a,b)](){} [c+d](){} }", "BinaryExpression"),
         invalid("class foo { [a+(b*c)](){} }", "class foo { [a+b*c](){} }", "BinaryExpression"),
         invalid("const foo = class { [(a)](){} }", "const foo = class { [a](){} }", "Identifier"),
+        invalid("class foo { [(x)]; }", "class foo { [x]; }", "Identifier"),
+        invalid("class foo { static [(x)]; }", "class foo { static [x]; }", "Identifier"),
+        invalid("class foo { [(x)] = 1; }", "class foo { [x] = 1; }", "Identifier"),
+        invalid("class foo { static [(x)] = 1; }", "class foo { static [x] = 1; }", "Identifier"),
+        invalid("const foo = class { [(x)]; }", "const foo = class { [x]; }", "Identifier"),
+        invalid("class foo { [(x = y)]; }", "class foo { [x = y]; }", "AssignmentExpression"),
+        invalid("class foo { [(x + y)]; }", "class foo { [x + y]; }", "BinaryExpression"),
+        invalid("class foo { [(x ? y : z)]; }", "class foo { [x ? y : z]; }", "ConditionalExpression"),
+        invalid("class foo { [((x, y))]; }", "class foo { [(x, y)]; }", "SequenceExpression"),
+        invalid("class foo { x = (y); }", "class foo { x = y; }", "Identifier"),
+        invalid("class foo { static x = (y); }", "class foo { static x = y; }", "Identifier"),
+        invalid("class foo { #x = (y); }", "class foo { #x = y; }", "Identifier"),
+        invalid("class foo { static #x = (y); }", "class foo { static #x = y; }", "Identifier"),
+        invalid("const foo = class { x = (y); }", "const foo = class { x = y; }", "Identifier"),
+        invalid("class foo { x = (() => {}); }", "class foo { x = () => {}; }", "ArrowFunctionExpression"),
+        invalid("class foo { x = (y + z); }", "class foo { x = y + z; }", "BinaryExpression"),
+        invalid("class foo { x = (y ? z : q); }", "class foo { x = y ? z : q; }", "ConditionalExpression"),
+        invalid("class foo { x = ((y, z)); }", "class foo { x = (y, z); }", "SequenceExpression"),
+
+        //
         invalid(
             "var foo = (function*() { if ((yield foo())) { return; } }())",
             "var foo = (function*() { if (yield foo()) { return; } }())",
diff --git a/tests/lib/rules/no-useless-computed-key.js b/tests/lib/rules/no-useless-computed-key.js
index a7bf323cf..37f311188 100644
--- a/tests/lib/rules/no-useless-computed-key.js
+++ b/tests/lib/rules/no-useless-computed-key.js
@@ -42,6 +42,9 @@ ruleTester.run("no-useless-computed-key", rule, {
         { code: "class Foo { static ['constructor']() {} }", options: [{ enforceForClassMembers: false }] },
         { code: "class Foo { ['prototype']() {} }", options: [{ enforceForClassMembers: false }] },
         { code: "class Foo { a }", options: [{ enforceForClassMembers: true }] },
+        { code: "class Foo { ['constructor'] }", options: [{ enforceForClassMembers: true }] },
+        { code: "class Foo { static ['constructor'] }", options: [{ enforceForClassMembers: true }] },
+        { code: "class Foo { static ['prototype'] }", options: [{ enforceForClassMembers: true }] },
 
         /*
          * Well-known browsers throw syntax error bigint literals on property names,
@@ -241,6 +244,22 @@ ruleTester.run("no-useless-computed-key", rule, {
                 data: { property: "2" },
                 type: "Property"
             }]
+        }, {
+            code: "({ ['constructor']: 1 })",
+            output: "({ 'constructor': 1 })",
+            errors: [{
+                messageId: "unnecessarilyComputedProperty",
+                data: { property: "'constructor'" },
+                type: "Property"
+            }]
+        }, {
+            code: "({ ['prototype']: 1 })",
+            output: "({ 'prototype': 1 })",
+            errors: [{
+                messageId: "unnecessarilyComputedProperty",
+                data: { property: "'prototype'" },
+                type: "Property"
+            }]
         }, {
             code: "class Foo { ['0']() {} }",
             output: "class Foo { '0'() {} }",
@@ -461,6 +480,24 @@ ruleTester.run("no-useless-computed-key", rule, {
                 data: { property: "'x'" },
                 type: "MethodDefinition"
             }]
+        }, {
+            code: "(class { ['__proto__']() {} })",
+            output: "(class { '__proto__'() {} })",
+            options: [{ enforceForClassMembers: true }],
+            errors: [{
+                messageId: "unnecessarilyComputedProperty",
+                data: { property: "'__proto__'" },
+                type: "MethodDefinition"
+            }]
+        }, {
+            code: "(class { static ['__proto__']() {} })",
+            output: "(class { static '__proto__'() {} })",
+            options: [{ enforceForClassMembers: true }],
+            errors: [{
+                messageId: "unnecessarilyComputedProperty",
+                data: { property: "'__proto__'" },
+                type: "MethodDefinition"
+            }]
         }, {
             code: "(class { static ['constructor']() {} })",
             output: "(class { static 'constructor'() {} })",
@@ -515,6 +552,33 @@ ruleTester.run("no-useless-computed-key", rule, {
                 data: { property: "'#foo'" },
                 type: "PropertyDefinition"
             }]
+        }, {
+            code: "(class { ['__proto__'] })",
+            output: "(class { '__proto__' })",
+            options: [{ enforceForClassMembers: true }],
+            errors: [{
+                messageId: "unnecessarilyComputedProperty",
+                data: { property: "'__proto__'" },
+                type: "PropertyDefinition"
+            }]
+        }, {
+            code: "(class { static ['__proto__'] })",
+            output: "(class { static '__proto__' })",
+            options: [{ enforceForClassMembers: true }],
+            errors: [{
+                messageId: "unnecessarilyComputedProperty",
+                data: { property: "'__proto__'" },
+                type: "PropertyDefinition"
+            }]
+        }, {
+            code: "(class { ['prototype'] })",
+            output: "(class { 'prototype' })",
+            options: [{ enforceForClassMembers: true }],
+            errors: [{
+                messageId: "unnecessarilyComputedProperty",
+                data: { property: "'prototype'" },
+                type: "PropertyDefinition"
+            }]
         }
     ]
 });
diff --git a/tests/lib/rules/prefer-destructuring.js b/tests/lib/rules/prefer-destructuring.js
index 8f111a1d8..7f808a642 100644
--- a/tests/lib/rules/prefer-destructuring.js
+++ b/tests/lib/rules/prefer-destructuring.js
@@ -16,7 +16,7 @@ const rule = require("../../../lib/rules/prefer-destructuring"),
 // Tests
 //------------------------------------------------------------------------------
 
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2020 } });
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2022 } });
 
 ruleTester.run("prefer-destructuring", rule, {
     valid: [
@@ -157,7 +157,40 @@ ruleTester.run("prefer-destructuring", rule, {
 
         // Optional chaining
         "var foo = array?.[0];", // because the fixed code can throw TypeError.
-        "var foo = object?.foo;"
+        "var foo = object?.foo;",
+
+        // Private identifiers
+        "class C { #x; foo() { const x = this.#x; } }",
+        "class C { #x; foo() { x = this.#x; } }",
+        "class C { #x; foo(a) { x = a.#x; } }",
+        {
+            code: "class C { #x; foo() { const x = this.#x; } }",
+            options: [{ array: true, object: true }, { enforceForRenamedProperties: true }]
+        },
+        {
+            code: "class C { #x; foo() { const y = this.#x; } }",
+            options: [{ array: true, object: true }, { enforceForRenamedProperties: true }]
+        },
+        {
+            code: "class C { #x; foo() { x = this.#x; } }",
+            options: [{ array: true, object: true }, { enforceForRenamedProperties: true }]
+        },
+        {
+            code: "class C { #x; foo() { y = this.#x; } }",
+            options: [{ array: true, object: true }, { enforceForRenamedProperties: true }]
+        },
+        {
+            code: "class C { #x; foo(a) { x = a.#x; } }",
+            options: [{ array: true, object: true }, { enforceForRenamedProperties: true }]
+        },
+        {
+            code: "class C { #x; foo(a) { y = a.#x; } }",
+            options: [{ array: true, object: true }, { enforceForRenamedProperties: true }]
+        },
+        {
+            code: "class C { #x; foo() { x = this.a.#x; } }",
+            options: [{ array: true, object: true }, { enforceForRenamedProperties: true }]
+        }
     ],
 
     invalid: [
diff --git a/tests/lib/rules/semi.js b/tests/lib/rules/semi.js
index 740251bff..092dae153 100644
--- a/tests/lib/rules/semi.js
+++ b/tests/lib/rules/semi.js
@@ -316,6 +316,7 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "ImportDeclaration",
+                line: 1,
                 column: 33,
                 endLine: void 0,
                 endColumn: void 0
@@ -327,7 +328,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ImportDeclaration"
+                type: "ImportDeclaration",
+                line: 1,
+                column: 35,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -336,7 +341,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ImportDeclaration"
+                type: "ImportDeclaration",
+                line: 1,
+                column: 37,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -345,7 +354,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ImportDeclaration"
+                type: "ImportDeclaration",
+                line: 1,
+                column: 19,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -354,7 +367,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ImportDeclaration"
+                type: "ImportDeclaration",
+                line: 1,
+                column: 55,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -362,7 +379,11 @@ ruleTester.run("semi", rule, {
             output: "function foo() { return []; }",
             errors: [{
                 messageId: "missingSemi",
-                type: "ReturnStatement"
+                type: "ReturnStatement",
+                line: 1,
+                column: 27,
+                endLine: 1,
+                endColumn: 28
             }]
         },
         {
@@ -370,7 +391,11 @@ ruleTester.run("semi", rule, {
             output: "while(true) { break; }",
             errors: [{
                 messageId: "missingSemi",
-                type: "BreakStatement"
+                type: "BreakStatement",
+                line: 1,
+                column: 20,
+                endLine: 1,
+                endColumn: 21
             }]
         },
         {
@@ -378,7 +403,11 @@ ruleTester.run("semi", rule, {
             output: "while(true) { continue; }",
             errors: [{
                 messageId: "missingSemi",
-                type: "ContinueStatement"
+                type: "ContinueStatement",
+                line: 1,
+                column: 23,
+                endLine: 1,
+                endColumn: 24
             }]
         },
         {
@@ -387,7 +416,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6 },
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 10,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -395,7 +428,11 @@ ruleTester.run("semi", rule, {
             output: "var x = 5;",
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 10,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -403,7 +440,11 @@ ruleTester.run("semi", rule, {
             output: "var x = 5, y;",
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 13,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -411,7 +452,11 @@ ruleTester.run("semi", rule, {
             output: "debugger;",
             errors: [{
                 messageId: "missingSemi",
-                type: "DebuggerStatement"
+                type: "DebuggerStatement",
+                line: 1,
+                column: 9,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -420,7 +465,9 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "ExpressionStatement",
+                line: 1,
                 column: 6,
+                endLine: void 0,
                 endColumn: void 0
             }]
         },
@@ -430,6 +477,7 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "ExpressionStatement",
+                line: 1,
                 column: 6,
                 endLine: 2,
                 endColumn: 1
@@ -441,6 +489,7 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "ExpressionStatement",
+                line: 1,
                 column: 6,
                 endLine: 2,
                 endColumn: 1
@@ -452,6 +501,7 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "ExpressionStatement",
+                line: 1,
                 column: 6,
                 endLine: 2,
                 endColumn: 1
@@ -463,6 +513,7 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "ExpressionStatement",
+                line: 1,
                 column: 6,
                 endLine: 2,
                 endColumn: 1
@@ -473,7 +524,11 @@ ruleTester.run("semi", rule, {
             output: "for (var a in b) var i; ",
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 23,
+                endLine: 1,
+                endColumn: 24
             }]
         },
         {
@@ -481,7 +536,11 @@ ruleTester.run("semi", rule, {
             output: "for (;;){var i;}",
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 15,
+                endLine: 1,
+                endColumn: 16
             }]
         },
         {
@@ -489,7 +548,11 @@ ruleTester.run("semi", rule, {
             output: "for (;;) var i; ",
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 15,
+                endLine: 1,
+                endColumn: 16
             }]
         },
         {
@@ -497,7 +560,11 @@ ruleTester.run("semi", rule, {
             output: "for (var j;;) {var i;}",
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 21,
+                endLine: 1,
+                endColumn: 22
             }]
         },
         {
@@ -506,7 +573,10 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "VariableDeclaration",
-                line: 3
+                line: 3,
+                column: 2,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -515,7 +585,10 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "VariableDeclaration",
-                line: 1
+                line: 1,
+                column: 8,
+                endLine: 2,
+                endColumn: 1
             }]
         },
         {
@@ -524,7 +597,10 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "ThrowStatement",
-                line: 1
+                line: 1,
+                column: 23,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -533,7 +609,10 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "missingSemi",
                 type: "DoWhileStatement",
-                line: 1
+                line: 1,
+                column: 16,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -541,7 +620,9 @@ ruleTester.run("semi", rule, {
             output: "if (foo) {bar();}",
             errors: [{
                 messageId: "missingSemi",
+                line: 1,
                 column: 16,
+                endLine: 1,
                 endColumn: 17
             }]
         },
@@ -550,7 +631,9 @@ ruleTester.run("semi", rule, {
             output: "if (foo) {bar();} ",
             errors: [{
                 messageId: "missingSemi",
+                line: 1,
                 column: 16,
+                endLine: 1,
                 endColumn: 17
             }]
         },
@@ -559,6 +642,7 @@ ruleTester.run("semi", rule, {
             output: "if (foo) {bar();\n}",
             errors: [{
                 messageId: "missingSemi",
+                line: 1,
                 column: 16,
                 endLine: 2,
                 endColumn: 1
@@ -572,7 +656,10 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "extraSemi",
                 type: "ThrowStatement",
-                column: 23
+                line: 1,
+                column: 23,
+                endLine: 1,
+                endColumn: 24
             }]
         },
         {
@@ -581,7 +668,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "ReturnStatement"
+                type: "ReturnStatement",
+                line: 1,
+                column: 27,
+                endLine: 1,
+                endColumn: 28
             }]
         },
         {
@@ -590,7 +681,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "BreakStatement"
+                type: "BreakStatement",
+                line: 1,
+                column: 20,
+                endLine: 1,
+                endColumn: 21
             }]
         },
         {
@@ -599,7 +694,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "ContinueStatement"
+                type: "ContinueStatement",
+                line: 1,
+                column: 23,
+                endLine: 1,
+                endColumn: 24
             }]
         },
         {
@@ -609,7 +708,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6 },
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 10,
+                endLine: 1,
+                endColumn: 11
             }]
         },
         {
@@ -618,7 +721,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 10,
+                endLine: 1,
+                endColumn: 11
             }]
         },
         {
@@ -627,7 +734,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 13,
+                endLine: 1,
+                endColumn: 14
             }]
         },
         {
@@ -636,7 +747,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "DebuggerStatement"
+                type: "DebuggerStatement",
+                line: 1,
+                column: 9,
+                endLine: 1,
+                endColumn: 10
             }]
         },
         {
@@ -645,7 +760,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "ExpressionStatement"
+                type: "ExpressionStatement",
+                line: 1,
+                column: 6,
+                endLine: 1,
+                endColumn: 7
             }]
         },
         {
@@ -654,7 +773,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 23,
+                endLine: 1,
+                endColumn: 24
             }]
         },
         {
@@ -663,7 +786,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 15,
+                endLine: 1,
+                endColumn: 16
             }]
         },
         {
@@ -672,7 +799,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 15,
+                endLine: 1,
+                endColumn: 16
             }]
         },
         {
@@ -681,7 +812,11 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 21,
+                endLine: 1,
+                endColumn: 22
             }]
         },
         {
@@ -691,7 +826,10 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "extraSemi",
                 type: "VariableDeclaration",
-                line: 3
+                line: 3,
+                column: 2,
+                endLine: 3,
+                endColumn: 3
             }]
         },
         {
@@ -701,7 +839,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "ImportDeclaration"
+                type: "ImportDeclaration",
+                line: 1,
+                column: 55,
+                endLine: 1,
+                endColumn: 56
             }]
         },
         {
@@ -711,7 +853,10 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "extraSemi",
                 type: "DoWhileStatement",
-                line: 1
+                line: 1,
+                column: 16,
+                endLine: 1,
+                endColumn: 17
             }]
         },
 
@@ -720,7 +865,11 @@ ruleTester.run("semi", rule, {
             output: "if (foo) { bar();\n }",
             options: ["always", { omitLastInOneLineBlock: true }],
             errors: [{
-                messageId: "missingSemi"
+                messageId: "missingSemi",
+                line: 1,
+                column: 17,
+                endLine: 2,
+                endColumn: 1
             }]
         },
         {
@@ -728,7 +877,11 @@ ruleTester.run("semi", rule, {
             output: "if (foo) {\n bar(); }",
             options: ["always", { omitLastInOneLineBlock: true }],
             errors: [{
-                messageId: "missingSemi"
+                messageId: "missingSemi",
+                line: 2,
+                column: 7,
+                endLine: 2,
+                endColumn: 8
             }]
         },
         {
@@ -736,7 +889,11 @@ ruleTester.run("semi", rule, {
             output: "if (foo) {\n bar(); baz(); }",
             options: ["always", { omitLastInOneLineBlock: true }],
             errors: [{
-                messageId: "missingSemi"
+                messageId: "missingSemi",
+                line: 2,
+                column: 14,
+                endLine: 2,
+                endColumn: 15
             }]
         },
         {
@@ -744,7 +901,11 @@ ruleTester.run("semi", rule, {
             output: "if (foo) { bar() }",
             options: ["always", { omitLastInOneLineBlock: true }],
             errors: [{
-                messageId: "extraSemi"
+                messageId: "extraSemi",
+                line: 1,
+                column: 17,
+                endLine: 1,
+                endColumn: 18
             }]
         },
 
@@ -756,7 +917,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ExportAllDeclaration"
+                type: "ExportAllDeclaration",
+                line: 1,
+                column: 20,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -765,7 +930,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ExportNamedDeclaration"
+                type: "ExportNamedDeclaration",
+                line: 1,
+                column: 26,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -774,7 +943,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ExportNamedDeclaration"
+                type: "ExportNamedDeclaration",
+                line: 1,
+                column: 27,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -783,7 +956,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 15,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -792,7 +969,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 15,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -801,7 +982,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 22,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -810,7 +995,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ExportDefaultDeclaration"
+                type: "ExportDefaultDeclaration",
+                line: 1,
+                column: 26,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -819,7 +1008,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ExportDefaultDeclaration"
+                type: "ExportDefaultDeclaration",
+                line: 1,
+                column: 34,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -828,7 +1021,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ExportDefaultDeclaration"
+                type: "ExportDefaultDeclaration",
+                line: 1,
+                column: 24,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
         {
@@ -837,7 +1034,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "missingSemi",
-                type: "ExportDefaultDeclaration"
+                type: "ExportDefaultDeclaration",
+                line: 1,
+                column: 25,
+                endLine: void 0,
+                endColumn: void 0
             }]
         },
 
@@ -850,7 +1051,9 @@ ruleTester.run("semi", rule, {
             errors: [{
                 messageId: "extraSemi",
                 type: "ExportAllDeclaration",
+                line: 1,
                 column: 20,
+                endLine: 1,
                 endColumn: 21
             }]
         },
@@ -861,7 +1064,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "ExportNamedDeclaration"
+                type: "ExportNamedDeclaration",
+                line: 1,
+                column: 26,
+                endLine: 1,
+                endColumn: 27
             }]
         },
         {
@@ -871,7 +1078,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "ExportNamedDeclaration"
+                type: "ExportNamedDeclaration",
+                line: 1,
+                column: 27,
+                endLine: 1,
+                endColumn: 28
             }]
         },
         {
@@ -881,7 +1092,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 15,
+                endLine: 1,
+                endColumn: 16
             }]
         },
         {
@@ -891,7 +1106,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 15,
+                endLine: 1,
+                endColumn: 16
             }]
         },
         {
@@ -901,7 +1120,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "VariableDeclaration"
+                type: "VariableDeclaration",
+                line: 1,
+                column: 22,
+                endLine: 1,
+                endColumn: 23
             }]
         },
         {
@@ -911,7 +1134,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "ExportDefaultDeclaration"
+                type: "ExportDefaultDeclaration",
+                line: 1,
+                column: 26,
+                endLine: 1,
+                endColumn: 27
             }]
         },
         {
@@ -921,7 +1148,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "ExportDefaultDeclaration"
+                type: "ExportDefaultDeclaration",
+                line: 1,
+                column: 34,
+                endLine: 1,
+                endColumn: 35
             }]
         },
         {
@@ -931,7 +1162,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "ExportDefaultDeclaration"
+                type: "ExportDefaultDeclaration",
+                line: 1,
+                column: 24,
+                endLine: 1,
+                endColumn: 25
             }]
         },
         {
@@ -941,7 +1176,11 @@ ruleTester.run("semi", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: [{
                 messageId: "extraSemi",
-                type: "ExportDefaultDeclaration"
+                type: "ExportDefaultDeclaration",
+                line: 1,
+                column: 25,
+                endLine: 1,
+                endColumn: 26
             }]
         },
         {
@@ -950,7 +1189,9 @@ ruleTester.run("semi", rule, {
             options: ["never"],
             errors: [{
                 messageId: "extraSemi",
+                line: 1,
                 column: 2,
+                endLine: 1,
                 endColumn: 3
             }]
         },
@@ -969,8 +1210,20 @@ ruleTester.run("semi", rule, {
             ].join("\n"),
             options: ["never"],
             errors: [
-                "Extra semicolon.",
-                "Unnecessary semicolon."
+                {
+                    messageId: "extraSemi",
+                    line: 2,
+                    column: 6,
+                    endLine: 2,
+                    endColumn: 7
+                },
+                {
+                    message: "Unnecessary semicolon.",
+                    line: 3,
+                    column: 1,
+                    endLine: 3,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -986,7 +1239,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "always" }],
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 2,
+                column: 34,
+                endLine: 3,
+                endColumn: 1
+            }]
         },
         {
             code: `
@@ -999,7 +1258,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "always" }],
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 2,
+                column: 38,
+                endLine: 3,
+                endColumn: 1
+            }]
         },
         {
             code: `
@@ -1016,7 +1281,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "always" }],
             parserOptions: { ecmaVersion: 2015 },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 3,
+                column: 27,
+                endLine: 4,
+                endColumn: 1
+            }]
         },
         {
             code: `
@@ -1032,7 +1303,13 @@ ruleTester.run("semi", rule, {
                 }
             `,
             options: ["never", { beforeStatementContinuationChars: "always" }],
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 3,
+                column: 26,
+                endLine: 4,
+                endColumn: 1
+            }]
         },
         {
             code: `
@@ -1048,7 +1325,13 @@ ruleTester.run("semi", rule, {
                 }
             `,
             options: ["never", { beforeStatementContinuationChars: "always" }],
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 3,
+                column: 29,
+                endLine: 4,
+                endColumn: 1
+            }]
         },
         {
             code: `
@@ -1060,7 +1343,13 @@ ruleTester.run("semi", rule, {
                 [1,2,3].forEach(doSomething)
             `,
             options: ["never", { beforeStatementContinuationChars: "always" }],
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 2,
+                column: 29,
+                endLine: 3,
+                endColumn: 1
+            }]
         },
         {
             code: `
@@ -1073,7 +1362,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "always" }],
             parserOptions: { ecmaVersion: 2015 },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 2,
+                column: 35,
+                endLine: 3,
+                endColumn: 1
+            }]
         },
         {
             code: `
@@ -1086,7 +1381,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 2,
+                column: 34,
+                endLine: 2,
+                endColumn: 35
+            }]
         },
         {
             code: `
@@ -1099,7 +1400,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 2,
+                column: 38,
+                endLine: 2,
+                endColumn: 39
+            }]
         },
         {
             code: `
@@ -1116,7 +1423,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 2015 },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 3,
+                column: 27,
+                endLine: 3,
+                endColumn: 28
+            }]
         },
         {
             code: `
@@ -1132,7 +1445,13 @@ ruleTester.run("semi", rule, {
                 }
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 3,
+                column: 26,
+                endLine: 3,
+                endColumn: 27
+            }]
         },
         {
             code: `
@@ -1148,7 +1467,13 @@ ruleTester.run("semi", rule, {
                 }
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 3,
+                column: 29,
+                endLine: 3,
+                endColumn: 30
+            }]
         },
         {
             code: `
@@ -1160,7 +1485,13 @@ ruleTester.run("semi", rule, {
                 [1,2,3].forEach(doSomething)
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 2,
+                column: 29,
+                endLine: 2,
+                endColumn: 30
+            }]
         },
         {
             code: `
@@ -1173,7 +1504,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 2015 },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 2,
+                column: 35,
+                endLine: 2,
+                endColumn: 36
+            }]
         },
         {
             code: `
@@ -1186,7 +1523,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 3,
+                column: 17,
+                endLine: 3,
+                endColumn: 18
+            }]
         },
         {
             code: `
@@ -1199,7 +1542,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 3,
+                column: 17,
+                endLine: 3,
+                endColumn: 18
+            }]
         },
         {
             code: `
@@ -1215,7 +1564,13 @@ ruleTester.run("semi", rule, {
                 }
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 4,
+                column: 21,
+                endLine: 4,
+                endColumn: 22
+            }]
         },
         {
             code: `
@@ -1231,7 +1586,13 @@ ruleTester.run("semi", rule, {
                 }
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 4,
+                column: 21,
+                endLine: 4,
+                endColumn: 22
+            }]
         },
         {
             code: `
@@ -1247,7 +1608,13 @@ ruleTester.run("semi", rule, {
                 }
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 4,
+                column: 21,
+                endLine: 4,
+                endColumn: 22
+            }]
         },
         {
             code: `
@@ -1259,7 +1626,13 @@ ruleTester.run("semi", rule, {
                 [1,2,3].forEach(doSomething)
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 3,
+                column: 17,
+                endLine: 3,
+                endColumn: 18
+            }]
         },
         {
             code: `
@@ -1272,7 +1645,13 @@ ruleTester.run("semi", rule, {
             `,
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 2015 },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 3,
+                column: 17,
+                endLine: 3,
+                endColumn: 18
+            }]
         },
 
         // Class fields
@@ -1280,56 +1659,104 @@ ruleTester.run("semi", rule, {
             code: "class C { foo }",
             output: "class C { foo; }",
             parserOptions: { ecmaVersion: 2022 },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 1,
+                column: 14,
+                endLine: 1,
+                endColumn: 15
+            }]
         },
         {
             code: "class C { foo }",
             output: "class C { foo; }",
             options: ["always"],
             parserOptions: { ecmaVersion: 2022 },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 1,
+                column: 14,
+                endLine: 1,
+                endColumn: 15
+            }]
         },
         {
             code: "class C { foo; }",
             output: "class C { foo }",
             options: ["never"],
             parserOptions: { ecmaVersion: 2022 },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 1,
+                column: 14,
+                endLine: 1,
+                endColumn: 15
+            }]
         },
         {
             code: "class C { foo\n[bar]; }",
             output: "class C { foo;\n[bar]; }",
             options: ["always"],
             parserOptions: { ecmaVersion: 2022 },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 1,
+                column: 14,
+                endLine: 2,
+                endColumn: 1
+            }]
         },
         {
             code: "class C { foo\n[bar] }",
             output: "class C { foo;\n[bar] }",
             options: ["never", { beforeStatementContinuationChars: "always" }],
             parserOptions: { ecmaVersion: 2022 },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 1,
+                column: 14,
+                endLine: 2,
+                endColumn: 1
+            }]
         },
         {
             code: "class C { foo\n;[bar] }",
             output: "class C { foo\n[bar] }",
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 2022 },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 2,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            }]
         },
         {
             code: "class C { foo = () => {}\n[bar] }",
             output: "class C { foo = () => {};\n[bar] }",
             options: ["never", { beforeStatementContinuationChars: "always" }],
             parserOptions: { ecmaVersion: 2022 },
-            errors: ["Missing semicolon."]
+            errors: [{
+                messageId: "missingSemi",
+                line: 1,
+                column: 25,
+                endLine: 2,
+                endColumn: 1
+            }]
         },
         {
             code: "class C { foo = () => {}\n;[bar] }",
             output: "class C { foo = () => {}\n[bar] }",
             options: ["never", { beforeStatementContinuationChars: "never" }],
             parserOptions: { ecmaVersion: 2022 },
-            errors: ["Extra semicolon."]
+            errors: [{
+                messageId: "extraSemi",
+                line: 2,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            }]
         }
     ]
 });