mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
fix(linter/unicorn): allow set spreading in no-useless-spread (#4944)
Closes #4872
This commit is contained in:
parent
4c989d0fda
commit
e99836d7d8
3 changed files with 15 additions and 34 deletions
|
|
@ -8,6 +8,10 @@ use crate::ast_util::{is_method_call, is_new_expression};
|
|||
pub(super) enum ValueHint {
|
||||
NewObject,
|
||||
NewArray,
|
||||
/// A non-array iterable.
|
||||
///
|
||||
/// Note that typed arrays are considered arrays, not iterables.
|
||||
NewIterable,
|
||||
Promise(Box<ValueHint>),
|
||||
Unknown,
|
||||
}
|
||||
|
|
@ -34,9 +38,12 @@ impl ValueHint {
|
|||
impl std::ops::BitAnd for ValueHint {
|
||||
type Output = Self;
|
||||
fn bitand(self, rhs: Self) -> Self::Output {
|
||||
// NOTE: what about (NewArray, NewIterable), e.g. in
|
||||
// `foo ? new Set() : []`
|
||||
match (self, rhs) {
|
||||
(Self::NewArray, Self::NewArray) => Self::NewArray,
|
||||
(Self::NewObject, Self::NewObject) => Self::NewObject,
|
||||
(Self::NewIterable, Self::NewIterable) => Self::NewIterable,
|
||||
_ => Self::Unknown,
|
||||
}
|
||||
}
|
||||
|
|
@ -81,8 +88,10 @@ impl<'a> ConstEval for Argument<'a> {
|
|||
|
||||
impl<'a> ConstEval for NewExpression<'a> {
|
||||
fn const_eval(&self) -> ValueHint {
|
||||
if is_new_array(self) || is_new_map_or_set(self) || is_new_typed_array(self) {
|
||||
if is_new_array(self) || is_new_typed_array(self) {
|
||||
ValueHint::NewArray
|
||||
} else if is_new_map_or_set(self) {
|
||||
ValueHint::NewIterable
|
||||
} else if is_new_object(self) {
|
||||
ValueHint::NewObject
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -492,23 +492,6 @@ fn get_method_name(call_expr: &CallExpression) -> Option<String> {
|
|||
Some(format!("{}.{}", object_name, callee.static_property_name().unwrap()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_debug() {
|
||||
use crate::tester::Tester;
|
||||
|
||||
let pass = vec![];
|
||||
|
||||
let fail = vec![
|
||||
// "[...arr.reduce(f, new Set())]",
|
||||
"const obj = { a, ...{ b, c } }",
|
||||
// "const promise = Promise.all([...iterable])",
|
||||
// "const obj = { ...(foo ? { a: 1 } : { a: 2 }) }",
|
||||
// "const array = [...[a]]",
|
||||
];
|
||||
|
||||
Tester::new(NoUselessSpread::NAME, pass, fail).test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::tester::Tester;
|
||||
|
|
@ -578,6 +561,7 @@ fn test() {
|
|||
// r"[...Int8Array.from(foo)]",
|
||||
// r"[...Int8Array.of()]",
|
||||
// r"[...new Int8Array(3)]",
|
||||
r"[...new Set(iter)]",
|
||||
r"[...Promise.all(foo)]",
|
||||
r"[...Promise.allSettled(foo)]",
|
||||
r"[...await Promise.all(foo, extraArgument)]",
|
||||
|
|
@ -585,6 +569,10 @@ fn test() {
|
|||
r"const obj = { ...obj, ...(addFoo ? { foo: 'foo' } : {}) }",
|
||||
r"<Button {...(isLoading ? { data: undefined } : { data: dataFromApi })} />",
|
||||
r"const obj = { ...(foo ? getObjectInOpaqueManner() : { a: 2 }) }",
|
||||
"[...arr.reduce((set, b) => set.add(b), new Set())]",
|
||||
"[...arr.reduce((set, b) => set.add(b), new Set(iter))]",
|
||||
// NOTE: we may want to consider this a violation in the future
|
||||
"[...(foo ? new Set() : [])]",
|
||||
];
|
||||
|
||||
let fail = vec![
|
||||
|
|
@ -707,8 +695,6 @@ fn test() {
|
|||
"[...arr.reduce((a, b) => a.push(b), Array.from(iter))]",
|
||||
"[...arr.reduce((a, b) => a.push(b), foo.map(x => x))]",
|
||||
"[...arr.reduce((a, b) => a.push(b), await Promise.all(promises))]",
|
||||
"[...arr.reduce((set, b) => set.add(b), new Set())]",
|
||||
"[...arr.reduce((set, b) => set.add(b), new Set(iter))]",
|
||||
// useless object clones with complex expressions
|
||||
r"const obj = { ...(foo ? { a: 1 } : { a: 2 }) }",
|
||||
r"const obj = { ...(foo ? Object.entries(obj).reduce(fn, {}) : { a: 2 }) }",
|
||||
|
|
|
|||
|
|
@ -788,20 +788,6 @@ source: crates/oxc_linter/src/tester.rs
|
|||
╰────
|
||||
help: `arr.reduce` returns a new array. Spreading it into an array expression to create a new array is redundant.
|
||||
|
||||
⚠ eslint-plugin-unicorn(no-useless-spread): Using a spread operator here creates a new array unnecessarily.
|
||||
╭─[no_useless_spread.tsx:1:2]
|
||||
1 │ [...arr.reduce((set, b) => set.add(b), new Set())]
|
||||
· ───
|
||||
╰────
|
||||
help: `arr.reduce` returns a new array. Spreading it into an array expression to create a new array is redundant.
|
||||
|
||||
⚠ eslint-plugin-unicorn(no-useless-spread): Using a spread operator here creates a new array unnecessarily.
|
||||
╭─[no_useless_spread.tsx:1:2]
|
||||
1 │ [...arr.reduce((set, b) => set.add(b), new Set(iter))]
|
||||
· ───
|
||||
╰────
|
||||
help: `arr.reduce` returns a new array. Spreading it into an array expression to create a new array is redundant.
|
||||
|
||||
⚠ eslint-plugin-unicorn(no-useless-spread): Using a spread operator here creates a new object unnecessarily.
|
||||
╭─[no_useless_spread.tsx:1:15]
|
||||
1 │ const obj = { ...(foo ? { a: 1 } : { a: 2 }) }
|
||||
|
|
|
|||
Loading…
Reference in a new issue