diff --git a/docs/rules/semi.md b/docs/rules/semi.md index 049ae41cf16..158cd7f53e2 100644 --- a/docs/rules/semi.md +++ b/docs/rules/semi.md @@ -76,6 +76,8 @@ Object option (when `"never"`): * `"beforeStatementContinuationChars": "always"` requires semicolons at the end of statements if the next line starts with `[`, `(`, `/`, `+`, or `-`. * `"beforeStatementContinuationChars": "never"` disallows semicolons as the end of statements if it doesn't make ASI hazard even if the next line starts with `[`, `(`, `/`, `+`, or `-`. +**Note:** `beforeStatementContinuationChars` does not apply to class fields because class fields are not statements. + ### always Examples of **incorrect** code for this rule with the default `"always"` option: @@ -88,6 +90,10 @@ var name = "ESLint" object.method = function() { // ... } + +class Foo { + bar = 1 +} ``` Examples of **correct** code for this rule with the default `"always"` option: @@ -100,6 +106,10 @@ var name = "ESLint"; object.method = function() { // ... }; + +class Foo { + bar = 1; +} ``` ### never @@ -114,6 +124,10 @@ var name = "ESLint"; object.method = function() { // ... }; + +class Foo { + bar = 1; +} ``` Examples of **correct** code for this rule with the `"never"` option: @@ -142,6 +156,10 @@ import b from "b" ;(function() { // ... })() + +class Foo { + bar = 1 +} ``` #### omitLastInOneLineBlock diff --git a/lib/rules/semi.js b/lib/rules/semi.js index 3d7aa2dd5e5..ac488c86c30 100644 --- a/lib/rules/semi.js +++ b/lib/rules/semi.js @@ -292,7 +292,13 @@ module.exports = { if (isOnSameLineWithNextToken(node)) { return false; // One liner. } - if (beforeStatementContinuationChars === "never" && !maybeAsiHazardAfter(node)) { + + // continuation characters should not apply to class fields + if ( + node.type !== "PropertyDefinition" && + beforeStatementContinuationChars === "never" && + !maybeAsiHazardAfter(node) + ) { return true; // ASI works. This statement doesn't connect to the next. } if (!maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) { @@ -332,7 +338,11 @@ module.exports = { if (never) { if (isSemi && canRemoveSemicolon(node)) { report(node, true); - } else if (!isSemi && beforeStatementContinuationChars === "always" && maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) { + } else if ( + !isSemi && beforeStatementContinuationChars === "always" && + node.type !== "PropertyDefinition" && + maybeAsiHazardBefore(sourceCode.getTokenAfter(node)) + ) { report(node); } } else { diff --git a/tests/lib/rules/semi.js b/tests/lib/rules/semi.js index 2a049ab99c6..3cc82000961 100644 --- a/tests/lib/rules/semi.js +++ b/tests/lib/rules/semi.js @@ -336,6 +336,58 @@ ruleTester.run("semi", rule, { code: "class C { a=b;\ninstanceof }", options: ["never"], parserOptions: { ecmaVersion: 2022 } + }, + { + code: ` + class C { + x + [foo] + + x; + [foo] + + x = "a"; + [foo] + } + `, + options: ["never", { beforeStatementContinuationChars: "never" }], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: ` + class C { + x + [foo] + + x; + [foo] + + x = 1; + [foo] + } + `, + options: ["never", { beforeStatementContinuationChars: "always" }], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: "class C { foo\n[bar] }", + options: ["never", { beforeStatementContinuationChars: "always" }], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: "class C { foo = () => {}\n[bar] }", + options: ["never", { beforeStatementContinuationChars: "always" }], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: "class C { foo\n;[bar] }", + options: ["never", { beforeStatementContinuationChars: "never" }], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: "class C { foo = () => {}\n;[bar] }", + options: ["never", { beforeStatementContinuationChars: "never" }], + parserOptions: { ecmaVersion: 2022 } } ], invalid: [ @@ -1736,58 +1788,6 @@ ruleTester.run("semi", rule, { endColumn: 1 }] }, - { - code: "class C { foo\n[bar] }", - output: "class C { foo;\n[bar] }", - options: ["never", { beforeStatementContinuationChars: "always" }], - parserOptions: { ecmaVersion: 2022 }, - 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: [{ - 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: [{ - 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: [{ - messageId: "extraSemi", - line: 2, - column: 1, - endLine: 2, - endColumn: 2 - }] - }, // class fields {