From 05fba9b51c774c061be215078446faa716a0903e Mon Sep 17 00:00:00 2001 From: Sysix <3897725+Sysix@users.noreply.github.com> Date: Sun, 20 Jul 2025 21:04:44 +0000 Subject: [PATCH] fix(linter): don't panic on `TSNonNullExpression` in `unicorn/prefer-array-find` (#12400) closes #12399 --- .../src/rules/unicorn/prefer_array_find.rs | 26 ++++++++++++------- .../snapshots/unicorn_prefer_array_find.snap | 14 ++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_array_find.rs b/crates/oxc_linter/src/rules/unicorn/prefer_array_find.rs index 5b6296fcba97c..dbfbf61589b93 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_array_find.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_array_find.rs @@ -72,8 +72,11 @@ impl Rule for PreferArrayFind { if let AstKind::CallExpression(call_expr) = node.kind() { if is_method_call(call_expr, None, Some(&["shift"]), Some(0), Some(0)) { - if let Expression::CallExpression(filter_call_expr) = - call_expr.callee.as_member_expression().unwrap().object().get_inner_expression() + if let Some(Expression::CallExpression(filter_call_expr)) = call_expr + .callee + .get_inner_expression() + .as_member_expression() + .map(|expression| expression.object().get_inner_expression()) { if is_filter_call(filter_call_expr) { ctx.diagnostic(prefer_array_find_diagnostic( @@ -197,12 +200,11 @@ impl Rule for PreferArrayFind { }) }) { - if let Expression::CallExpression(filter_call_expr) = at_call_expr + if let Some(Expression::CallExpression(filter_call_expr)) = at_call_expr .callee - .as_member_expression() - .unwrap() - .object() .get_inner_expression() + .as_member_expression() + .map(|expression| expression.object().get_inner_expression()) { if is_filter_call(filter_call_expr) { ctx.diagnostic(prefer_array_find_diagnostic( @@ -216,12 +218,11 @@ impl Rule for PreferArrayFind { // `array.filter().pop()` if let AstKind::CallExpression(pop_call_expr) = node.kind() { if is_method_call(pop_call_expr, None, Some(&["pop"]), Some(0), Some(0)) { - if let Expression::CallExpression(filter_call_expr) = pop_call_expr + if let Some(Expression::CallExpression(filter_call_expr)) = pop_call_expr .callee - .as_member_expression() - .unwrap() - .object() .get_inner_expression() + .as_member_expression() + .map(|expression| expression.object().get_inner_expression()) { if is_filter_call(filter_call_expr) { ctx.diagnostic(prefer_array_find_diagnostic( @@ -427,6 +428,8 @@ fn test() { "array.filter().at(0)", "array.filter(foo, thisArgument, extraArgument).at(0)", "array.filter(...foo).at(0)", + // oxc-project/oxc#12399 + "{a.pop!()}", ]; let fail = vec![ @@ -609,6 +612,9 @@ fn test() { ) // comment 6 ;", + // oxc-project/oxc#12399 + "array.filter(foo).pop!()", + "array.filter(foo)?.pop()", ]; let _fix: Vec<(&'static str, &'static str, Option)> = vec![ diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_array_find.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_array_find.snap index c7287e141006e..2b5f099af7cc4 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_array_find.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_array_find.snap @@ -563,3 +563,17 @@ source: crates/oxc_linter/src/tester.rs 4 │ // comment 2 ╰──── help: Use 'find(predicate)' instead of 'filter(predicate)[0]' or similar patterns + + ⚠ eslint-plugin-unicorn(prefer-array-find): Prefer 'find' over filtering and accessing the first result + ╭─[prefer_array_find.tsx:1:7] + 1 │ array.filter(foo).pop!() + · ────── + ╰──── + help: Use 'find(predicate)' instead of 'filter(predicate)[0]' or similar patterns + + ⚠ eslint-plugin-unicorn(prefer-array-find): Prefer 'find' over filtering and accessing the first result + ╭─[prefer_array_find.tsx:1:7] + 1 │ array.filter(foo)?.pop() + · ────── + ╰──── + help: Use 'find(predicate)' instead of 'filter(predicate)[0]' or similar patterns