Skip to content
Permalink
Browse files
Update: add option "allowInParentheses" to no-sequences (fixes #14197) (
#14199)

* New: add option "allowInParentheses" to rule "no-sequences"

* added documentation

* [no-equence]: switch default of "allowInParentheses" to true

* restored removed sentence

* changes from code review

* code review
  • Loading branch information
danielrentz committed Mar 26, 2021
1 parent dbf2529 commit 687ccae517b8b815cf21e948f80d22e2bf118a99
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 13 deletions.
@@ -17,7 +17,7 @@ while (a = next(), a && a.length);
This rule forbids the use of the comma operator, with the following exceptions:

* In the initialization or update portions of a `for` statement.
* If the expression sequence is explicitly wrapped in parentheses.
* By default, if the expression sequence is explicitly wrapped in parentheses. This exception can be removed with the `allowInParentheses` option.

Examples of **incorrect** code for this rule:

@@ -63,10 +63,48 @@ while ((val = foo(), val < 42));
with ((doSomething(), val)) {}
```

## Options

This rule takes one option, an object, with the following properties:

* `"allowInParentheses"`: If set to `true` (default), this rule allows expression sequences that are explicitly wrapped in parentheses.

### allowInParentheses

Examples of **incorrect** code for this rule with the `{ "allowInParentheses": false }` option:

```js
/*eslint no-sequences: ["error", { "allowInParentheses": false }]*/
foo = (doSomething(), val);
(0, eval)("doSomething();");
do {} while ((doSomething(), !!test));
for (; (doSomething(), !!test); );
if ((doSomething(), !!test));
switch ((val = foo(), val)) {}
while ((val = foo(), val < 42));
with ((doSomething(), val)) {}
```

Examples of **correct** code for this rule with the `{ "allowInParentheses": false }` option:

```js
/*eslint no-sequences: ["error", { "allowInParentheses": false }]*/
for (i = 0, j = 10; i < j; i++, j--);
```

## When Not To Use It

Disable this rule if sequence expressions with the comma operator are acceptable.
Another case is where you might want to report all usages of the comma operator, even if they are wrapped in parentheses or in a for loop. You can achieve this using rule `no-restricted-syntax`:
Another case is where you might want to report all usages of the comma operator, even in a for loop. You can achieve this using rule `no-restricted-syntax`:

```js
{
@@ -11,6 +11,14 @@

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

const DEFAULT_OPTIONS = {
allowInParentheses: true
};

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -26,14 +34,23 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-sequences"
},

schema: [],
schema: [{
properties: {
allowInParentheses: {
type: "boolean",
default: true
}
},
additionalProperties: false
}],

messages: {
unexpectedCommaExpression: "Unexpected use of comma operator."
}
},

create(context) {
const options = Object.assign({}, DEFAULT_OPTIONS, context.options[0]);
const sourceCode = context.getSourceCode();

/**
@@ -99,13 +116,15 @@ module.exports = {
}

// Wrapping a sequence in extra parens indicates intent
if (requiresExtraParens(node)) {
if (isParenthesisedTwice(node)) {
return;
}
} else {
if (isParenthesised(node)) {
return;
if (options.allowInParentheses) {
if (requiresExtraParens(node)) {
if (isParenthesisedTwice(node)) {
return;
}
} else {
if (isParenthesised(node)) {
return;
}
}
}

@@ -46,10 +46,20 @@ ruleTester.run("no-sequences", rule, {
"do {} while ((doSomething(), !!test));",
"for ((doSomething(), somethingElse()); (doSomething(), !!test); );",
"if ((doSomething(), !!test));",
"switch ((doSomething(), !!test)) {}",
"switch ((doSomething(), val)) {}",
"while ((doSomething(), !!test));",
"with ((doSomething(), val)) {}",
{ code: "a => ((doSomething(), a))", env: { es6: true } }
{ code: "a => ((doSomething(), a))", env: { es6: true } },

// options object without "allowInParentheses" property
{ code: "var foo = (1, 2);", options: [{}] },

// explicitly set option "allowInParentheses" to default value
{ code: "var foo = (1, 2);", options: [{ allowInParentheses: true }] },

// valid code with "allowInParentheses" set to `false`
{ code: "for ((i = 0, j = 0); test; );", options: [{ allowInParentheses: false }] },
{ code: "for (; test; (i++, j++));", options: [{ allowInParentheses: false }] }
],

// Examples of code that should trigger the rule
@@ -75,6 +85,18 @@ ruleTester.run("no-sequences", rule, {
{ code: "a => (doSomething(), a)", env: { es6: true }, errors: errors(20) },
{ code: "(1), 2", errors: errors(4) },
{ code: "((1)) , (2)", errors: errors(7) },
{ code: "while((1) , 2);", errors: errors(11) }
{ code: "while((1) , 2);", errors: errors(11) },

// option "allowInParentheses": do not allow sequence in parentheses
{ code: "var foo = (1, 2);", options: [{ allowInParentheses: false }], errors: errors(13) },
{ code: "(0,eval)(\"foo()\");", options: [{ allowInParentheses: false }], errors: errors(3) },
{ code: "foo(a, (b, c), d);", options: [{ allowInParentheses: false }], errors: errors(10) },
{ code: "do {} while ((doSomething(), !!test));", options: [{ allowInParentheses: false }], errors: errors(28) },
{ code: "for (; (doSomething(), !!test); );", options: [{ allowInParentheses: false }], errors: errors(22) },
{ code: "if ((doSomething(), !!test));", options: [{ allowInParentheses: false }], errors: errors(19) },
{ code: "switch ((doSomething(), val)) {}", options: [{ allowInParentheses: false }], errors: errors(23) },
{ code: "while ((doSomething(), !!test));", options: [{ allowInParentheses: false }], errors: errors(22) },
{ code: "with ((doSomething(), val)) {}", options: [{ allowInParentheses: false }], errors: errors(21) },
{ code: "a => ((doSomething(), a))", options: [{ allowInParentheses: false }], env: { es6: true }, errors: errors(21) }
]
});

0 comments on commit 687ccae

Please sign in to comment.