Skip to content

Commit

Permalink
prefer-set-has: Ignore arrays only checking existence once (#706)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker committed May 3, 2020
1 parent aab97b4 commit 54c6f54
Show file tree
Hide file tree
Showing 3 changed files with 575 additions and 105 deletions.
23 changes: 10 additions & 13 deletions docs/rules/prefer-set-has.md
Expand Up @@ -8,28 +8,25 @@ This rule is fixable.

```js
const array = [1, 2, 3];

function hasValue(value) {
return array.includes(value);
}
const hasValue = value => array.includes(value);
```

## Pass

```js
const set = new Set([1, 2, 3]);

function hasValue(value) {
return set.has(value);
}
const hasValue = value => set.has(value);
```

```js
// This array is not only checking existence.
const array = [1, 2];

function hasValue(value) {
return array.includes(value);
}

const hasValue = value => array.includes(value);
array.push(3);
```

```js
// This array is only checked once.
const array = [1, 2, 3];
const hasOne = array.includes(1);
```
39 changes: 38 additions & 1 deletion rules/prefer-set-has.js
Expand Up @@ -107,6 +107,36 @@ const isIncludesCall = node => {
);
};

const multipleCallNodeTypes = new Set([
'ForOfStatement',
'ForStatement',
'ForInStatement',
'WhileStatement',
'DoWhileStatement',
'FunctionDeclaration',
'FunctionExpression',
'ArrowFunctionExpression',
'ObjectMethod',
'ClassMethod'
]);

const isMultipleCall = (identifier, node) => {
const root = node.parent.parent.parent;
let {parent} = identifier.parent; // `.include()` callExpression
while (
parent &&
parent !== root
) {
if (multipleCallNodeTypes.has(parent.type)) {
return true;
}

parent = parent.parent;
}

return false;
};

const create = context => {
return {
[selector]: node => {
Expand All @@ -115,7 +145,14 @@ const create = context => {

if (
identifiers.length === 0 ||
identifiers.some(node => !isIncludesCall(node))
identifiers.some(identifier => !isIncludesCall(identifier))
) {
return;
}

if (
identifiers.length === 1 &&
identifiers.every(identifier => !isMultipleCall(identifier, node))
) {
return;
}
Expand Down

0 comments on commit 54c6f54

Please sign in to comment.