Skip to content

Commit 352e90c

Browse files
authored
Simplify prefer-set-has (#679)
1 parent 29f3c9c commit 352e90c

File tree

2 files changed

+83
-36
lines changed

2 files changed

+83
-36
lines changed

rules/prefer-set-has.js

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
2+
const {findVariable} = require('eslint-utils');
23
const getDocumentationUrl = require('./utils/get-documentation-url');
3-
const getReferences = require('./utils/get-references');
4+
const getVariableIdentifiers = require('./utils/get-variable-identifiers');
45
const methodSelector = require('./utils/method-selector');
56

67
// `[]`
@@ -107,45 +108,30 @@ const isIncludesCall = node => {
107108
};
108109

109110
const create = context => {
110-
const scope = context.getScope();
111-
const declarations = new Set();
112-
113111
return {
114112
[selector]: node => {
115-
declarations.add(node);
116-
},
117-
'Program:exit'() {
118-
if (declarations.size === 0) {
113+
const variable = findVariable(context.getScope(), node);
114+
const identifiers = getVariableIdentifiers(variable).filter(identifier => identifier !== node);
115+
116+
if (
117+
identifiers.length === 0 ||
118+
identifiers.some(node => !isIncludesCall(node))
119+
) {
119120
return;
120121
}
121122

122-
const references = getReferences(scope);
123-
for (const declaration of declarations) {
124-
const variable = references
125-
.find(({identifier}) => identifier === declaration)
126-
.resolved;
127-
const nodes = variable.references
128-
.map(({identifier}) => identifier)
129-
.filter(node => node !== declaration);
130-
131-
if (
132-
nodes.length > 0 &&
133-
nodes.every(node => isIncludesCall(node))
134-
) {
135-
context.report({
136-
node: declaration,
137-
messageId: MESSAGE_ID,
138-
data: {
139-
name: declaration.name
140-
},
141-
fix: fixer => [
142-
fixer.insertTextBefore(declaration.parent.init, 'new Set('),
143-
fixer.insertTextAfter(declaration.parent.init, ')'),
144-
...nodes.map(node => fixer.replaceText(node.parent.property, 'has'))
145-
]
146-
});
147-
}
148-
}
123+
context.report({
124+
node,
125+
messageId: MESSAGE_ID,
126+
data: {
127+
name: node.name
128+
},
129+
fix: fixer => [
130+
fixer.insertTextBefore(node.parent.init, 'new Set('),
131+
fixer.insertTextAfter(node.parent.init, ')'),
132+
...identifiers.map(identifier => fixer.replaceText(identifier.parent.property, 'has'))
133+
]
134+
});
149135
}
150136
};
151137
};

test/prefer-set-has.js

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,12 @@ ruleTester.run(ruleId, rule, {
270270
outdent`
271271
const foo = bar.notListed();
272272
const exists = foo.includes(1);
273+
`,
274+
275+
// `lodash`
276+
outdent`
277+
const foo = _.map([1, 2, 3], value => value);
278+
const exists = _.includes(foo, 1);
273279
`
274280
],
275281
invalid: [
@@ -338,6 +344,44 @@ ruleTester.run(ruleId, rule, {
338344
...createError('bar')
339345
]
340346
},
347+
// Different scope
348+
{
349+
code: outdent`
350+
const foo = [1, 2, 3];
351+
const exists = foo.includes(1);
352+
const bar = [1, 2, 3];
353+
354+
function outer(find) {
355+
const foo = [1, 2, 3];
356+
const exists = foo.includes(1);
357+
358+
function inner(find) {
359+
const bar = [1, 2, 3];
360+
const exists = bar.includes(1);
361+
}
362+
}
363+
`,
364+
output: outdent`
365+
const foo = new Set([1, 2, 3]);
366+
const exists = foo.has(1);
367+
const bar = [1, 2, 3];
368+
369+
function outer(find) {
370+
const foo = new Set([1, 2, 3]);
371+
const exists = foo.has(1);
372+
373+
function inner(find) {
374+
const bar = new Set([1, 2, 3]);
375+
const exists = bar.has(1);
376+
}
377+
}
378+
`,
379+
errors: [
380+
...createError('foo'),
381+
...createError('foo'),
382+
...createError('bar')
383+
]
384+
},
341385

342386
// `Array()`
343387
{
@@ -402,6 +446,23 @@ ruleTester.run(ruleId, rule, {
402446
const exists = foo.has(1);
403447
`,
404448
errors: createError('foo')
405-
}))
449+
})),
450+
451+
// `lodash`
452+
// `bar` is not `array`, but code not broken
453+
// See https://github.com/sindresorhus/eslint-plugin-unicorn/pull/641
454+
{
455+
code: outdent`
456+
const foo = _([1,2,3]);
457+
const bar = foo.map(value => value);
458+
const exists = bar.includes(1);
459+
`,
460+
output: outdent`
461+
const foo = _([1,2,3]);
462+
const bar = new Set(foo.map(value => value));
463+
const exists = bar.has(1);
464+
`,
465+
errors: createError('bar')
466+
}
406467
]
407468
});

0 commit comments

Comments
 (0)