Skip to content

Commit

Permalink
Fix: Update semi for class-fields (refs #14591)
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Aug 18, 2021
1 parent 81c60f4 commit c67c7c0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
29 changes: 29 additions & 0 deletions lib/rules/semi.js
Expand Up @@ -78,6 +78,8 @@ module.exports = {
create(context) {

const OPT_OUT_PATTERN = /^[-[(/+`]/u; // One of [(/+-`
const unsafeClassFieldNames = new Set(["get", "set", "static"]);
const unsafeClassFieldFollowers = new Set(["*", "in", "instanceof"]);
const options = context.options[1];
const never = context.options[0] === "never";
const exceptOneLine = Boolean(options && options.omitLastInOneLineBlock);
Expand Down Expand Up @@ -166,6 +168,30 @@ module.exports = {
);
}

/**
* Checks if a given PropertyDefinition node followed by a semicolon
* can safely remove that semicolon. It is not to safe to remove if
* the class field name is "get", "set", or "static", or if
* followed by a generator method.
* @param {ASTNode} node The node to check.
* @returns {boolean} `true` if the node cannot have the semicolon
* removed.
*/
function maybeClassFieldAsiHazard(node) {

if (node.type !== "PropertyDefinition") {
return false;
}

if (unsafeClassFieldNames.has(node.key.name)) {
return true;
}

const followingToken = sourceCode.getTokenAfter(node);

return unsafeClassFieldFollowers.has(followingToken.value);
}

/**
* Check whether a given node is on the same line with the next token.
* @param {Node} node A statement node to check.
Expand Down Expand Up @@ -233,6 +259,9 @@ module.exports = {
* @returns {boolean} whether the semicolon is unnecessary.
*/
function canRemoveSemicolon(node) {
if (never && maybeClassFieldAsiHazard(node)) {
return false;
}
if (isRedundantSemi(sourceCode.getLastToken(node))) {
return true; // `;;` or `;}`
}
Expand Down
30 changes: 30 additions & 0 deletions tests/lib/rules/semi.js
Expand Up @@ -306,6 +306,36 @@ ruleTester.run("semi", rule, {
code: "class C { foo() {}; }", // no-extra-semi reports it
options: ["never"],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { a=b;\n*foo() {} }",
options: ["never"],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { get;\nfoo() {} }",
options: ["never"],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { set;\nfoo() {} }",
options: ["never"],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static;\nfoo() {} }",
options: ["never"],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { a=b;\nin }",
options: ["never"],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { a=b;\ninstanceof }",
options: ["never"],
parserOptions: { ecmaVersion: 2022 }
}
],
invalid: [
Expand Down

0 comments on commit c67c7c0

Please sign in to comment.