diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js index 37f0d650bf9..8d358d23ad3 100644 --- a/lib/rules/no-extra-parens.js +++ b/lib/rules/no-extra-parens.js @@ -472,20 +472,34 @@ module.exports = { const callee = node.callee; if (hasExcessParensWithPrecedence(callee, precedence(node))) { - const hasNewParensException = callee.type === "NewExpression" && !isNewExpressionWithParens(callee); - if ( hasDoubleExcessParens(callee) || - !isIIFE(node) && - !hasNewParensException && !( - - // Allow extra parens around a new expression if they are intervening parentheses. - node.type === "NewExpression" && - callee.type === "MemberExpression" && - doesMemberExpressionContainCallExpression(callee) - ) && - !(!node.optional && callee.type === "ChainExpression") + isIIFE(node) || + + // (new A)(); new (new A)(); + ( + callee.type === "NewExpression" && + !isNewExpressionWithParens(callee) && + !( + node.type === "NewExpression" && + !isNewExpressionWithParens(node) + ) + ) || + + // new (a().b)(); new (a.b().c); + ( + node.type === "NewExpression" && + callee.type === "MemberExpression" && + doesMemberExpressionContainCallExpression(callee) + ) || + + // (a?.b)(); (a?.())(); + ( + !node.optional && + callee.type === "ChainExpression" + ) + ) ) { report(node.callee); } diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js index 6e979b3e382..3fee9fefd8f 100644 --- a/tests/lib/rules/no-extra-parens.js +++ b/tests/lib/rules/no-extra-parens.js @@ -96,6 +96,8 @@ ruleTester.run("no-extra-parens", rule, { "(new A)()", "(new (Foo || Bar))()", "(new new foo())()", + "new (new A)()", + "new (new a.b)()", "new (new new foo())(bar)", "(new foo).bar", "(new foo)[bar]", @@ -847,6 +849,10 @@ ruleTester.run("no-extra-parens", rule, { invalid("new ((a().b().d))", "new (a().b().d)", "MemberExpression"), invalid("new ((a())).b.d", "new (a()).b.d", "CallExpression"), invalid("new (a.b).d;", "new a.b.d;", "MemberExpression"), + invalid("new (new A())();", "new new A()();", "NewExpression"), + invalid("new (new A());", "new new A();", "NewExpression"), + invalid("new (new A);", "new new A;", "NewExpression"), + invalid("new (new a.b);", "new new a.b;", "NewExpression"), invalid("(a().b).d;", "a().b.d;", "MemberExpression"), invalid("(a.b()).d;", "a.b().d;", "CallExpression"), invalid("(a.b).d;", "a.b.d;", "MemberExpression"),