Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions crates/oxc_linter/src/generated/rule_runner_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,13 @@ impl RuleRunner for crate::rules::eslint::no_new::NoNew {
}

impl RuleRunner for crate::rules::eslint::no_new_func::NoNewFunc {
const NODE_TYPES: Option<&AstTypesBitset> = None;
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
AstType::CallExpression,
AstType::ComputedMemberExpression,
AstType::NewExpression,
AstType::PrivateFieldExpression,
AstType::StaticMemberExpression,
]));
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
}

Expand Down Expand Up @@ -1069,7 +1075,12 @@ impl RuleRunner for crate::rules::import::no_anonymous_default_export::NoAnonymo
}

impl RuleRunner for crate::rules::import::no_commonjs::NoCommonjs {
const NODE_TYPES: Option<&AstTypesBitset> = None;
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
AstType::CallExpression,
AstType::ComputedMemberExpression,
AstType::PrivateFieldExpression,
AstType::StaticMemberExpression,
]));
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
}

Expand Down Expand Up @@ -2274,7 +2285,12 @@ impl RuleRunner for crate::rules::react::no_set_state::NoSetState {
}

impl RuleRunner for crate::rules::react::no_string_refs::NoStringRefs {
const NODE_TYPES: Option<&AstTypesBitset> = None;
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
AstType::ComputedMemberExpression,
AstType::JSXAttribute,
AstType::PrivateFieldExpression,
AstType::StaticMemberExpression,
]));
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
}

Expand Down Expand Up @@ -3487,7 +3503,13 @@ impl RuleRunner for crate::rules::unicorn::prefer_node_protocol::PreferNodeProto
}

impl RuleRunner for crate::rules::unicorn::prefer_number_properties::PreferNumberProperties {
const NODE_TYPES: Option<&AstTypesBitset> = None;
const NODE_TYPES: Option<&AstTypesBitset> = Some(&AstTypesBitset::from_types(&[
AstType::CallExpression,
AstType::ComputedMemberExpression,
AstType::IdentifierReference,
AstType::PrivateFieldExpression,
AstType::StaticMemberExpression,
]));
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
}

Expand Down
2 changes: 1 addition & 1 deletion tasks/linter_codegen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ fn detect_top_level_node_types(
return Some(node_types);
}

let node_types = MatchDetector::from_run_func(run_func);
let node_types = MatchDetector::from_run_func(run_func, rule_runner_data);
if let Some(node_types) = node_types
&& !node_types.is_empty()
{
Expand Down
31 changes: 26 additions & 5 deletions tasks/linter_codegen/src/match_detector.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
use syn::{Arm, Expr, Pat, Stmt};

use crate::{
CollectionResult,
CollectionResult, RuleRunnerData,
node_type_set::NodeTypeSet,
utils::{astkind_variant_from_path, is_node_kind_call},
};

/// Detects top-level `match node.kind() { ... }` patterns in the `run` method.
pub struct MatchDetector {
pub struct MatchDetector<'a> {
node_types: NodeTypeSet,
rule_runner_data: &'a RuleRunnerData,
}

impl MatchDetector {
pub fn from_run_func(run_func: &syn::ImplItemFn) -> Option<NodeTypeSet> {
impl<'a> MatchDetector<'a> {
pub fn from_run_func(
run_func: &syn::ImplItemFn,
rule_runner_data: &'a RuleRunnerData,
) -> Option<NodeTypeSet> {
// Only consider when the body's only statement is `match node.kind() { ... }`
let block = &run_func.block;
if block.stmts.len() != 1 {
Expand All @@ -28,7 +32,7 @@ impl MatchDetector {
return None;
}

let mut detector = Self { node_types: NodeTypeSet::new() };
let mut detector = Self { node_types: NodeTypeSet::new(), rule_runner_data };
let result = detector.extract_variants_from_match_expr(match_expr);
if detector.node_types.is_empty() || result == CollectionResult::Incomplete {
return None;
Expand Down Expand Up @@ -82,6 +86,23 @@ impl MatchDetector {
CollectionResult::Incomplete
}
}
Pat::Ident(ident) => {
if ident.subpat.is_some() {
return CollectionResult::Incomplete;
}
// Look for a `member_expr if member_expr.is_member_expression_kind() => {` arm
if let Some((_, guard_expr)) = &arm.guard
&& let Expr::MethodCall(method_call) = &**guard_expr
&& method_call.method == "is_member_expression_kind"
&& method_call.args.is_empty()
{
// We have a match, so we can add MemberExpression to the set of node types
self.node_types.extend(self.rule_runner_data.member_expression_kinds.clone());
CollectionResult::Complete
} else {
CollectionResult::Incomplete
}
}
_ => CollectionResult::Incomplete,
}
}
Expand Down
Loading