Skip to content

Commit a695472

Browse files
authored
refactor(linter): simplify finding ancestor of specific kind (oxc-project#11224)
1 parent 6a7018e commit a695472

File tree

5 files changed

+34
-62
lines changed

5 files changed

+34
-62
lines changed

crates/oxc_linter/src/rules/oxc/only_used_in_recursion.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -236,18 +236,13 @@ fn create_diagnostic_jsx(
236236

237237
// search for references to the function and remove the property
238238
for reference in ctx.semantic().symbol_references(property_symbol_id) {
239-
let mut ancestor_ids = ctx.nodes().ancestor_ids(reference.node_id());
240-
241-
let Some(attr) =
242-
ancestor_ids.find_map(|node| match ctx.nodes().get_node(node).kind() {
243-
AstKind::JSXAttributeItem(attr) => Some(attr),
244-
_ => None,
245-
})
246-
else {
247-
continue;
248-
};
249-
250-
fix.push(Fix::delete(attr.span()));
239+
if let Some(attr) = ctx
240+
.nodes()
241+
.ancestors(reference.node_id())
242+
.find_map(|node| node.kind().as_jsx_attribute_item())
243+
{
244+
fix.push(Fix::delete(attr.span()));
245+
}
251246
}
252247

253248
fix.with_message("Remove unused property")
@@ -334,9 +329,11 @@ fn is_property_only_used_in_recursion_jsx(
334329
return false;
335330
};
336331

337-
let Some(attr) = ctx.nodes().ancestors(may_jsx_expr_container.id()).find_map(|node| {
338-
if let AstKind::JSXAttributeItem(attr) = node.kind() { Some(attr) } else { None }
339-
}) else {
332+
let Some(attr) = ctx
333+
.nodes()
334+
.ancestors(may_jsx_expr_container.id())
335+
.find_map(|node| node.kind().as_jsx_attribute_item())
336+
else {
340337
return false;
341338
};
342339

@@ -350,14 +347,10 @@ fn is_property_only_used_in_recursion_jsx(
350347
return false;
351348
}
352349

353-
let Some(opening_element) =
354-
ctx.nodes().ancestor_ids(reference.node_id()).find_map(|node| {
355-
if let AstKind::JSXOpeningElement(elem) = ctx.nodes().get_node(node).kind() {
356-
Some(elem)
357-
} else {
358-
None
359-
}
360-
})
350+
let Some(opening_element) = ctx
351+
.nodes()
352+
.ancestors(reference.node_id())
353+
.find_map(|node| node.kind().as_jsx_opening_element())
361354
else {
362355
return false;
363356
};

crates/oxc_linter/src/rules/react/jsx_key.rs

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use cow_utils::CowUtils;
22
use oxc_ast::{
33
AstKind,
4-
ast::{Expression, JSXAttributeItem, JSXAttributeName, JSXElement, JSXFragment, Statement},
4+
ast::{
5+
CallExpression, Expression, JSXAttributeItem, JSXAttributeName, JSXElement, JSXFragment,
6+
Statement,
7+
},
58
};
69
use oxc_diagnostics::OxcDiagnostic;
710
use oxc_macros::declare_oxc_lint;
@@ -84,18 +87,8 @@ impl Rule for JsxKey {
8487
}
8588
}
8689

87-
pub fn is_to_array(node: &AstNode<'_>) -> bool {
88-
const TOARRAY: &str = "toArray";
89-
90-
let AstKind::CallExpression(call) = node.kind() else { return false };
91-
92-
let Some(subject) = call.callee_name() else { return false };
93-
94-
if subject != TOARRAY {
95-
return false;
96-
}
97-
98-
true
90+
pub fn is_to_array(call: &CallExpression<'_>) -> bool {
91+
call.callee_name().is_some_and(|subject| subject == "toArray")
9992
}
10093

10194
pub fn import_matcher<'a>(
@@ -125,12 +118,10 @@ pub fn is_import<'a>(
125118
import_matcher(ctx, actual_local_name, expected_module_name)
126119
}
127120

128-
pub fn is_children<'a, 'b>(node: &'b AstNode<'a>, ctx: &'b LintContext<'a>) -> bool {
121+
pub fn is_children<'a, 'b>(call: &'b CallExpression<'a>, ctx: &'b LintContext<'a>) -> bool {
129122
const REACT: &str = "React";
130123
const CHILDREN: &str = "Children";
131124

132-
let AstKind::CallExpression(call) = node.kind() else { return false };
133-
134125
let Some(member) = call.callee.as_member_expression() else { return false };
135126

136127
if let Expression::Identifier(ident) = member.object() {
@@ -150,8 +141,8 @@ pub fn is_children<'a, 'b>(node: &'b AstNode<'a>, ctx: &'b LintContext<'a>) -> b
150141
fn is_within_children_to_array<'a, 'b>(node: &'b AstNode<'a>, ctx: &'b LintContext<'a>) -> bool {
151142
let parents_iter = ctx.nodes().ancestors(node.id()).skip(2);
152143
parents_iter
153-
.filter(|parent_node| matches!(parent_node.kind(), AstKind::CallExpression(_)))
154-
.any(|parent_node| is_children(parent_node, ctx) && is_to_array(parent_node))
144+
.filter_map(|parent_node| parent_node.kind().as_call_expression())
145+
.any(|parent_call| is_children(parent_call, ctx) && is_to_array(parent_call))
155146
}
156147

157148
enum InsideArrayOrIterator {

crates/oxc_linter/src/rules/typescript/no_namespace.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,9 @@ impl Rule for NoNamespace {
182182
}
183183

184184
fn is_declaration(node: &AstNode, ctx: &LintContext) -> bool {
185-
ctx.nodes().ancestors(node.id()).any(|node| {
186-
let AstKind::TSModuleDeclaration(declaration) = node.kind() else {
187-
return false;
188-
};
189-
declaration.declare
190-
})
185+
ctx.nodes()
186+
.ancestors(node.id())
187+
.any(|node| node.kind().as_ts_module_declaration().is_some_and(|decl| decl.declare))
191188
}
192189

193190
#[test]

crates/oxc_linter/src/rules/vitest/no_conditional_tests.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use oxc_ast::AstKind;
21
use oxc_diagnostics::OxcDiagnostic;
32
use oxc_macros::declare_oxc_lint;
43
use oxc_span::Span;
@@ -79,12 +78,9 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>)
7978
JestFnKind::General(JestGeneralFnKind::Test),
8079
],
8180
) {
82-
let if_statement_node = ctx
83-
.nodes()
84-
.ancestors(node.id())
85-
.find(|node| matches!(node.kind(), AstKind::IfStatement(_)))?;
81+
let if_statement =
82+
ctx.nodes().ancestors(node.id()).find_map(|node| node.kind().as_if_statement())?;
8683

87-
let if_statement = if_statement_node.kind().as_if_statement()?;
8884
ctx.diagnostic(no_conditional_tests(if_statement.span));
8985
}
9086

crates/oxc_linter/src/rules/vitest/require_local_test_context_for_concurrent_snapshots.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,10 @@ impl RequireLocalTestContextForConcurrentSnapshots {
117117

118118
let test_or_describe_node_found =
119119
ctx.nodes().ancestors(possible_jest_node.node.id()).any(|node| {
120-
if let AstKind::CallExpression(ancestor_call_expr) = node.kind() {
121-
if let Some(ancestor_member_expr) =
122-
ancestor_call_expr.callee.as_member_expression()
123-
{
124-
return is_test_or_describe_node(ancestor_member_expr);
125-
}
126-
}
127-
128-
false
120+
node.kind()
121+
.as_call_expression()
122+
.and_then(|call_expr| call_expr.callee.as_member_expression())
123+
.is_some_and(|member_expr| is_test_or_describe_node(member_expr))
129124
});
130125

131126
if test_or_describe_node_found {

0 commit comments

Comments
 (0)