mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(lint-unicorn): add rule prefer set has (#7075)
implementing the rule [prefer set has](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-set-has.md) from unicorn. I put the fix as dangerous fix because they was no test for the fix on the unicorn part. I did add some test for this but i'm not sure that i'm covering everything. --------- Co-authored-by: Boshen <boshenc@gmail.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com>
This commit is contained in:
parent
a68a2172d2
commit
79ab8cca0e
3 changed files with 1183 additions and 0 deletions
|
|
@ -361,6 +361,7 @@ mod unicorn {
|
||||||
pub mod prefer_query_selector;
|
pub mod prefer_query_selector;
|
||||||
pub mod prefer_reflect_apply;
|
pub mod prefer_reflect_apply;
|
||||||
pub mod prefer_regexp_test;
|
pub mod prefer_regexp_test;
|
||||||
|
pub mod prefer_set_has;
|
||||||
pub mod prefer_set_size;
|
pub mod prefer_set_size;
|
||||||
pub mod prefer_spread;
|
pub mod prefer_spread;
|
||||||
pub mod prefer_string_raw;
|
pub mod prefer_string_raw;
|
||||||
|
|
@ -954,6 +955,7 @@ oxc_macros::declare_all_lint_rules! {
|
||||||
unicorn::prefer_query_selector,
|
unicorn::prefer_query_selector,
|
||||||
unicorn::prefer_reflect_apply,
|
unicorn::prefer_reflect_apply,
|
||||||
unicorn::prefer_regexp_test,
|
unicorn::prefer_regexp_test,
|
||||||
|
unicorn::prefer_set_has,
|
||||||
unicorn::prefer_set_size,
|
unicorn::prefer_set_size,
|
||||||
unicorn::prefer_spread,
|
unicorn::prefer_spread,
|
||||||
unicorn::prefer_string_raw,
|
unicorn::prefer_string_raw,
|
||||||
|
|
|
||||||
909
crates/oxc_linter/src/rules/unicorn/prefer_set_has.rs
Normal file
909
crates/oxc_linter/src/rules/unicorn/prefer_set_has.rs
Normal file
|
|
@ -0,0 +1,909 @@
|
||||||
|
use itertools::Itertools;
|
||||||
|
use oxc_ast::{
|
||||||
|
ast::{Expression, MemberExpression, VariableDeclarationKind},
|
||||||
|
AstKind,
|
||||||
|
};
|
||||||
|
use oxc_diagnostics::OxcDiagnostic;
|
||||||
|
use oxc_macros::declare_oxc_lint;
|
||||||
|
use oxc_semantic::ScopeId;
|
||||||
|
use oxc_span::Span;
|
||||||
|
use phf::phf_set;
|
||||||
|
|
||||||
|
use crate::{ast_util::is_method_call, context::LintContext, rule::Rule, AstNode};
|
||||||
|
|
||||||
|
const ARRAY_METHODS_RETURNS_ARRAY: phf::Set<&'static str> = phf_set! {
|
||||||
|
"concat",
|
||||||
|
"copyWithin",
|
||||||
|
"fill",
|
||||||
|
"filter",
|
||||||
|
"flat",
|
||||||
|
"flatMap",
|
||||||
|
"map",
|
||||||
|
"reverse",
|
||||||
|
"slice",
|
||||||
|
"sort",
|
||||||
|
"splice",
|
||||||
|
"toReversed",
|
||||||
|
"toSorted",
|
||||||
|
"toSpliced",
|
||||||
|
"with",
|
||||||
|
};
|
||||||
|
|
||||||
|
fn prefer_set_has_diagnostic(span: Span) -> OxcDiagnostic {
|
||||||
|
OxcDiagnostic::warn("should be a `Set`, and use `.has()` to check existence or non-existence.")
|
||||||
|
.with_help("Switch to `Set`")
|
||||||
|
.with_label(span)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct PreferSetHas;
|
||||||
|
|
||||||
|
declare_oxc_lint!(
|
||||||
|
/// ### What it does
|
||||||
|
///
|
||||||
|
/// Prefer `Set#has()` over `Array#includes()` when checking for existence or non-existence.
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
///
|
||||||
|
/// Set#has() is faster than Array#includes().
|
||||||
|
///
|
||||||
|
/// ### Examples
|
||||||
|
///
|
||||||
|
/// Examples of **incorrect** code for this rule:
|
||||||
|
/// ```js
|
||||||
|
/// const array = [1, 2, 3];
|
||||||
|
/// const hasValue = value => array.includes(value);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Examples of **correct** code for this rule:
|
||||||
|
/// ```js
|
||||||
|
/// const set = new Set([1, 2, 3]);
|
||||||
|
/// const hasValue = value => set.has(value);
|
||||||
|
/// ```
|
||||||
|
/// ```js
|
||||||
|
/// const array = [1, 2, 3];
|
||||||
|
/// const hasOne = array.includes(1);
|
||||||
|
/// ```
|
||||||
|
PreferSetHas,
|
||||||
|
perf,
|
||||||
|
dangerous_fix
|
||||||
|
);
|
||||||
|
|
||||||
|
fn is_array_of_or_from(callee: &MemberExpression) -> bool {
|
||||||
|
callee.is_specific_member_access("Array", "of")
|
||||||
|
|| callee.is_specific_member_access("Array", "from")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_kind_of_array_expr(expr: &Expression) -> bool {
|
||||||
|
match expr {
|
||||||
|
Expression::NewExpression(new_expr) => {
|
||||||
|
new_expr.callee.get_identifier_reference().map_or(false, |ident| ident.name == "Array")
|
||||||
|
}
|
||||||
|
Expression::CallExpression(call_expr) => {
|
||||||
|
let Some(callee) = call_expr.callee.get_member_expr() else {
|
||||||
|
return call_expr.callee_name().map_or(false, |name| name == "Array");
|
||||||
|
};
|
||||||
|
|
||||||
|
if callee.is_computed() || callee.optional() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(name) = callee.static_property_name() else { return false };
|
||||||
|
|
||||||
|
is_array_of_or_from(callee) || ARRAY_METHODS_RETURNS_ARRAY.contains(name)
|
||||||
|
}
|
||||||
|
Expression::ArrayExpression(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_multiple_calls(node: &AstNode, ctx: &LintContext, root_scope_id: ScopeId) -> bool {
|
||||||
|
let mut was_in_root_scope = node.scope_id() == root_scope_id;
|
||||||
|
let mut is_multiple = false;
|
||||||
|
for parent in ctx.nodes().ancestors(node.id()) {
|
||||||
|
let parent_scope = parent.scope_id();
|
||||||
|
if was_in_root_scope && parent_scope != root_scope_id {
|
||||||
|
is_multiple = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
was_in_root_scope = parent_scope == root_scope_id;
|
||||||
|
let parent_kind = parent.kind();
|
||||||
|
if matches!(
|
||||||
|
parent_kind,
|
||||||
|
AstKind::ForOfStatement(_)
|
||||||
|
| AstKind::ForInStatement(_)
|
||||||
|
| AstKind::ForStatement(_)
|
||||||
|
| AstKind::WhileStatement(_)
|
||||||
|
| AstKind::DoWhileStatement(_)
|
||||||
|
| AstKind::ArrowFunctionExpression(_)
|
||||||
|
| AstKind::Function(_)
|
||||||
|
) {
|
||||||
|
is_multiple = true;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
is_multiple
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rule for PreferSetHas {
|
||||||
|
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||||
|
let AstKind::VariableDeclarator(declarator) = node.kind() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let VariableDeclarationKind::Var = declarator.kind {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(init) = declarator.init.as_ref() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_kind_of_array = is_kind_of_array_expr(init);
|
||||||
|
|
||||||
|
if !is_kind_of_array {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(ident) = declarator.id.get_binding_identifier() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(symbol_id) = ident.symbol_id.get() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let module_record = ctx.module_record();
|
||||||
|
if module_record.exported_bindings.contains_key(ident.name.as_str())
|
||||||
|
|| module_record.export_default.is_some_and(|default| default == ident.span)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let symbol_table = ctx.symbols();
|
||||||
|
|
||||||
|
let mut references = symbol_table.get_resolved_references(symbol_id).peekable();
|
||||||
|
|
||||||
|
let Ok(len) = references.try_len() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if len == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let root_scope = node.scope_id();
|
||||||
|
|
||||||
|
if len == 1 {
|
||||||
|
let Some(reference) = references.peek() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let node = ctx.nodes().get_node(reference.node_id());
|
||||||
|
|
||||||
|
if !is_multiple_calls(node, ctx, root_scope) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if references.any(|reference| {
|
||||||
|
let node = ctx.nodes().get_node(reference.node_id());
|
||||||
|
let Some(parent_id) = ctx.nodes().parent_id(node.id()) else {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
let Some(AstKind::CallExpression(call_expression)) = ctx.nodes().parent_kind(parent_id)
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
if call_expression.arguments.len() != 1 || call_expression.optional {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let arg = &call_expression.arguments[0];
|
||||||
|
if arg.is_spread() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let Some(AstKind::MemberExpression(member_expr)) = ctx.nodes().parent_kind(node.id())
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
if member_expr.optional() || member_expr.is_computed() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let is_method = is_method_call(
|
||||||
|
call_expression,
|
||||||
|
Some(&[ident.name.as_str()]),
|
||||||
|
Some(&["includes"]),
|
||||||
|
Some(1),
|
||||||
|
Some(1),
|
||||||
|
);
|
||||||
|
!is_method
|
||||||
|
}) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.diagnostic_with_fix(prefer_set_has_diagnostic(declarator.span), |fixer| {
|
||||||
|
let fixer = fixer.for_multifix();
|
||||||
|
let mut declaration_fix = fixer.new_fix_with_capacity(2);
|
||||||
|
let new_string = "new";
|
||||||
|
let set_start_string = "Set(";
|
||||||
|
let set_end_string = ")";
|
||||||
|
let set_array_string = format!("{set_start_string}[");
|
||||||
|
let net_set_array_string = format!("{new_string} {set_array_string}");
|
||||||
|
let new_set_start_string = format!("{new_string} {set_start_string}");
|
||||||
|
let array_end_string = format!("]{set_end_string}");
|
||||||
|
let array_parenthesis_len = 6; // Array( => 6
|
||||||
|
let new_space_len = 4; // new => 4
|
||||||
|
match init {
|
||||||
|
Expression::ArrayExpression(init_node) => {
|
||||||
|
declaration_fix
|
||||||
|
.push(fixer.insert_text_before(&init_node.span, new_set_start_string));
|
||||||
|
declaration_fix.push(fixer.insert_text_after(&init_node.span, set_end_string));
|
||||||
|
}
|
||||||
|
Expression::CallExpression(call_expr) => {
|
||||||
|
if call_expr.callee.is_identifier_reference() {
|
||||||
|
let start = call_expr.span.start;
|
||||||
|
let end = start + 6;
|
||||||
|
let span = Span::new(start, end);
|
||||||
|
declaration_fix.push(fixer.replace(span, net_set_array_string));
|
||||||
|
let start = call_expr.span.end - 1;
|
||||||
|
let end = start + 1;
|
||||||
|
let span = Span::new(start, end);
|
||||||
|
declaration_fix.push(fixer.replace(span, array_end_string));
|
||||||
|
} else {
|
||||||
|
declaration_fix
|
||||||
|
.push(fixer.insert_text_before(&call_expr.span, new_set_start_string));
|
||||||
|
declaration_fix
|
||||||
|
.push(fixer.insert_text_after(&call_expr.span, set_end_string));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expression::NewExpression(new_expr) => {
|
||||||
|
let start = new_expr.span.start + new_space_len;
|
||||||
|
let end = start + array_parenthesis_len;
|
||||||
|
let span = Span::new(start, end);
|
||||||
|
declaration_fix.push(fixer.replace(span, set_array_string));
|
||||||
|
let start = new_expr.span.end - 1;
|
||||||
|
let end = start + 1;
|
||||||
|
let span = Span::new(start, end);
|
||||||
|
declaration_fix.push(fixer.replace(span, array_end_string));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut references_fix = fixer.new_fix_with_capacity(len);
|
||||||
|
let references = symbol_table.get_resolved_references(symbol_id);
|
||||||
|
for reference in references {
|
||||||
|
let node = ctx.nodes().get_node(reference.node_id());
|
||||||
|
let Some(parent) = ctx.nodes().parent_node(node.id()) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let AstKind::MemberExpression(member_expr) = parent.kind() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(property_info) = member_expr.static_property_info() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
references_fix.push(fixer.replace(property_info.0, "has"));
|
||||||
|
}
|
||||||
|
return declaration_fix.extend(references_fix);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
use crate::tester::Tester;
|
||||||
|
|
||||||
|
let pass = vec![
|
||||||
|
"
|
||||||
|
const foo = new Set([1, 2, 3]);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.has(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
const isExists = foo.includes(1);
|
||||||
|
",
|
||||||
|
"
|
||||||
|
while (a) {
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
const isExists = foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
(() => {})(foo.includes(1));
|
||||||
|
",
|
||||||
|
"
|
||||||
|
foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const exists = foo.includes(1);
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const exists = [1, 2, 3].includes(1);
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes;
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return includes(foo);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return bar.includes(foo);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo[includes](1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.indexOf(1) !== -1;
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
foo.includes(1);
|
||||||
|
foo.length = 1;
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
if (foo.includes(1)) {}
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
var foo = [1, 2, 3];
|
||||||
|
var foo = [4, 5, 6];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = bar;
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes();
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1, 1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1, 0);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1, undefined);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(...[1]);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo?.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes?.(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo?.includes?.(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
function unicorn() {
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
}
|
||||||
|
function unicorn2() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
export const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
module.exports = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return module.exports.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
export {foo};
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
export default foo;
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
export {foo as bar};
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
module.exports = foo;
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
exports = foo;
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
module.exports.foo = foo;
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = NotArray(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = new NotArray(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = NotArray.from({length: 1}, (_, index) => index);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = NotArray.of(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = Array.notListed();
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = Array[from]({length: 1}, (_, index) => index);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = Array[of](1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = 'Array'.from({length: 1}, (_, index) => index);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = 'Array'.of(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = Array['from']({length: 1}, (_, index) => index);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = Array['of'](1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = of(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = from({length: 1}, (_, index) => index);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = bar.notListed();
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = _.map([1, 2, 3], value => value);
|
||||||
|
function unicorn() {
|
||||||
|
return _.includes(foo, 1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
@connect(
|
||||||
|
state => {
|
||||||
|
const availableComponents = ['is']
|
||||||
|
if (nsConfig.enabled) availableComponents.push('ns')
|
||||||
|
if (jsConfig.enabled) availableComponents.push('js')
|
||||||
|
if (asConfig.enabled) availableComponents.push('as')
|
||||||
|
return {
|
||||||
|
availableComponents,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
export default class A {}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
@connect(
|
||||||
|
state => {
|
||||||
|
const availableComponents = ['is']
|
||||||
|
if (nsConfig.enabled) availableComponents.push('ns')
|
||||||
|
if (jsConfig.enabled) availableComponents.push('js')
|
||||||
|
return {
|
||||||
|
availableComponents,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
export default class A {}
|
||||||
|
",
|
||||||
|
];
|
||||||
|
|
||||||
|
let fail = vec![
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
const isExists = foo.includes(1);
|
||||||
|
const isExists2 = foo.includes(2);
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
for (const a of b) {
|
||||||
|
foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
async function unicorn() {
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
for await (const a of b) {
|
||||||
|
foo.includes(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
for (let a in b) {
|
||||||
|
foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
while (a) {
|
||||||
|
foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
do {
|
||||||
|
foo.includes(1);
|
||||||
|
} while (a)
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
do {
|
||||||
|
// …
|
||||||
|
} while (foo.includes(1))
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function * unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
async function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
async function * unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
const unicorn = function () {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
const unicorn = () => foo.includes(1);
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
const a = {
|
||||||
|
b() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
class A {
|
||||||
|
b() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [...bar];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
bar.pop();
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
const exists = foo.includes(1);
|
||||||
|
function isExists(find) {
|
||||||
|
return foo.includes(find);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
function wrap() {
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bar = [4, 5, 6];
|
||||||
|
function unicorn() {
|
||||||
|
return bar.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function wrap() {
|
||||||
|
const exists = foo.includes(1);
|
||||||
|
const bar = [1, 2, 3];
|
||||||
|
function outer(find) {
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
while (a) {
|
||||||
|
foo.includes(1);
|
||||||
|
}
|
||||||
|
function inner(find) {
|
||||||
|
const bar = [1, 2, 3];
|
||||||
|
while (a) {
|
||||||
|
const exists = bar.includes(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = Array(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = new Array(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = Array.from({length: 1}, (_, index) => index);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = Array.of(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = _([1,2,3]);
|
||||||
|
const bar = foo.map(value => value);
|
||||||
|
function unicorn() {
|
||||||
|
return bar.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const a: Array<'foo' | 'bar'> = ['foo', 'bar']
|
||||||
|
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (a.includes(someString)) {
|
||||||
|
console.log(123)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
];
|
||||||
|
|
||||||
|
let fix = vec![
|
||||||
|
(
|
||||||
|
"
|
||||||
|
const foo = [1, 2, 3];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = new Set([1, 2, 3]);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.has(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"
|
||||||
|
const foo = [...bar];
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
bar.pop();
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = new Set([...bar]);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.has(1);
|
||||||
|
}
|
||||||
|
bar.pop();
|
||||||
|
",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"
|
||||||
|
const foo = Array(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = new Set([1, 2]);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.has(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"
|
||||||
|
const foo = new Array(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = new Set([1, 2]);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.has(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"
|
||||||
|
const foo = _([1,2,3]);
|
||||||
|
const bar = foo.map(value => value);
|
||||||
|
function unicorn() {
|
||||||
|
return bar.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = _([1,2,3]);
|
||||||
|
const bar = new Set(foo.map(value => value));
|
||||||
|
function unicorn() {
|
||||||
|
return bar.has(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"
|
||||||
|
const foo = Array.of(1, 2);
|
||||||
|
function unicorn() {
|
||||||
|
return foo.includes(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
const foo = new Set(Array.of(1, 2));
|
||||||
|
function unicorn() {
|
||||||
|
return foo.has(1);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
Tester::new(PreferSetHas::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
|
||||||
|
}
|
||||||
272
crates/oxc_linter/src/snapshots/prefer_set_has.snap
Normal file
272
crates/oxc_linter/src/snapshots/prefer_set_has.snap
Normal file
|
|
@ -0,0 +1,272 @@
|
||||||
|
---
|
||||||
|
source: crates/oxc_linter/src/tester.rs
|
||||||
|
---
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:10]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ const isExists = foo.includes(1);
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ for (const a of b) {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:3:20]
|
||||||
|
2 │ async function unicorn() {
|
||||||
|
3 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
4 │ for await (const a of b) {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ for (let i = 0; i < n; i++) {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ for (let a in b) {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ while (a) {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ do {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ do {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ function * unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ async function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ async function * unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ const unicorn = function () {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ const unicorn = () => foo.includes(1);
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ const a = {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ class A {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [...bar];
|
||||||
|
· ──────────────
|
||||||
|
3 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:3:20]
|
||||||
|
2 │ function wrap() {
|
||||||
|
3 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
4 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:8:19]
|
||||||
|
7 │ }
|
||||||
|
8 │ const bar = [4, 5, 6];
|
||||||
|
· ───────────────
|
||||||
|
9 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
3 │ function wrap() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:7:21]
|
||||||
|
6 │ function outer(find) {
|
||||||
|
7 │ const foo = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
8 │ while (a) {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:12:22]
|
||||||
|
11 │ function inner(find) {
|
||||||
|
12 │ const bar = [1, 2, 3];
|
||||||
|
· ───────────────
|
||||||
|
13 │ while (a) {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = Array(1, 2);
|
||||||
|
· ─────────────────
|
||||||
|
3 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = new Array(1, 2);
|
||||||
|
· ─────────────────────
|
||||||
|
3 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = Array.from({length: 1}, (_, index) => index);
|
||||||
|
· ──────────────────────────────────────────────────
|
||||||
|
3 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const foo = Array.of(1, 2);
|
||||||
|
· ────────────────────
|
||||||
|
3 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:3:19]
|
||||||
|
2 │ const foo = _([1,2,3]);
|
||||||
|
3 │ const bar = foo.map(value => value);
|
||||||
|
· ─────────────────────────────
|
||||||
|
4 │ function unicorn() {
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(prefer-set-has): should be a `Set`, and use `.has()` to check existence or non-existence.
|
||||||
|
╭─[prefer_set_has.tsx:2:19]
|
||||||
|
1 │
|
||||||
|
2 │ const a: Array<'foo' | 'bar'> = ['foo', 'bar']
|
||||||
|
· ────────────────────────────────────────
|
||||||
|
3 │
|
||||||
|
╰────
|
||||||
|
help: Switch to `Set`
|
||||||
Loading…
Reference in a new issue