diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 4bf3a969ffc085..fbac8743bda2d2 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -95,6 +95,16 @@ macro_rules! add_member_expression_variants { } } +#[macro_export] +macro_rules! match_member_expression_variants { + ($ty:ident) => { + $ty::ComputedMemberExpression(_) + | $ty::StaticMemberExpression(_) + | $ty::PrivateFieldExpression(_) + }; +} +pub use match_member_expression_variants; + add_member_expression_variants! { /// Expression #[ast_node] @@ -282,10 +292,9 @@ impl<'a> Expression<'a> { #[allow(clippy::missing_panics_doc)] // `unwrap()` for `MemberExpression` variants cannot panic pub fn is_specific_member_access(&self, object: &str, property: &str) -> bool { - let inner = self.get_inner_expression(); - match inner { - _ if inner.is_member_expression() => { - inner.as_member_expression().unwrap().is_specific_member_access(object, property) + match self.get_inner_expression() { + expr if expr.is_member_expression() => { + expr.as_member_expression().unwrap().is_specific_member_access(object, property) } Expression::ChainExpression(chain) => { let Some(expr) = chain.expression.as_member_expression() else { @@ -356,10 +365,9 @@ impl<'a> Expression<'a> { } pub fn get_member_expr(&self) -> Option<&MemberExpression<'a>> { - let inner = self.get_inner_expression(); - match inner { + match self.get_inner_expression() { Expression::ChainExpression(chain_expr) => chain_expr.expression.as_member_expression(), - _ => inner.as_member_expression(), + expr => expr.as_member_expression(), } } @@ -787,9 +795,7 @@ impl<'a> MemberExpression<'a> { let object_matches = match self.object().without_parenthesized() { Expression::ChainExpression(x) => match &x.expression { ChainElement::CallExpression(_) => false, - ChainElement::ComputedMemberExpression(_) - | ChainElement::StaticMemberExpression(_) - | ChainElement::PrivateFieldExpression(_) => { + match_member_expression_variants!(ChainElement) => { let member_expr = x.expression.as_member_expression().unwrap(); member_expr.object().without_parenthesized().is_specific_id(object) } @@ -867,9 +873,7 @@ impl<'a> CallExpression<'a> { pub fn callee_name(&self) -> Option<&str> { match &self.callee { Expression::Identifier(ident) => Some(ident.name.as_str()), - _ => { - self.callee.as_member_expression().and_then(MemberExpression::static_property_name) - } + expr => expr.as_member_expression().and_then(MemberExpression::static_property_name), } } @@ -894,7 +898,7 @@ impl<'a> CallExpression<'a> { // TODO: is 'Symbol' reference to global object match &self.callee { Expression::Identifier(id) => id.name == "Symbol", - _ => match self.callee.as_member_expression() { + expr => match expr.as_member_expression() { Some(member) => { matches!(member.object(), Expression::Identifier(id) if id.name == "Symbol") && member.static_property_name() == Some("for") diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index bcda92589725fa..5a648a6b69093b 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -174,7 +174,6 @@ macro_rules! add_ts_type_variants { } } -// TODO: Create similar macros for the other inherited enums #[macro_export] macro_rules! match_ts_type_variants { ($ty:ident) => { @@ -1180,7 +1179,7 @@ impl<'a> Decorator<'a> { pub fn name(&self) -> Option<&str> { match &self.expression { Expression::Identifier(ident) => Some(&ident.name), - _ if self.expression.is_member_expression() => { + expr if expr.is_member_expression() => { self.expression.as_member_expression().unwrap().static_property_name() } Expression::CallExpression(call) => { diff --git a/crates/oxc_ast/src/ast_kind.rs b/crates/oxc_ast/src/ast_kind.rs index 40e991564f34cf..91ef1906636f65 100644 --- a/crates/oxc_ast/src/ast_kind.rs +++ b/crates/oxc_ast/src/ast_kind.rs @@ -351,13 +351,9 @@ impl<'a> AstKind<'a> { Expression::TSTypeAssertion(e) => Self::TSTypeAssertion(e), Expression::TSNonNullExpression(e) => Self::TSNonNullExpression(e), Expression::TSInstantiationExpression(e) => Self::TSInstantiationExpression(e), - - Expression::ComputedMemberExpression(_) - | Expression::StaticMemberExpression(_) - | Expression::PrivateFieldExpression(_) => { + match_member_expression_variants!(Expression) => { Self::MemberExpression(e.as_member_expression().unwrap()) } - Expression::Dummy => Self::Dummy, } } diff --git a/crates/oxc_ast/src/precedence.rs b/crates/oxc_ast/src/precedence.rs index 6c7f758e0294eb..807b51949d9204 100644 --- a/crates/oxc_ast/src/precedence.rs +++ b/crates/oxc_ast/src/precedence.rs @@ -1,10 +1,10 @@ use oxc_syntax::precedence::{GetPrecedence, Precedence}; use crate::ast::{ - ArrowFunctionExpression, AssignmentExpression, AwaitExpression, BinaryExpression, - CallExpression, ConditionalExpression, Expression, ImportExpression, LogicalExpression, - MemberExpression, NewExpression, SequenceExpression, UnaryExpression, UpdateExpression, - YieldExpression, + match_member_expression_variants, ArrowFunctionExpression, AssignmentExpression, + AwaitExpression, BinaryExpression, CallExpression, ConditionalExpression, Expression, + ImportExpression, LogicalExpression, MemberExpression, NewExpression, SequenceExpression, + UnaryExpression, UpdateExpression, YieldExpression, }; impl<'a> GetPrecedence for Expression<'a> { @@ -22,9 +22,9 @@ impl<'a> GetPrecedence for Expression<'a> { Self::AwaitExpression(expr) => expr.precedence(), Self::NewExpression(expr) => expr.precedence(), Self::CallExpression(expr) => expr.precedence(), - Self::ComputedMemberExpression(_) - | Self::StaticMemberExpression(_) - | Self::PrivateFieldExpression(_) => self.as_member_expression().unwrap().precedence(), + match_member_expression_variants!(Self) => { + self.as_member_expression().unwrap().precedence() + } _ => panic!("All cases should be covered"), } } diff --git a/crates/oxc_ast/src/visit/visit.rs b/crates/oxc_ast/src/visit/visit.rs index adb007c230bde6..1c044151a84477 100644 --- a/crates/oxc_ast/src/visit/visit.rs +++ b/crates/oxc_ast/src/visit/visit.rs @@ -1484,14 +1484,10 @@ pub mod walk { Expression::TSInstantiationExpression(expr) => { visitor.visit_ts_instantiation_expression(expr); } - - Expression::ComputedMemberExpression(_) - | Expression::StaticMemberExpression(_) - | Expression::PrivateFieldExpression(_) => { + match_member_expression_variants!(Expression) => { let member_expr = expr.as_member_expression().unwrap(); visitor.visit_member_expression(member_expr); } - Expression::Dummy => dummy!(), } } @@ -1625,14 +1621,9 @@ pub mod walk { pub fn walk_chain_element<'a, V: Visit<'a>>(visitor: &mut V, elem: &ChainElement<'a>) { match elem { ChainElement::CallExpression(expr) => visitor.visit_call_expression(expr), - - ChainElement::ComputedMemberExpression(_) - | ChainElement::StaticMemberExpression(_) - | ChainElement::PrivateFieldExpression(_) => { - let member_expr = elem.as_member_expression().unwrap(); - visitor.visit_member_expression(member_expr); + match_member_expression_variants!(ChainElement) => { + visitor.visit_member_expression(elem.as_member_expression().unwrap()); } - ChainElement::Dummy => dummy!(), } } @@ -1873,11 +1864,8 @@ pub mod walk { SimpleAssignmentTarget::AssignmentTargetIdentifier(ident) => { visitor.visit_identifier_reference(ident); } - SimpleAssignmentTarget::ComputedMemberExpression(_) - | SimpleAssignmentTarget::StaticMemberExpression(_) - | SimpleAssignmentTarget::PrivateFieldExpression(_) => { - let member_expr = target.as_member_expression().unwrap(); - visitor.visit_member_expression(member_expr); + match_member_expression_variants!(SimpleAssignmentTarget) => { + visitor.visit_member_expression(target.as_member_expression().unwrap()); } SimpleAssignmentTarget::TSAsExpression(expr) => { visitor.visit_expression(&expr.expression); diff --git a/crates/oxc_ast/src/visit/visit_mut.rs b/crates/oxc_ast/src/visit/visit_mut.rs index 337f74b7b03ae4..1f019003fcaf78 100644 --- a/crates/oxc_ast/src/visit/visit_mut.rs +++ b/crates/oxc_ast/src/visit/visit_mut.rs @@ -1512,14 +1512,10 @@ pub mod walk_mut { Expression::TSInstantiationExpression(expr) => { visitor.visit_ts_instantiation_expression(expr); } - - Expression::ComputedMemberExpression(_) - | Expression::StaticMemberExpression(_) - | Expression::PrivateFieldExpression(_) => { + match_member_expression_variants!(Expression) => { let member_expr = expr.as_member_expression_mut().unwrap(); visitor.visit_member_expression(member_expr); } - Expression::Dummy => dummy!(), } } @@ -1680,14 +1676,9 @@ pub mod walk_mut { ) { match elem { ChainElement::CallExpression(expr) => visitor.visit_call_expression(expr), - - ChainElement::ComputedMemberExpression(_) - | ChainElement::StaticMemberExpression(_) - | ChainElement::PrivateFieldExpression(_) => { - let member_expr = elem.as_member_expression_mut().unwrap(); - visitor.visit_member_expression(member_expr); + match_member_expression_variants!(ChainElement) => { + visitor.visit_member_expression(elem.as_member_expression_mut().unwrap()); } - ChainElement::Dummy => dummy!(), } } @@ -1952,11 +1943,8 @@ pub mod walk_mut { SimpleAssignmentTarget::AssignmentTargetIdentifier(ident) => { visitor.visit_identifier_reference(ident); } - SimpleAssignmentTarget::ComputedMemberExpression(_) - | SimpleAssignmentTarget::StaticMemberExpression(_) - | SimpleAssignmentTarget::PrivateFieldExpression(_) => { - let member_expr = target.as_member_expression_mut().unwrap(); - visitor.visit_member_expression(member_expr); + match_member_expression_variants!(SimpleAssignmentTarget) => { + visitor.visit_member_expression(target.as_member_expression_mut().unwrap()); } SimpleAssignmentTarget::TSAsExpression(expr) => { visitor.visit_expression(&mut expr.expression); diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 10895b3d0a8fcf..a8cca9869c2ebb 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -1016,13 +1016,9 @@ impl<'a, const MINIFY: bool> GenExpr for Expression<'a> { Self::TSTypeAssertion(e) => e.gen_expr(p, precedence, ctx), Self::TSNonNullExpression(e) => e.expression.gen_expr(p, precedence, ctx), Self::TSInstantiationExpression(e) => e.expression.gen_expr(p, precedence, ctx), - - Self::ComputedMemberExpression(_) - | Self::StaticMemberExpression(_) - | Self::PrivateFieldExpression(_) => { + match_member_expression_variants!(Self) => { self.as_member_expression().unwrap().gen_expr(p, precedence, ctx); } - Self::Dummy => dummy!(), } } @@ -1809,9 +1805,7 @@ impl<'a, const MINIFY: bool> GenExpr for SimpleAssignmentTarget<'a> { fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) { match self { Self::AssignmentTargetIdentifier(ident) => ident.gen(p, ctx), - Self::ComputedMemberExpression(_) - | Self::StaticMemberExpression(_) - | Self::PrivateFieldExpression(_) => { + match_member_expression_variants!(Self) => { self.as_member_expression().unwrap().gen_expr(p, precedence, ctx); } Self::TSAsExpression(e) => e.gen_expr(p, precedence, ctx), @@ -2018,9 +2012,7 @@ impl<'a, const MINIFY: bool> GenExpr for ChainExpression<'a> { fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) { match &self.expression { ChainElement::CallExpression(expr) => expr.gen_expr(p, precedence, ctx), - ChainElement::ComputedMemberExpression(_) - | ChainElement::StaticMemberExpression(_) - | ChainElement::PrivateFieldExpression(_) => { + match_member_expression_variants!(ChainElement) => { self.expression.as_member_expression().unwrap().gen_expr(p, precedence, ctx); } ChainElement::Dummy => dummy!(), diff --git a/crates/oxc_linter/src/rules/eslint/getter_return.rs b/crates/oxc_linter/src/rules/eslint/getter_return.rs index 6c56d25c8ceca3..1812e8b1e41e9f 100644 --- a/crates/oxc_linter/src/rules/eslint/getter_return.rs +++ b/crates/oxc_linter/src/rules/eslint/getter_return.rs @@ -1,7 +1,7 @@ use oxc_ast::{ ast::{ - ChainElement, Expression, MemberExpression, MethodDefinitionKind, ObjectProperty, - PropertyKind, + match_member_expression_variants, ChainElement, Expression, MemberExpression, + MethodDefinitionKind, ObjectProperty, PropertyKind, }, dummy, AstKind, }; @@ -89,18 +89,13 @@ impl GetterReturn { } fn handle_actual_expression<'a>(callee: &'a Expression<'a>) -> bool { - let callee = callee.without_parenthesized(); - match callee { - _ if callee.is_member_expression() => { - let member_expr = callee.as_member_expression().unwrap(); - Self::handle_member_expression(member_expr) + match callee.without_parenthesized() { + expr if expr.is_member_expression() => { + Self::handle_member_expression(expr.as_member_expression().unwrap()) } Expression::ChainExpression(ce) => match &ce.expression { - ChainElement::ComputedMemberExpression(_) - | ChainElement::StaticMemberExpression(_) - | ChainElement::PrivateFieldExpression(_) => { - let member_expr = ce.expression.as_member_expression().unwrap(); - Self::handle_member_expression(member_expr) + match_member_expression_variants!(ChainElement) => { + Self::handle_member_expression(ce.expression.as_member_expression().unwrap()) } ChainElement::CallExpression(_) => { false // todo: make a test for this diff --git a/crates/oxc_linter/src/rules/jest/prefer_spy_on.rs b/crates/oxc_linter/src/rules/jest/prefer_spy_on.rs index 23b42f0597a423..145e159be636db 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_spy_on.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_spy_on.rs @@ -73,12 +73,18 @@ impl Rule for PreferSpyOn { return; }; - if let Expression::CallExpression(call_expr) = right { - Self::check_and_fix(assign_expr, call_expr, left_assign, node, ctx); - } else if let Some(mem_expr) = right.as_member_expression() { - if let Expression::CallExpression(call_expr) = mem_expr.object() { + match right { + Expression::CallExpression(call_expr) => { Self::check_and_fix(assign_expr, call_expr, left_assign, node, ctx); - }; + } + _ => { + if let Some(mem_expr) = right.as_member_expression() { + let Expression::CallExpression(call_expr) = mem_expr.object() else { + return; + }; + Self::check_and_fix(assign_expr, call_expr, left_assign, node, ctx); + } + } } } } @@ -178,15 +184,17 @@ impl PreferSpyOn { return call_expr.arguments.first(); } - if let Some(mem_expr) = call_expr.callee.as_member_expression() { - if let Some(call_expr) = Self::find_mem_expr(mem_expr) { - return Self::get_jest_fn_call(call_expr); + match &call_expr.callee { + expr if expr.is_member_expression() => { + let mem_expr = expr.as_member_expression().unwrap(); + if let Some(call_expr) = Self::find_mem_expr(mem_expr) { + return Self::get_jest_fn_call(call_expr); + } + None } - } else if let Expression::CallExpression(call_expr) = &call_expr.callee { - return Self::get_jest_fn_call(call_expr); + Expression::CallExpression(call_expr) => Self::get_jest_fn_call(call_expr), + _ => None, } - - None } fn find_mem_expr<'a>(mut mem_expr: &'a MemberExpression<'a>) -> Option<&'a CallExpression<'a>> { diff --git a/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs b/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs index 5a90e2943d6270..1500b174732ae6 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs @@ -80,33 +80,44 @@ impl PreferToHaveLength { return; }; - let object = static_expr.object(); - if let Some(mem_expr) = object.as_member_expression() { - let Expression::CallExpression(expr_call_expr) = mem_expr.object() else { - return; - }; - match mem_expr { - MemberExpression::ComputedMemberExpression(_) => Self::check_and_fix( - call_expr, - expr_call_expr, - &parsed_expect_call, - Some("ComputedMember"), - mem_expr.static_property_name(), - ctx, - ), - MemberExpression::StaticMemberExpression(_) => Self::check_and_fix( + match static_expr.object() { + expr if expr.is_member_expression() => { + let mem_expr = expr.as_member_expression().unwrap(); + let Expression::CallExpression(expr_call_expr) = mem_expr.object() else { + return; + }; + match mem_expr { + MemberExpression::ComputedMemberExpression(_) => Self::check_and_fix( + call_expr, + expr_call_expr, + &parsed_expect_call, + Some("ComputedMember"), + mem_expr.static_property_name(), + ctx, + ), + MemberExpression::StaticMemberExpression(_) => Self::check_and_fix( + call_expr, + expr_call_expr, + &parsed_expect_call, + Some("StaticMember"), + mem_expr.static_property_name(), + ctx, + ), + MemberExpression::PrivateFieldExpression(_) => (), + MemberExpression::Dummy => dummy!(unreachable), + }; + } + Expression::CallExpression(expr_call_expr) => { + Self::check_and_fix( call_expr, expr_call_expr, &parsed_expect_call, - Some("StaticMember"), - mem_expr.static_property_name(), + None, + None, ctx, - ), - MemberExpression::PrivateFieldExpression(_) => (), - MemberExpression::Dummy => dummy!(unreachable), - }; - } else if let Expression::CallExpression(expr_call_expr) = object { - Self::check_and_fix(call_expr, expr_call_expr, &parsed_expect_call, None, None, ctx); + ); + } + _ => (), } } diff --git a/crates/oxc_linter/src/rules/oxc/misrefactored_assign_op.rs b/crates/oxc_linter/src/rules/oxc/misrefactored_assign_op.rs index d67e3d84df4af3..c8185827f9e2cb 100644 --- a/crates/oxc_linter/src/rules/oxc/misrefactored_assign_op.rs +++ b/crates/oxc_linter/src/rules/oxc/misrefactored_assign_op.rs @@ -1,7 +1,7 @@ // Based on https://github.com/rust-lang/rust-clippy//blob/c9a43b18f11219fa70fe632b29518581fcd589c8/clippy_lints/src/operators/misrefactored_assign_op.rs use oxc_ast::{ ast::{AssignmentTarget, Expression, SimpleAssignmentTarget}, - dummy, AstKind, + dummy, match_member_expression_variants, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -107,9 +107,7 @@ fn assignment_target_eq_expr<'a>( false } } - SimpleAssignmentTarget::ComputedMemberExpression(_) - | SimpleAssignmentTarget::StaticMemberExpression(_) - | SimpleAssignmentTarget::PrivateFieldExpression(_) => { + match_member_expression_variants!(SimpleAssignmentTarget) => { let member_expr = simple_assignment_target.as_member_expression().unwrap(); if let Some(right_member_expr) = right_expr.as_member_expression() { is_same_member_expression(member_expr, right_member_expr, ctx) diff --git a/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs index 9fa7658d5dc6c7..6f00ab0336305b 100644 --- a/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs +++ b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs @@ -49,8 +49,7 @@ declare_oxc_lint!( impl Rule for NoNonNullAssertedOptionalChain { fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { if let AstKind::TSNonNullExpression(non_null_expr) = node.kind() { - let inner = non_null_expr.expression.get_inner_expression(); - let chain_span = match inner { + let chain_span = match non_null_expr.expression.get_inner_expression() { Expression::ChainExpression(chain) => match &chain.expression { ChainElement::ComputedMemberExpression(member) if member.optional => { Some(member.object.span()) @@ -77,8 +76,8 @@ impl Rule for NoNonNullAssertedOptionalChain { None } } - _ if inner.is_member_expression() => { - let member_expr = inner.as_member_expression().unwrap(); + expr if expr.is_member_expression() => { + let member_expr = expr.as_member_expression().unwrap(); if member_expr.optional() && !is_parent_member_or_call(node, ctx) { Some(member_expr.object().span()) } else { diff --git a/crates/oxc_linter/src/rules/typescript/prefer_for_of.rs b/crates/oxc_linter/src/rules/typescript/prefer_for_of.rs index c229013cbfbd7d..08afb86199aa7e 100644 --- a/crates/oxc_linter/src/rules/typescript/prefer_for_of.rs +++ b/crates/oxc_linter/src/rules/typescript/prefer_for_of.rs @@ -151,16 +151,15 @@ impl Rule for PreferForOf { return; } - let object = mem_expr.object(); - if let Expression::Identifier(id) = object { - id.name.as_str() - } else if let Some(mem_expr) = object.as_member_expression() { - match mem_expr.static_property_name() { - Some(array_name) => array_name, - None => return, + match &mem_expr.object() { + Expression::Identifier(id) => id.name.as_str(), + expr if expr.is_member_expression() => { + match expr.as_member_expression().unwrap().static_property_name() { + Some(array_name) => array_name, + None => return, + } } - } else { - return; + _ => return, } }; @@ -199,11 +198,10 @@ impl Rule for PreferForOf { let parent_kind = ref_parent.kind(); let AstKind::MemberExpression(mem_expr) = parent_kind else { return true }; - let object = mem_expr.object(); - match object { + match mem_expr.object() { Expression::Identifier(id) => id.name.as_str() != array_name, - _ if object.is_member_expression() => { - match object.as_member_expression().unwrap().static_property_name() { + expr if expr.is_member_expression() => { + match expr.as_member_expression().unwrap().static_property_name() { Some(prop_name) => prop_name != array_name, None => true, } diff --git a/crates/oxc_linter/src/rules/unicorn/no_array_for_each.rs b/crates/oxc_linter/src/rules/unicorn/no_array_for_each.rs index 341c7bbfb50f03..f138826d76beaf 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_array_for_each.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_array_for_each.rs @@ -73,8 +73,9 @@ impl Rule for NoArrayForEach { } } _ if object.is_member_expression() => { - let member_expr = object.as_member_expression().unwrap(); - if let Some(name) = member_expr.static_property_name() { + if let Some(name) = + object.as_member_expression().unwrap().static_property_name() + { if IGNORED_OBJECTS.contains(name) { return; } diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_spread.rs b/crates/oxc_linter/src/rules/unicorn/prefer_spread.rs index 8e727136de3c26..24a8bdcb355eba 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_spread.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_spread.rs @@ -193,10 +193,9 @@ fn is_not_array(expr: &Expression) -> bool { return false; } - let expr = expr.without_parenthesized(); - let ident = match expr { + let ident = match expr.without_parenthesized() { Expression::Identifier(ident) => ident.name.as_str(), - _ if expr.is_member_expression() => { + expr if expr.is_member_expression() => { let member_expr = expr.as_member_expression().unwrap(); if let Some(v) = member_expr.static_property_name() { v diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_type_error.rs b/crates/oxc_linter/src/rules/unicorn/prefer_type_error.rs index 005833707d25dd..f2b504b0166c6d 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_type_error.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_type_error.rs @@ -79,8 +79,7 @@ impl Rule for PreferTypeError { fn is_type_checking_expr(expr: &Expression) -> bool { match expr { _ if expr.is_member_expression() => { - let member_expr = expr.as_member_expression().unwrap(); - is_type_checking_member_expr(member_expr) + is_type_checking_member_expr(expr.as_member_expression().unwrap()) } Expression::CallExpression(call_expr) => is_typechecking_call_expr(call_expr), Expression::UnaryExpression(unary_expr) => { diff --git a/crates/oxc_linter/src/rules/unicorn/throw_new_error.rs b/crates/oxc_linter/src/rules/unicorn/throw_new_error.rs index f2ad1a7f485463..d827254eecfa6e 100644 --- a/crates/oxc_linter/src/rules/unicorn/throw_new_error.rs +++ b/crates/oxc_linter/src/rules/unicorn/throw_new_error.rs @@ -60,14 +60,13 @@ impl Rule for ThrowNewError { return; }; - let callee = call_expr.callee.without_parenthesized(); - match callee { + match call_expr.callee.without_parenthesized() { Expression::Identifier(v) => { if !CUSTOM_ERROR_REGEX_PATTERN.is_match(&v.name) { return; } } - _ if callee.is_member_expression() => { + callee if callee.is_member_expression() => { let member_expr = callee.as_member_expression().unwrap(); if member_expr.is_computed() { return; diff --git a/crates/oxc_linter/src/utils/jest/parse_jest_fn.rs b/crates/oxc_linter/src/utils/jest/parse_jest_fn.rs index dddf432ed6de94..d109e9e6f0d070 100644 --- a/crates/oxc_linter/src/utils/jest/parse_jest_fn.rs +++ b/crates/oxc_linter/src/utils/jest/parse_jest_fn.rs @@ -294,8 +294,7 @@ fn resolve_first_ident<'a>(expr: &'a Expression<'a>) -> Option<&'a IdentifierRef match expr { Expression::Identifier(ident) => Some(ident), _ if expr.is_member_expression() => { - let member_expr = expr.as_member_expression().unwrap(); - resolve_first_ident(member_expr.object()) + resolve_first_ident(expr.as_member_expression().unwrap().object()) } Expression::CallExpression(call_expr) => resolve_first_ident(&call_expr.callee), Expression::TaggedTemplateExpression(tagged_expr) => resolve_first_ident(&tagged_expr.tag), diff --git a/crates/oxc_prettier/src/format/assignment.rs b/crates/oxc_prettier/src/format/assignment.rs index cbc3f076ce11f1..f52dbe43949a59 100644 --- a/crates/oxc_prettier/src/format/assignment.rs +++ b/crates/oxc_prettier/src/format/assignment.rs @@ -373,17 +373,9 @@ fn is_poorly_breakable_member_or_call_chain<'a>(p: &Prettier<'a>, expr: &Express call_expressions.push(call_expr); Some(callee) } - Expression::ComputedMemberExpression(member_expr) => { + _ if node.is_member_expression() => { is_chain_expression = true; - Some(&member_expr.object) - } - Expression::StaticMemberExpression(member_expr) => { - is_chain_expression = true; - Some(&member_expr.object) - } - Expression::PrivateFieldExpression(member_expr) => { - is_chain_expression = true; - Some(&member_expr.object) + Some(node.as_member_expression().unwrap().object()) } Expression::Identifier(_) | Expression::ThisExpression(_) => { is_ident_or_this_expr = true; diff --git a/crates/oxc_prettier/src/format/call_arguments.rs b/crates/oxc_prettier/src/format/call_arguments.rs index bd448cf919a4d5..1d41ad933e31c3 100644 --- a/crates/oxc_prettier/src/format/call_arguments.rs +++ b/crates/oxc_prettier/src/format/call_arguments.rs @@ -338,9 +338,8 @@ fn is_simple_call_argument(node: &Expression, depth: usize) -> bool { if let Expression::UpdateExpression(expr) = node { return match &expr.argument { SimpleAssignmentTarget::AssignmentTargetIdentifier(target) => true, - _ if expr.argument.is_member_expression() => { - let target = expr.argument.as_member_expression().unwrap(); - check_member_expression(target) + target if target.is_member_expression() => { + check_member_expression(target.as_member_expression().unwrap()) } _ => return false, }; diff --git a/crates/oxc_prettier/src/format/mod.rs b/crates/oxc_prettier/src/format/mod.rs index ffbd3f9bd89d2c..43525d2f296acf 100644 --- a/crates/oxc_prettier/src/format/mod.rs +++ b/crates/oxc_prettier/src/format/mod.rs @@ -1293,11 +1293,9 @@ impl<'a> Format<'a> for Expression<'a> { Self::TSTypeAssertion(expr) => expr.expression.format(p), Self::TSNonNullExpression(expr) => expr.expression.format(p), Self::TSInstantiationExpression(expr) => expr.expression.format(p), - - Self::ComputedMemberExpression(_) - | Self::StaticMemberExpression(_) - | Self::PrivateFieldExpression(_) => self.as_member_expression().unwrap().format(p), - + match_member_expression_variants!(Self) => { + self.as_member_expression().unwrap().format(p) + } Self::Dummy => dummy!(unreachable), } } @@ -1832,9 +1830,9 @@ impl<'a> Format<'a> for SimpleAssignmentTarget<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { match self { Self::AssignmentTargetIdentifier(ident) => ident.format(p), - Self::ComputedMemberExpression(_) - | Self::StaticMemberExpression(_) - | Self::PrivateFieldExpression(_) => self.as_member_expression().unwrap().format(p), + match_member_expression_variants!(Self) => { + self.as_member_expression().unwrap().format(p) + } Self::TSAsExpression(expr) => expr.expression.format(p), Self::TSSatisfiesExpression(expr) => expr.expression.format(p), Self::TSNonNullExpression(expr) => expr.expression.format(p), @@ -2021,11 +2019,8 @@ impl<'a> Format<'a> for ChainElement<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { match self { Self::CallExpression(expr) => expr.format(p), - Self::ComputedMemberExpression(_) - | Self::StaticMemberExpression(_) - | Self::PrivateFieldExpression(_) => { - let member_expr = self.as_member_expression().unwrap(); - member_expr.format(p) + match_member_expression_variants!(Self) => { + self.as_member_expression().unwrap().format(p) } Self::Dummy => dummy!(unreachable), } diff --git a/crates/oxc_prettier/src/needs_parens.rs b/crates/oxc_prettier/src/needs_parens.rs index 0d90b61bcf449b..ff376238f624fc 100644 --- a/crates/oxc_prettier/src/needs_parens.rs +++ b/crates/oxc_prettier/src/needs_parens.rs @@ -606,15 +606,10 @@ impl<'a> Prettier<'a> { }, AssignmentTarget::AssignmentTargetPattern(_) | AssignmentTarget::Dummy => false, }, - Expression::ComputedMemberExpression(e) => { - Self::starts_with_no_lookahead_token(&e.object, span) - } - Expression::StaticMemberExpression(e) => { - Self::starts_with_no_lookahead_token(&e.object, span) - } - Expression::PrivateFieldExpression(e) => { - Self::starts_with_no_lookahead_token(&e.object, span) - } + _ if e.is_member_expression() => Self::starts_with_no_lookahead_token( + e.as_member_expression().unwrap().object(), + span, + ), Expression::TaggedTemplateExpression(e) => { if matches!(e.tag, Expression::FunctionExpression(_)) { return false; diff --git a/crates/oxc_transformer/src/react/display_name/mod.rs b/crates/oxc_transformer/src/react/display_name/mod.rs index d52f214242164c..ebc768d54d286a 100644 --- a/crates/oxc_transformer/src/react/display_name/mod.rs +++ b/crates/oxc_transformer/src/react/display_name/mod.rs @@ -93,10 +93,10 @@ impl<'a> ReactDisplayName<'a> { ) -> Option<&'b mut Box<'a, ObjectExpression<'a>>> { let Expression::CallExpression(call_expr) = e else { return None }; if match &call_expr.callee { - _ if call_expr.callee.is_member_expression() => { - let member_expr = call_expr.callee.as_member_expression().unwrap(); - !member_expr.is_specific_member_access("React", "createClass") - } + callee if callee.is_member_expression() => !callee + .as_member_expression() + .unwrap() + .is_specific_member_access("React", "createClass"), Expression::Identifier(ident) => ident.name != "createReactClass", _ => true, } {