Skip to content

Commit

Permalink
prefer-spread: Fix false negative on array constants (#1474)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker committed Aug 9, 2021
1 parent 7febb42 commit 4162145
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 23 deletions.
38 changes: 27 additions & 11 deletions rules/prefer-spread.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';
const {isParenthesized, getStaticValue, isCommaToken, hasSideEffect} = require('eslint-utils');
const {methodCallSelector} = require('./selectors/index.js');
const {methodCallSelector, not} = require('./selectors/index.js');
const needsSemicolon = require('./utils/needs-semicolon.js');
const {getParenthesizedRange, getParenthesizedText} = require('./utils/parentheses.js');
const shouldAddParenthesesToSpreadElementArgument = require('./utils/should-add-parentheses-to-spread-element-argument.js');
Expand Down Expand Up @@ -42,16 +42,12 @@ const arrayFromCallSelector = [

const arrayConcatCallSelector = [
methodCallSelector('concat'),
`:not(${
not(
[
...[
'Literal',
'TemplateLiteral',
].map(type => `[callee.object.type="${type}"]`),
// Most likely it's a static method of a class
'[callee.object.name=/^[A-Z]/]',
].join(', ')
})`,
'Literal',
'TemplateLiteral',
].map(type => `[callee.object.type="${type}"]`),
),
].join('');

const arraySliceCallSelector = [
Expand Down Expand Up @@ -301,6 +297,20 @@ function fixSlice(node, sourceCode) {
};
}

function isClassName(node) {
if (node.type === 'MemberExpression') {
node = node.property;
}

if (node.type !== 'Identifier') {
return false;
}

const {name} = node;

return /^[A-Z]./.test(name) && name.toUpperCase() !== name;
}

const create = context => {
const sourceCode = context.getSourceCode();

Expand All @@ -313,8 +323,14 @@ const create = context => {
};
},
[arrayConcatCallSelector](node) {
const {object} = node.callee;

if (isClassName(object)) {
return;
}

const scope = context.getScope();
const staticResult = getStaticValue(node.callee.object, scope);
const staticResult = getStaticValue(object, scope);

if (staticResult && !Array.isArray(staticResult.value)) {
return;
Expand Down
7 changes: 5 additions & 2 deletions test/prefer-spread.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ test.snapshot({
'const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);',
'Foo.concat(1)',
'FooBar.concat(1)',
'FOO.concat(1)',
'A.concat(1)',
'global.Buffer.concat([])',
],
invalid: [
'[1].concat(2)',
Expand Down Expand Up @@ -266,6 +265,10 @@ test.snapshot({
'foo.concat(bar, 2, 3, ...baz)',
'notClass.concat(1)',
'_A.concat(1)',
// Constants
'FOO.concat(1)',
'A.concat(1)',
'Foo.x.concat(1)',
// Semicolon
'if (test) foo.concat(1)',
'if (test) {} else foo.concat(1)',
Expand Down
68 changes: 58 additions & 10 deletions test/snapshots/prefer-spread.mjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,54 @@ Generated by [AVA](https://avajs.dev).
`

## Invalid #54
1 | FOO.concat(1)

> Output
`␊
1 | [...FOO, 1]␊
`

> Error 1/1
`␊
> 1 | FOO.concat(1)␊
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #55
1 | A.concat(1)

> Output
`␊
1 | [...A, 1]␊
`

> Error 1/1
`␊
> 1 | A.concat(1)␊
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #56
1 | Foo.x.concat(1)

> Output
`␊
1 | [...Foo.x, 1]␊
`

> Error 1/1
`␊
> 1 | Foo.x.concat(1)␊
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #57
1 | if (test) foo.concat(1)

> Output
Expand All @@ -1823,7 +1871,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #55
## Invalid #58
1 | if (test) {} else foo.concat(1)

> Output
Expand All @@ -1839,7 +1887,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #56
## Invalid #59
1 | if (test) {} else foo.concat(1)

> Output
Expand All @@ -1855,7 +1903,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #57
## Invalid #60
1 | for (;;) foo.concat(1)

> Output
Expand All @@ -1871,7 +1919,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #58
## Invalid #61
1 | for (a in b) foo.concat(1)

> Output
Expand All @@ -1887,7 +1935,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #59
## Invalid #62
1 | for (a in b) foo.concat(1)

> Output
Expand All @@ -1903,7 +1951,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #60
## Invalid #63
1 | for (const a of b) foo.concat(1)

> Output
Expand All @@ -1919,7 +1967,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #61
## Invalid #64
1 | while (test) foo.concat(1)

> Output
Expand All @@ -1935,7 +1983,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #62
## Invalid #65
1 | do foo.concat(1); while (test)

> Output
Expand All @@ -1951,7 +1999,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #63
## Invalid #66
1 | with (foo) foo.concat(1)

> Output
Expand All @@ -1967,7 +2015,7 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^ Prefer the spread operator over \`Array#concat(…)\`.␊
`

## Invalid #64
## Invalid #67
1 | const baz = [2];
2 | call(foo, ...[bar].concat(baz));

Expand Down
Binary file modified test/snapshots/prefer-spread.mjs.snap
Binary file not shown.

0 comments on commit 4162145

Please sign in to comment.