From b73cfd992e8f87f03b29d20488195275f5f90f44 Mon Sep 17 00:00:00 2001 From: tbashiyy <40194351+tbashiyy@users.noreply.github.com> Date: Mon, 4 Nov 2024 12:12:37 +0900 Subject: [PATCH] fix(linter): fix `is_method_call` with parentheses and chain expression (#7095) I fixed `is_method_call` behavior in specific case below. For example, when we use `is_method_call(call_expr, None, Some(&["apply"]), Some(1), Some(1))` for [`(a?.b.apply)(args)`](https://playground.oxc.rs/#eNpFjkEKg0AMRe+SVQviAdx057alN4gaZWBMJJmxFfHunVG0q+Qnn//fCi1UcMNH2ZQ4TX6531AHu0MBAtUKGjkPWzjgF6qgkQrwjsO5WysTXWIZG/GnCopsvegIVY/eaCtgQjXSnIjey+dNISo/YzDXUR25DU5S3+5OZqVknumFSmxHasrI7XtG2q+K89BKRwNl5iRGx653/xcHFV+n3gwwkzZiCf1g27YfdH1fTA==), we cannot check correctly. This is because we don't consider `call_expr` has parentheses and chain expression. --- crates/oxc_linter/src/ast_util.rs | 10 ++++++++-- .../oxc_linter/src/rules/unicorn/prefer_array_flat.rs | 2 ++ crates/oxc_linter/src/snapshots/prefer_array_flat.snap | 9 +++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/oxc_linter/src/ast_util.rs b/crates/oxc_linter/src/ast_util.rs index 86355df6a..c9333d9b8 100644 --- a/crates/oxc_linter/src/ast_util.rs +++ b/crates/oxc_linter/src/ast_util.rs @@ -332,8 +332,14 @@ pub fn is_method_call<'a>( } } - let Some(member_expr) = call_expr.callee.without_parentheses().as_member_expression() else { - return false; + let callee_without_parentheses = call_expr.callee.without_parentheses(); + let member_expr = match callee_without_parentheses { + match_member_expression!(Expression) => callee_without_parentheses.to_member_expression(), + Expression::ChainExpression(chain) => match chain.expression { + match_member_expression!(ChainElement) => chain.expression.to_member_expression(), + ChainElement::CallExpression(_) => return false, + }, + _ => return false, }; if let Some(objects) = objects { 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 a6a1c4a9b..c2d97c461 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs @@ -302,6 +302,7 @@ fn test() { r"array.flatMap(() => x)", r"array.flatMap((x, y) => x)", r"array.flatMap(x => y)", + r"(array?.flatMap)?.(x => y)", r"new array.reduce((a, b) => a.concat(b), [])", r"array.reduce", r"reduce((a, b) => a.concat(b), [])", @@ -388,6 +389,7 @@ fn test() { let fail = vec![ r"array.flatMap(x => x)", + r"(array?.flatMap)?.(x => x)", r"function foo(){return[].flatMap(x => x)}", r"foo.flatMap(x => x) instanceof Array", r"array.reduce((a, b) => a.concat(b), [])", diff --git a/crates/oxc_linter/src/snapshots/prefer_array_flat.snap b/crates/oxc_linter/src/snapshots/prefer_array_flat.snap index 4f154b9bb..6166f049e 100644 --- a/crates/oxc_linter/src/snapshots/prefer_array_flat.snap +++ b/crates/oxc_linter/src/snapshots/prefer_array_flat.snap @@ -1,5 +1,7 @@ --- source: crates/oxc_linter/src/tester.rs +assertion_line: 353 +snapshot_kind: text --- ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. ╭─[prefer_array_flat.tsx:1:1] @@ -8,6 +10,13 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Call `.flat()` on the array instead. + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. + ╭─[prefer_array_flat.tsx:1:1] + 1 │ (array?.flatMap)?.(x => x) + · ────────────────────────── + ╰──── + help: Call `.flat()` on the array instead. + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. ╭─[prefer_array_flat.tsx:1:22] 1 │ function foo(){return[].flatMap(x => x)}