mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(linter/unicorn/prefer-array-flat): fix concat.apply suggestions (#25373)
## Summary - Add fixes for identifier-backed `[].concat.apply([], array)` and `Array.prototype.concat.apply([], array)` cases. - Keep other `apply` and `call` patterns diagnostic-only. --------- Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>
This commit is contained in:
1 parent
7d8a9b5f2f
commit
44e73fde5f
2 files changed
+55
-12
No files matched your search
@@ -359,22 +359,34 @@ fn check_array_prototype_concat_case<'a>(call_expr: &CallExpression<'a>, ctx: &L
|
||||
|
||||
if let Some(member_expr_obj) = member_expr.object().as_member_expression() {
|
||||
let is_call_call = is_method_call(call_expr, None, Some(&["call"]), Some(2), Some(2));
|
||||
let is_apply_call = is_method_call(call_expr, None, Some(&["apply"]), Some(2), Some(2));
|
||||
|
||||
if (is_call_call || is_method_call(call_expr, None, Some(&["apply"]), Some(2), Some(2)))
|
||||
if (is_call_call || is_apply_call)
|
||||
&& is_prototype_property(member_expr_obj, "concat", Some("Array"))
|
||||
&& let Some(first_argument) = call_expr.arguments[0].as_expression()
|
||||
&& is_empty_array_expression(first_argument)
|
||||
&& (is_call_call
|
||||
|| !matches!(call_expr.arguments.get(1), Some(Argument::SpreadElement(_))))
|
||||
{
|
||||
ctx.diagnostic(prefer_array_flat_diagnostic(call_expr.span));
|
||||
if is_apply_call
|
||||
&& let Some(Argument::Identifier(array)) = call_expr.arguments.get(1)
|
||||
&& array.name != "arguments"
|
||||
{
|
||||
let replacement = format!("{}.flat()", ctx.source_range(array.span));
|
||||
ctx.diagnostic_with_dangerous_fix(
|
||||
prefer_array_flat_diagnostic(call_expr.span),
|
||||
|fixer| fixer.replace(call_expr.span, replacement),
|
||||
);
|
||||
} else {
|
||||
ctx.diagnostic(prefer_array_flat_diagnostic(call_expr.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::tester::Tester;
|
||||
use crate::{fixer::FixKind, tester::Tester};
|
||||
|
||||
let pass = vec![
|
||||
"array.flatMap",
|
||||
@@ -557,6 +569,7 @@ fn test() {
|
||||
"[].concat.apply([], ((array)))",
|
||||
"[].concat.apply([], [foo])",
|
||||
"[].concat.apply([], [[foo]])",
|
||||
"function flatten() { return [].concat.apply([], arguments); }",
|
||||
"[].concat.call([], maybeArray)",
|
||||
"[].concat.call([], ((0, maybeArray)))",
|
||||
"[].concat.call([], ((maybeArray)))",
|
||||
@@ -573,6 +586,7 @@ fn test() {
|
||||
"Array.prototype.concat.apply([], ((array)))",
|
||||
"Array.prototype.concat.apply([], [foo])",
|
||||
"Array.prototype.concat.apply([], [[foo]])",
|
||||
"function flatten() { return Array.prototype.concat.apply([], arguments); }",
|
||||
"Array.prototype.concat.call([], maybeArray)",
|
||||
"Array.prototype.concat.call([], ((0, maybeArray)))",
|
||||
"Array.prototype.concat.call([], ((maybeArray)))",
|
||||
@@ -623,16 +637,28 @@ fn test() {
|
||||
];
|
||||
|
||||
let fix = vec![
|
||||
("array.flatMap(x => x)", "array.flat()"),
|
||||
("array.reduce((a, b) => a.concat(b), [])", "array.flat()"),
|
||||
("array.reduce((a, b) => [...a, ...b], [])", "array.flat()"),
|
||||
("Foo.bar.flatMap(x => x)", "Foo.bar.flat()"),
|
||||
("array.flatMap(x => x)", "array.flat()", None, FixKind::SafeFix),
|
||||
("array.reduce((a, b) => a.concat(b), [])", "array.flat()", None, FixKind::SafeFix),
|
||||
("array.reduce((a, b) => [...a, ...b], [])", "array.flat()", None, FixKind::SafeFix),
|
||||
("Foo.bar.flatMap(x => x)", "Foo.bar.flat()", None, FixKind::SafeFix),
|
||||
(
|
||||
"const values = getValues(); values.flatMap(x => x);",
|
||||
"const values = getValues(); values.flat();",
|
||||
None,
|
||||
FixKind::SafeFix,
|
||||
),
|
||||
(
|
||||
"const values = []; values.flatMap(x => x);",
|
||||
"const values = []; values.flat();",
|
||||
None,
|
||||
FixKind::SafeFix,
|
||||
),
|
||||
(
|
||||
"const Items = []; Items.flatMap(x => x);",
|
||||
"const Items = []; Items.flat();",
|
||||
None,
|
||||
FixKind::SafeFix,
|
||||
),
|
||||
("const values = []; values.flatMap(x => x);", "const values = []; values.flat();"),
|
||||
("const Items = []; Items.flatMap(x => x);", "const Items = []; Items.flat();"),
|
||||
(
|
||||
"for (const value of values) {
|
||||
value.flatMap(x => x);
|
||||
@@ -640,14 +666,17 @@ fn test() {
|
||||
"for (const value of values) {
|
||||
value.flat();
|
||||
}",
|
||||
None,
|
||||
FixKind::SafeFix,
|
||||
),
|
||||
(
|
||||
"const Items = [] as unknown[]; Items.flatMap(x => x);",
|
||||
"const Items = [] as unknown[]; Items.flat();",
|
||||
None,
|
||||
FixKind::SafeFix,
|
||||
),
|
||||
// TODO: Get these passing.
|
||||
// ("/**/[].concat.apply([], array)", "/**/array.flat()"),
|
||||
// ("Array.prototype.concat.apply([], array)", "array.flat()"),
|
||||
("/**/[].concat.apply([], array)", "/**/array.flat()", None, FixKind::DangerousFix),
|
||||
("Array.prototype.concat.apply([], array)", "array.flat()", None, FixKind::DangerousFix),
|
||||
];
|
||||
|
||||
Tester::new(PreferArrayFlat::NAME, PreferArrayFlat::PLUGIN, pass, fail)
|
||||
|
||||
@@ -249,6 +249,13 @@ source: crates/oxc_linter/src/tester.rs
|
||||
╰────
|
||||
help: Call `.flat()` on the array instead.
|
||||
|
||||
⚠ unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays.
|
||||
╭─[prefer_array_flat.tsx:1:29]
|
||||
1 │ function flatten() { return [].concat.apply([], arguments); }
|
||||
· ──────────────────────────────
|
||||
╰────
|
||||
help: Call `.flat()` on the array instead.
|
||||
|
||||
⚠ unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays.
|
||||
╭─[prefer_array_flat.tsx:1:1]
|
||||
1 │ [].concat.call([], maybeArray)
|
||||
@@ -361,6 +368,13 @@ source: crates/oxc_linter/src/tester.rs
|
||||
╰────
|
||||
help: Call `.flat()` on the array instead.
|
||||
|
||||
⚠ unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays.
|
||||
╭─[prefer_array_flat.tsx:1:29]
|
||||
1 │ function flatten() { return Array.prototype.concat.apply([], arguments); }
|
||||
· ───────────────────────────────────────────
|
||||
╰────
|
||||
help: Call `.flat()` on the array instead.
|
||||
|
||||
⚠ unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays.
|
||||
╭─[prefer_array_flat.tsx:1:1]
|
||||
1 │ Array.prototype.concat.call([], maybeArray)
|
||||
|
||||
Reference in new issue
Block a user