diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js index c5cf7904774..c6809c355bc 100644 --- a/lib/rules/no-extra-parens.js +++ b/lib/rules/no-extra-parens.js @@ -205,7 +205,14 @@ module.exports = { const lastToken = sourceCode.getLastToken(newExpression); const penultimateToken = sourceCode.getTokenBefore(lastToken); - return newExpression.arguments.length > 0 || astUtils.isOpeningParenToken(penultimateToken) && astUtils.isClosingParenToken(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 + astUtils.isOpeningParenToken(penultimateToken) && + astUtils.isClosingParenToken(lastToken) && + newExpression.callee.range[1] < newExpression.range[1] + ); } /** @@ -338,7 +345,7 @@ module.exports = { function finishReport() { context.report({ node, - loc: leftParenToken.loc.start, + loc: leftParenToken.loc, messageId: "unexpected", fix(fixer) { const parenthesizedSource = sourceCode.text.slice(leftParenToken.range[1], rightParenToken.range[0]); @@ -887,6 +894,12 @@ module.exports = { report(node.object); } + if (nodeObjHasExcessParens && + node.object.type === "NewExpression" && + isNewExpressionWithParens(node.object)) { + report(node.object); + } + if (node.computed && hasExcessParens(node.property)) { report(node.property); } diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js index 788823e0434..e42b5eadc31 100644 --- a/tests/lib/rules/no-extra-parens.js +++ b/tests/lib/rules/no-extra-parens.js @@ -95,6 +95,17 @@ ruleTester.run("no-extra-parens", rule, { "new A()()", "(new A)()", "(new (Foo || Bar))()", + "(new new foo())()", + "new (new new foo())(bar)", + "(new foo).bar", + "(new foo)[bar]", + "(new foo).bar.baz", + "(new foo.bar).baz", + "(new foo).bar()", + "(new foo.bar).baz()", + "new (new foo).bar", + "new (new foo.bar).baz", + "(new new foo()).baz", "(2 + 3) ** 4", "2 ** (2 + 3)", "new (import(source))", @@ -647,6 +658,11 @@ ruleTester.run("no-extra-parens", rule, { invalid("(foo()).bar", "foo().bar", "CallExpression"), invalid("(foo.bar()).baz", "foo.bar().baz", "CallExpression"), invalid("(foo\n.bar())\n.baz", "foo\n.bar()\n.baz", "CallExpression"), + invalid("(new foo()).bar", "new foo().bar", "NewExpression"), + invalid("(new foo()).bar()", "new foo().bar()", "NewExpression"), + invalid("(new foo(bar)).baz", "new foo(bar).baz", "NewExpression"), + invalid("(new foo.bar()).baz", "new foo.bar().baz", "NewExpression"), + invalid("(new foo.bar()).baz()", "new foo.bar().baz()", "NewExpression"), invalid("new (A)", "new A", "Identifier"), invalid("(new A())()", "new A()()", "NewExpression"),