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

Code before:
                    isParenthesisedTwice(node)
                ) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Determines if a node test expression is allowed to have a parenthesised assignment
         * @param {ASTNode} node The node to be checked.
         * @returns {boolean} True if the assignment can be parenthesised.
         * @private
         */
        function isCondAssignException(node) {
            return EXCEPT_COND_ASSIGN && node.test.type === "AssignmentExpression";
        }

        /**
         * Determines if a node test expression is allowed to have a parenthesised condition in ternary expression
         * @param {ASTNode} node The node to be checked.
         * @returns {boolean} True if the conditional in ternary expression can be parenthesised.
         * @private
         */
        function isCondTernaryException(node) {
            const filterType = new Set(["Identifier", "CallExpression"]);

            return EXCEPT_COND_TERNARY &&
                node.test.type && node.consequent && node.alternate && (
                !filterType.has(node.test.type) ||
                !filterType.has(node.consequent.type) ||
                !filterType.has(node.alternate.type));
        }

        /**
         * Determines if a node is in a return statement
         * @param {ASTNode} node The node to be checked.
         * @returns {boolean} True if the node is in a return statement.
         * @private
         */
        function isInReturnStatement(node) {
            for (let currentNode = node; currentNode; currentNode = currentNode.parent) {
                if (
                    currentNode.type === "ReturnStatement" ||
                    (currentNode.type === "ArrowFunctionExpression" && currentNode.body.type !== "BlockStatement")
                ) {
                    return true;
                }
            }

            return false;

Review comment (suggestion):
Since the `no-mixed-operators` rule requires parentheses only around binary expressions, to align these two rules the new option should only apply when the parenthesized node is a BinaryExpression node. For example, these parentheses should still not be allowed:

```js
/* eslint no-extra-parens: ["error", "all", { conditionalTernary: false }] */

(a.b) ? c : d // false negative

```

It would be better to check if the node is BinaryExpression than to check if it's not in a list of other expressions.

Code after:
                    isParenthesisedTwice(node)
                ) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Determines if a node test expression is allowed to have a parenthesised assignment
         * @param {ASTNode} node The node to be checked.
         * @returns {boolean} True if the assignment can be parenthesised.
         * @private
         */
        function isCondAssignException(node) {
            return EXCEPT_COND_ASSIGN && node.test.type === "AssignmentExpression";
        }

        /**
         * Determines if a node is in a return statement
         * @param {ASTNode} node The node to be checked.
         * @returns {boolean} True if the node is in a return statement.
         * @private
         */
        function isInReturnStatement(node) {
            for (let currentNode = node; currentNode; currentNode = currentNode.parent) {
                if (
                    currentNode.type === "ReturnStatement" ||
                    (currentNode.type === "ArrowFunctionExpression" && currentNode.body.type !== "BlockStatement")
                ) {
                    return true;
                }
            }

            return false;
        }

        /**
         * Determines if a constructor function is newed-up with parens
         * @param {ASTNode} newExpression The NewExpression node to be checked.
         * @returns {boolean} True if the constructor is called with parens.
         * @private
         */
        function isNewExpressionWithParens(newExpression) {
            const lastToken = sourceCode.getLastToken(newExpression);
            const penultimateToken = sourceCode.getTokenBefore(lastToken);

            return newExpression.arguments.length > 0 ||
                (

                    // The expression should end with its own parens, e.g., new new foo() is not a new expression with parens