Repository: eslint/eslint
File: lib/rules/no-extra-parens.js (JavaScript)

Code before:
                }

                checkBinaryLogical(node);
            },

            CallExpression: checkCallNew,

            ConditionalExpression(node) {
                if (isReturnAssignException(node)) {
                    return;
                }

                const availableTypes = new Set(["BinaryExpression", "LogicalExpression", "SequenceExpression"]);

                if (isCondTernaryException(node)) {
                    if (!availableTypes.has(node.test.type) && isParenthesised(node.test)) {
                        report(node.test);
                    }
                    if (!availableTypes.has(node.consequent.type) && isParenthesised(node.consequent)) {
                        report(node.consequent);
                    }
                    if (!availableTypes.has(node.alternate.type) && isParenthesised(node.alternate)) {
                        report(node.alternate);
                    }
                    return;
                }

                if (
                    !isCondAssignException(node) &&
                    hasExcessParensWithPrecedence(node.test, precedence({ type: "LogicalExpression", operator: "||" }))
                ) {
                    report(node.test);
                }

                if (hasExcessParensWithPrecedence(node.consequent, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
                    report(node.consequent);
                }

                if (hasExcessParensWithPrecedence(node.alternate, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
                    report(node.alternate);
                }
            },

            DoWhileStatement(node) {
                if (hasExcessParens(node.test) && !isCondAssignException(node)) {
                    report(node.test);
                }
            },

            ExportDefaultDeclaration: node => checkExpressionOrExportStatement(node.declaration),
            ExpressionStatement: node => checkExpressionOrExportStatement(node.expression),

Review comment (suggestion):
This is still a false positive:

```js
/* eslint no-extra-parens: ["error", "all", { "ternaryOperandBinaryExpressions": false }] */

(a = b) ? c : d; // false positive, removing parentheses will change semantics to a = (b ? c : d)

```

Note that this is just one example where the added `if (isCondTernaryException(node))` branch doesn't work correctly. We should update the code to fall into existing logic when the new option doesn't apply, as suggested in https://github.com/eslint/eslint/pull/17270#discussion_r1230878847.

Code after:
                }

                const availableTypes = new Set(["BinaryExpression", "LogicalExpression"]);

                if (
                    !(EXCEPT_COND_TERNARY && availableTypes.has(node.test.type)) &&
                    !isCondAssignException(node) &&
                    hasExcessParensWithPrecedence(node.test, precedence({ type: "LogicalExpression", operator: "||" }))
                ) {
                    report(node.test);
                }

                if (
                    !(EXCEPT_COND_TERNARY && availableTypes.has(node.consequent.type)) &&
                    hasExcessParensWithPrecedence(node.consequent, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
                    report(node.consequent);
                }

                if (
                    !(EXCEPT_COND_TERNARY && availableTypes.has(node.alternate.type)) &&
                    hasExcessParensWithPrecedence(node.alternate, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
                    report(node.alternate);
                }
            },

            DoWhileStatement(node) {
                if (hasExcessParens(node.test) && !isCondAssignException(node)) {
                    report(node.test);
                }
            },

            ExportDefaultDeclaration: node => checkExpressionOrExportStatement(node.declaration),
            ExpressionStatement: node => checkExpressionOrExportStatement(node.expression),

            ForInStatement(node) {
                if (node.left.type !== "VariableDeclaration") {
                    const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken);

                    if (
                        firstLeftToken.value === "let" &&
                        astUtils.isOpeningBracketToken(
                            sourceCode.getTokenAfter(firstLeftToken, astUtils.isNotClosingParenToken)
                        )
                    ) {

                        // ForInStatement#left expression cannot start with `let[`.
                        tokensToIgnore.add(firstLeftToken);
                    }
                }

                if (hasExcessParens(node.left)) {