From ce5ac38156ffbbfcc322659338a95b2649808422 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Thu, 21 Mar 2024 16:35:39 -0600 Subject: [PATCH] fix: [no-extra-boolean-cast] inspect comma expressions and ?? expressions. Fixes #18186 --- lib/rules/no-extra-boolean-cast.js | 15 ++++++++++++ tests/lib/rules/no-extra-boolean-cast.js | 30 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/lib/rules/no-extra-boolean-cast.js b/lib/rules/no-extra-boolean-cast.js index f342533bfc9..dcf13d2bcad 100644 --- a/lib/rules/no-extra-boolean-cast.js +++ b/lib/rules/no-extra-boolean-cast.js @@ -115,6 +115,19 @@ module.exports = { return isInFlaggedContext(node.parent); } + /* + * Check last expression only in a sequence, i.e. if ((1, 2, Boolean(3))) {}, since + * the others don't affect the result of the expression. + */ + if (node.parent.type === "SequenceExpression" && node.parent.expressions.at(-1) === node) { + return isInFlaggedContext(node.parent); + } + + // Check the right hand side of a `??` operator. + if (node.parent.type === "LogicalExpression" && node.parent.operator === "??" && node.parent.right === node) { + return isInFlaggedContext(node.parent); + } + return isInBooleanContext(node) || (isLogicalContext(node.parent) && @@ -157,6 +170,7 @@ module.exports = { if (previousNode.parent.type === "ChainExpression") { return needsParens(previousNode.parent, node); } + if (isParenthesized(previousNode)) { // parentheses around the previous node will stay, so there is no need for an additional pair @@ -174,6 +188,7 @@ module.exports = { case "DoWhileStatement": case "WhileStatement": case "ForStatement": + case "SequenceExpression": return false; case "ConditionalExpression": return precedence(node) <= precedence(parent); diff --git a/tests/lib/rules/no-extra-boolean-cast.js b/tests/lib/rules/no-extra-boolean-cast.js index 27f30962543..b41fff616e0 100644 --- a/tests/lib/rules/no-extra-boolean-cast.js +++ b/tests/lib/rules/no-extra-boolean-cast.js @@ -34,6 +34,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { "for(Boolean(foo);;) {}", "for(;; Boolean(foo)) {}", "if (new Boolean(foo)) {}", + "if ((Boolean(1), 2)) {}", { code: "var foo = bar || !!baz", options: [{ enforceForLogicalOperands: true }] @@ -2435,6 +2436,35 @@ ruleTester.run("no-extra-boolean-cast", rule, { ecmaVersion: 2020 }, errors: [{ messageId: "unexpectedCall" }] + }, + { + code: "if ((1, 2, Boolean(3))) {}", + output: "if ((1, 2, 3)) {}", + errors: [{ messageId: "unexpectedCall" }] + }, + { + code: "if (a ?? Boolean(b)) {}", + output: "if (a ?? b) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [{ messageId: "unexpectedCall" }] + }, + { + code: "if (a ?? Boolean(b)) {}", + output: "if (a ?? b) {}", + options: [{ enforceForLogicalOperands: false }], + errors: [{ messageId: "unexpectedCall" }] + }, + { + code: "if ((a, b, c ?? (d, e, f ?? Boolean(g)))) {}", + output: "if ((a, b, c ?? (d, e, f ?? g))) {}", + options: [{ enforceForLogicalOperands: false }], + errors: [{ messageId: "unexpectedCall" }] + }, + { + code: "if ((a, b, c ?? (d, e, f ?? Boolean(g)))) {}", + output: "if ((a, b, c ?? (d, e, f ?? g))) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [{ messageId: "unexpectedCall" }] } ] });