From 1d01aa316f5dd4c3241821821c3a6096bd480480 Mon Sep 17 00:00:00 2001 From: camc314 <18101008+camc314@users.noreply.github.com> Date: Sat, 24 Aug 2024 22:58:38 +0000 Subject: [PATCH] feat(linter/unicorn): add partial fixer for `prefer-array-flat` (#5143) --- .../src/rules/unicorn/prefer_array_flat.rs | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs b/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs index 2c47dbf68b393..0b221321dd40d 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs @@ -58,7 +58,7 @@ declare_oxc_lint!( /// ``` PreferArrayFlat, pedantic, - pending + conditional_fix ); impl Rule for PreferArrayFlat { @@ -100,7 +100,19 @@ fn check_array_flat_map_case<'a>(call_expr: &CallExpression<'a>, ctx: &LintConte return; } - ctx.diagnostic(prefer_array_flat_diagnostic(call_expr.span)); + let target_fix_span = call_expr + .callee + .as_member_expression() + .and_then(oxc_ast::ast::MemberExpression::static_property_info) + .map(|v| Span::new(v.0.start, call_expr.span.end)); + + if let Some(span) = target_fix_span { + ctx.diagnostic_with_fix(prefer_array_flat_diagnostic(call_expr.span), |fixer| { + fixer.replace(span, "flat()") + }); + } else { + ctx.diagnostic(prefer_array_flat_diagnostic(call_expr.span)); + } } // `array.reduce((a, b) => a.concat(b), [])` @@ -162,11 +174,26 @@ fn check_array_reduce_case<'a>(call_expr: &CallExpression<'a>, ctx: &LintContext return; } - ctx.diagnostic(prefer_array_flat_diagnostic(call_expr.span)); + ctx.diagnostic_with_fix(prefer_array_flat_diagnostic(call_expr.span), |fixer| { + let target_fix_span = call_expr + .callee + .as_member_expression() + .and_then(oxc_ast::ast::MemberExpression::static_property_info) + .map(|v| Span::new(v.0.start, call_expr.span.end)); + + debug_assert!(target_fix_span.is_some()); + + if let Some(span) = target_fix_span { + fixer.replace(span, "flat()") + } else { + fixer.noop() + } + }); } } } + // `array.reduce((a, b) => [...a, ...b], [])` if let Expression::ArrayExpression(array_expr) = &expr_stmt.expression { if array_expr.elements.len() != 2 { return; @@ -194,7 +221,21 @@ fn check_array_reduce_case<'a>(call_expr: &CallExpression<'a>, ctx: &LintContext return; } - ctx.diagnostic(prefer_array_flat_diagnostic(call_expr.span)); + ctx.diagnostic_with_fix(prefer_array_flat_diagnostic(call_expr.span), |fixer| { + let target_fix_span = call_expr + .callee + .as_member_expression() + .and_then(oxc_ast::ast::MemberExpression::static_property_info) + .map(|v| Span::new(v.0.start, call_expr.span.end)); + + debug_assert!(target_fix_span.is_some()); + + if let Some(target_fix_span) = target_fix_span { + fixer.replace(target_fix_span, "flat()") + } else { + fixer.noop() + } + }); }; } @@ -405,5 +446,11 @@ fn test() { r"[/**/].concat(some.array)", ]; - Tester::new(PreferArrayFlat::NAME, pass, fail).test_and_snapshot(); + 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()"), + ]; + + Tester::new(PreferArrayFlat::NAME, pass, fail).expect_fix(fix).test_and_snapshot(); }