Skip to content

Commit

Permalink
Update: Option to allow extra parens for cond assign (fixes #3317)
Browse files Browse the repository at this point in the history
  • Loading branch information
alberto committed Jan 10, 2016
1 parent a4e8312 commit 4182e65
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
30 changes: 28 additions & 2 deletions docs/rules/no-extra-parens.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ A few cases of redundant parentheses are always allowed:

### Options

The default behavior of the rule is specified by `"all"` and it will report unnecessary parentheses around any expression. The following patterns are considered problems:
This rule takes 1 argument, a string which must be one of the following:

* `"all"` (default): it will report unnecessary parentheses around any expression.
* `"all-except-cond-assign"`: extra parens are allowed for assignment in conditional statements.
* `"functions"`: only function expressions will be checked for unnecessary parentheses.

#### "all"

The following patterns are considered problems:

```js
/*eslint no-extra-parens: 2*/
Expand Down Expand Up @@ -41,7 +49,25 @@ The following patterns are not considered problems:
(/^a$/).test(x);
```

If the option is set to `"functions"`, only function expressions will be checked for unnecessary parentheses. The following patterns are considered problems:
#### "all-except-cond-assign"

The following patterns are not considered problems:

```js
/*eslint no-extra-parens: [2, "all-except-cond-assign"]*/

while ((foo = bar())) {}

if ((foo = bar())) {}

do; while ((foo = bar()))

for (;(a = b););
```

#### "functions"

The following patterns are considered problems:

```js
/*eslint no-extra-parens: [2, "functions"]*/
Expand Down
15 changes: 10 additions & 5 deletions lib/rules/no-extra-parens.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
module.exports = function(context) {

var ALL_NODES = context.options[0] !== "functions";
var EXCEPT_COND_ASSIGN = context.options[0] === "all-except-cond-assign";
var sourceCode = context.getSourceCode();

/**
Expand Down Expand Up @@ -343,7 +344,8 @@ module.exports = function(context) {
}
},
"DoWhileStatement": function(node) {
if (hasDoubleExcessParens(node.test)) {
if (hasDoubleExcessParens(node.test) &&
(!EXCEPT_COND_ASSIGN || node.test.type !== "AssignmentExpression")) {
report(node.test);
}
},
Expand Down Expand Up @@ -388,7 +390,8 @@ module.exports = function(context) {
report(node.init);
}

if (node.test && hasExcessParens(node.test)) {
if (node.test && hasExcessParens(node.test) &&
(!EXCEPT_COND_ASSIGN || node.test.type !== "AssignmentExpression")) {
report(node.test);
}

Expand All @@ -397,7 +400,8 @@ module.exports = function(context) {
}
},
"IfStatement": function(node) {
if (hasDoubleExcessParens(node.test)) {
if (hasDoubleExcessParens(node.test) &&
(!EXCEPT_COND_ASSIGN || node.test.type !== "AssignmentExpression")) {
report(node.test);
}
},
Expand Down Expand Up @@ -483,7 +487,8 @@ module.exports = function(context) {
}
},
"WhileStatement": function(node) {
if (hasDoubleExcessParens(node.test)) {
if (hasDoubleExcessParens(node.test) &&
(!EXCEPT_COND_ASSIGN || node.test.type !== "AssignmentExpression")) {
report(node.test);
}
},
Expand Down Expand Up @@ -511,6 +516,6 @@ module.exports = function(context) {

module.exports.schema = [
{
"enum": ["all", "functions"]
"enum": ["all", "all-except-cond-assign", "functions"]
}
];
12 changes: 12 additions & 0 deletions tests/lib/rules/no-extra-parens.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ ruleTester.run("no-extra-parens", rule, {
{code: "var a = (b = c)", options: ["functions"]},
{code: "_ => (a = 0)", options: ["functions"], parserOptions: { ecmaVersion: 6 }},

// "all-except-cond-assign" enables extra parens around conditional assignments
{code: "while ((foo = bar())) {}", options: ["all-except-cond-assign"]},
{code: "if ((foo = bar())) {}", options: ["all-except-cond-assign"]},
{code: "do; while ((foo = bar()))", options: ["all-except-cond-assign"]},
{code: "for (;(a = b););", options: ["all-except-cond-assign"]},

// https://github.com/eslint/eslint/issues/3653
"(function(){}).foo(), 1, 2;",
"(function(){}).foo++;",
Expand Down Expand Up @@ -304,6 +310,12 @@ ruleTester.run("no-extra-parens", rule, {
invalid("(_ => 0), 0", "ArrowFunctionExpression", 1, {options: ["functions"], parserOptions: { ecmaVersion: 6 }}),
invalid("a = (_ => 0)", "ArrowFunctionExpression", 1, {options: ["functions"], parserOptions: { ecmaVersion: 6 }}),


invalid("while ((foo = bar())) {}", "AssignmentExpression"),
invalid("if ((foo = bar())) {}", "AssignmentExpression"),
invalid("do; while ((foo = bar()))", "AssignmentExpression"),
invalid("for (;(a = b););", "AssignmentExpression"),

// https://github.com/eslint/eslint/issues/3653
invalid("((function(){})).foo();", "FunctionExpression"),
invalid("((function(){}).foo());", "CallExpression"),
Expand Down

0 comments on commit 4182e65

Please sign in to comment.