diff --git a/crates/oxc_linter/src/generated/rule_runner_impls.rs b/crates/oxc_linter/src/generated/rule_runner_impls.rs index 5d991622066bf..01ad8309edf69 100644 --- a/crates/oxc_linter/src/generated/rule_runner_impls.rs +++ b/crates/oxc_linter/src/generated/rule_runner_impls.rs @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/tasks/linter_codegen/src/main.rs b/tasks/linter_codegen/src/main.rs index e0eae9ee8e7eb..4dfffe1f64983 100644 --- a/tasks/linter_codegen/src/main.rs +++ b/tasks/linter_codegen/src/main.rs @@ -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() { diff --git a/tasks/linter_codegen/src/match_detector.rs b/tasks/linter_codegen/src/match_detector.rs index 3d16ea1518301..cd82f1342c67c 100644 --- a/tasks/linter_codegen/src/match_detector.rs +++ b/tasks/linter_codegen/src/match_detector.rs @@ -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 { +impl<'a> MatchDetector<'a> { + pub fn from_run_func( + run_func: &syn::ImplItemFn, + rule_runner_data: &'a RuleRunnerData, + ) -> Option { // Only consider when the body's only statement is `match node.kind() { ... }` let block = &run_func.block; if block.stmts.len() != 1 { @@ -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; @@ -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, } }