Skip to content

Commit bc17428

Browse files
authored
Add no-magic-array-flat-depth rule (#2335)
1 parent 204d31c commit bc17428

7 files changed

+187
-0
lines changed

configs/recommended.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module.exports = {
3131
'unicorn/no-invalid-remove-event-listener': 'error',
3232
'unicorn/no-keyword-prefix': 'off',
3333
'unicorn/no-lonely-if': 'error',
34+
'unicorn/no-magic-array-flat-depth': 'error',
3435
'no-negated-condition': 'off',
3536
'unicorn/no-negated-condition': 'error',
3637
'no-nested-ternary': 'off',
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Disallow a magic number as the `depth` argument in `Array#flat(…).`
2+
3+
💼 This rule is enabled in the ✅ `recommended` [config](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs-eslintconfigjs).
4+
5+
<!-- end auto-generated rule header -->
6+
<!-- Do not manually modify this header. Run: `npm run fix:eslint-docs` -->
7+
8+
When calling [`Array#flat(depth)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat), the depth argument should normally be `1` or `Infinity`, otherwise it should be a meaningful variable name or explained with a comment.
9+
10+
## Fail
11+
12+
```js
13+
const foo = array.flat(2);
14+
```
15+
16+
```js
17+
const foo = array.flat(99);
18+
```
19+
20+
## Pass
21+
22+
```js
23+
const foo = array.flat();
24+
```
25+
26+
```js
27+
const foo = array.flat(Number.POSITIVE_INFINITY);
28+
```
29+
30+
```js
31+
const foo = array.flat(Infinity);
32+
```
33+
34+
```js
35+
const foo = array.flat(depth);
36+
```
37+
38+
```js
39+
const foo = array.flat(/* The depth is always 2 */ 2);
40+
```

readme.md

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c
141141
| [no-invalid-remove-event-listener](docs/rules/no-invalid-remove-event-listener.md) | Prevent calling `EventTarget#removeEventListener()` with the result of an expression. || | |
142142
| [no-keyword-prefix](docs/rules/no-keyword-prefix.md) | Disallow identifiers starting with `new` or `class`. | | | |
143143
| [no-lonely-if](docs/rules/no-lonely-if.md) | Disallow `if` statements as the only statement in `if` blocks without `else`. || 🔧 | |
144+
| [no-magic-array-flat-depth](docs/rules/no-magic-array-flat-depth.md) | Disallow a magic number as the `depth` argument in `Array#flat(…).` || | |
144145
| [no-negated-condition](docs/rules/no-negated-condition.md) | Disallow negated conditions. || 🔧 | |
145146
| [no-nested-ternary](docs/rules/no-nested-ternary.md) | Disallow nested ternary expressions. || 🔧 | |
146147
| [no-new-array](docs/rules/no-new-array.md) | Disallow `new Array()`. || 🔧 | 💡 |

rules/no-magic-array-flat-depth.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
const {isOpeningParenToken} = require('@eslint-community/eslint-utils');
3+
const {isMethodCall, isNumberLiteral} = require('./ast/index.js');
4+
5+
const MESSAGE_ID = 'no-magic-array-flat-depth';
6+
const messages = {
7+
[MESSAGE_ID]: 'Magic number as depth is not allowed.',
8+
};
9+
10+
/** @param {import('eslint').Rule.RuleContext} context */
11+
const create = context => ({
12+
CallExpression(callExpression) {
13+
if (!isMethodCall(callExpression, {
14+
method: 'flat',
15+
argumentsLength: 1,
16+
optionalCall: false,
17+
})) {
18+
return;
19+
}
20+
21+
const [depth] = callExpression.arguments;
22+
23+
if (!isNumberLiteral(depth) || depth.value === 1) {
24+
return;
25+
}
26+
27+
const {sourceCode} = context;
28+
const openingParenthesisToken = sourceCode.getTokenAfter(callExpression.callee, isOpeningParenToken);
29+
const closingParenthesisToken = sourceCode.getLastToken(callExpression);
30+
if (sourceCode.commentsExistBetween(openingParenthesisToken, closingParenthesisToken)) {
31+
return;
32+
}
33+
34+
return {
35+
node: depth,
36+
messageId: MESSAGE_ID,
37+
};
38+
},
39+
});
40+
41+
/** @type {import('eslint').Rule.RuleModule} */
42+
module.exports = {
43+
create,
44+
meta: {
45+
type: 'suggestion',
46+
docs: {
47+
description: 'Disallow a magic number as the `depth` argument in `Array#flat(…).`',
48+
recommended: true,
49+
},
50+
messages,
51+
},
52+
};

test/no-magic-array-flat-depth.mjs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {getTester} from './utils/test.mjs';
2+
3+
const {test} = getTester(import.meta);
4+
5+
test.snapshot({
6+
valid: [
7+
'array.flat(1)',
8+
'array.flat(1.0)',
9+
'array.flat(0x01)',
10+
'array.flat(unknown)',
11+
'array.flat(Number.POSITIVE_INFINITY)',
12+
'array.flat(Infinity)',
13+
'array.flat(/* explanation */2)',
14+
'array.flat(2/* explanation */)',
15+
'array.flat()',
16+
'array.flat(2, extraArgument)',
17+
'new array.flat(2)',
18+
'array.flat?.(2)',
19+
'array.notFlat(2)',
20+
'flat(2)',
21+
],
22+
invalid: [
23+
'array.flat(2)',
24+
'array?.flat(2)',
25+
'array.flat(99,)',
26+
'array.flat(0b10,)',
27+
],
28+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Snapshot report for `test/no-magic-array-flat-depth.mjs`
2+
3+
The actual snapshot is saved in `no-magic-array-flat-depth.mjs.snap`.
4+
5+
Generated by [AVA](https://avajs.dev).
6+
7+
## invalid(1): array.flat(2)
8+
9+
> Input
10+
11+
`␊
12+
1 | array.flat(2)␊
13+
`
14+
15+
> Error 1/1
16+
17+
`␊
18+
> 1 | array.flat(2)␊
19+
| ^ Magic number as depth is not allowed.␊
20+
`
21+
22+
## invalid(2): array?.flat(2)
23+
24+
> Input
25+
26+
`␊
27+
1 | array?.flat(2)␊
28+
`
29+
30+
> Error 1/1
31+
32+
`␊
33+
> 1 | array?.flat(2)␊
34+
| ^ Magic number as depth is not allowed.␊
35+
`
36+
37+
## invalid(3): array.flat(99,)
38+
39+
> Input
40+
41+
`␊
42+
1 | array.flat(99,)␊
43+
`
44+
45+
> Error 1/1
46+
47+
`␊
48+
> 1 | array.flat(99,)␊
49+
| ^^ Magic number as depth is not allowed.␊
50+
`
51+
52+
## invalid(4): array.flat(0b10,)
53+
54+
> Input
55+
56+
`␊
57+
1 | array.flat(0b10,)␊
58+
`
59+
60+
> Error 1/1
61+
62+
`␊
63+
> 1 | array.flat(0b10,)␊
64+
| ^^^^ Magic number as depth is not allowed.␊
65+
`
336 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)