Skip to content

Commit

Permalink
Fix: false positive new with member in no-extra-parens (fixes #12740)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeonjuan committed May 30, 2020
1 parent c29bd9f commit ce6d5c5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
35 changes: 32 additions & 3 deletions lib/rules/no-extra-parens.js
Expand Up @@ -687,6 +687,34 @@ module.exports = {
reportsBuffer.reports = reportsBuffer.reports.filter(r => r.node !== node);
}

/**
* Checks whether a node is a MemberExpression at NewExpression's callee.
* @param {ASTNode} node node to check.
* @returns {boolean} True if the node is a MemberExpression at NewExpression's callee. false otherwise.
*/
function isMemberInNewCallee(node) {
if (node.type === "MemberExpression") {
return node.parent.type === "NewExpression" && node.parent.callee === node
? true
: isMemberInNewCallee(node.parent);
}
return false;
}

/**
* Checks whether a MemberExpression node contains a CallExpression in member chaining.
* @param {ASTNode} node node to check
* @returns {boolean} True if the MemberExpression contains a CallExpression in member chaining. false otherwise.
*/
function hasCallExpInMemberExp(node) {
if (node.type === "MemberExpression") {
return node.object.type === "CallExpression"
? true
: hasCallExpInMemberExp(node.object);
}
return false;
}

return {
ArrayExpression(node) {
node.elements
Expand Down Expand Up @@ -927,7 +955,8 @@ module.exports = {
LogicalExpression: checkBinaryLogical,

MemberExpression(node) {
const nodeObjHasExcessParens = hasExcessParens(node.object);
const shouldAllowWrapOnce = isMemberInNewCallee(node) && hasCallExpInMemberExp(node);
const nodeObjHasExcessParens = shouldAllowWrapOnce ? hasDoubleExcessParens(node.object) : hasExcessParens(node.object);

if (
nodeObjHasExcessParens &&
Expand All @@ -946,8 +975,8 @@ module.exports = {
}

if (nodeObjHasExcessParens &&
node.object.type === "CallExpression" &&
node.parent.type !== "NewExpression") {
node.object.type === "CallExpression"
) {
report(node.object);
}

Expand Down
18 changes: 17 additions & 1 deletion tests/lib/rules/no-extra-parens.js
Expand Up @@ -589,7 +589,15 @@ ruleTester.run("no-extra-parens", rule, {
"for (let a = b; a; a); a; a;",
"for (a; a; a); a; a;",
"for (; a; a); a; a;",
"for (let a = (b && c) === d; ;);"
"for (let a = (b && c) === d; ;);",

"new (a()).b.c;",
"new (a().b).c;",
"new (a().b.c);",
"new (a().b().d);",
"new a().b().d;",
"new (a(b()).c)",
"new (a.b()).c"
],

invalid: [
Expand Down Expand Up @@ -741,6 +749,14 @@ ruleTester.run("no-extra-parens", rule, {
invalid("((new A))()", "(new A)()", "NewExpression"),
invalid("new (foo\n.baz\n.bar\n.foo.baz)", "new foo\n.baz\n.bar\n.foo.baz", "MemberExpression"),
invalid("new (foo.baz.bar.baz)", "new foo.baz.bar.baz", "MemberExpression"),
invalid("new ((a.b())).c", "new (a.b()).c", "CallExpression"),
invalid("new ((a().b)).c", "new (a().b).c", "MemberExpression"),
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("(a().b).d;", "a().b.d;", "MemberExpression"),
invalid("(a.b()).d;", "a.b().d;", "CallExpression"),
invalid("(a.b).d;", "a.b.d;", "MemberExpression"),

invalid("0, (_ => 0)", "0, _ => 0", "ArrowFunctionExpression", 1),
invalid("(_ => 0), 0", "_ => 0, 0", "ArrowFunctionExpression", 1),
Expand Down

0 comments on commit ce6d5c5

Please sign in to comment.