diff --git a/crates/oxc_linter/src/rules/react/jsx_fragments.rs b/crates/oxc_linter/src/rules/react/jsx_fragments.rs index 9ef388139ade1..4a1224d6c967b 100644 --- a/crates/oxc_linter/src/rules/react/jsx_fragments.rs +++ b/crates/oxc_linter/src/rules/react/jsx_fragments.rs @@ -1,13 +1,10 @@ -use oxc_ast::{ - AstKind, - ast::{JSXElementName, JSXMemberExpressionObject, JSXOpeningElement}, -}; +use oxc_ast::AstKind; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; use serde_json::Value; -use crate::{AstNode, context::LintContext, rule::Rule}; +use crate::{AstNode, context::LintContext, rule::Rule, utils::is_jsx_fragment}; fn jsx_fragments_diagnostic(span: Span, mode: FragmentMode) -> OxcDiagnostic { let msg = if mode == FragmentMode::Element { @@ -178,22 +175,6 @@ impl Rule for JsxFragments { } } -fn is_jsx_fragment(elem: &JSXOpeningElement) -> bool { - match &elem.name { - JSXElementName::IdentifierReference(ident) => ident.name == "Fragment", - JSXElementName::MemberExpression(mem_expr) => { - if let JSXMemberExpressionObject::IdentifierReference(ident) = &mem_expr.object { - ident.name == "React" && mem_expr.property.name == "Fragment" - } else { - false - } - } - JSXElementName::NamespacedName(_) - | JSXElementName::Identifier(_) - | JSXElementName::ThisExpression(_) => false, - } -} - #[test] fn test() { use crate::tester::Tester; diff --git a/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs b/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs index 1b45d00ce0540..dcbf8e234b45a 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs @@ -3,13 +3,14 @@ use crate::{ context::{ContextHost, LintContext}, fixer::{RuleFix, RuleFixer}, rule::Rule, + utils::is_jsx_fragment, }; use oxc_allocator::Vec as ArenaVec; use oxc_ast::{ AstKind, ast::{ JSXAttributeItem, JSXAttributeName, JSXChild, JSXElement, JSXElementName, JSXExpression, - JSXFragment, JSXMemberExpressionObject, JSXOpeningElement, + JSXFragment, }, }; use oxc_diagnostics::OxcDiagnostic; @@ -321,22 +322,6 @@ fn is_html_element(elem_name: &JSXElementName) -> bool { ident.name.starts_with(char::is_lowercase) } -fn is_jsx_fragment(elem: &JSXOpeningElement) -> bool { - match &elem.name { - JSXElementName::IdentifierReference(ident) => ident.name == "Fragment", - JSXElementName::MemberExpression(mem_expr) => { - if let JSXMemberExpressionObject::IdentifierReference(ident) = &mem_expr.object { - ident.name == "React" && mem_expr.property.name == "Fragment" - } else { - false - } - } - JSXElementName::NamespacedName(_) - | JSXElementName::Identifier(_) - | JSXElementName::ThisExpression(_) => false, - } -} - fn has_less_than_two_children(children: &oxc_allocator::Vec<'_, JSXChild<'_>>) -> bool { let non_padding_children = children.iter().filter(|v| is_padding_spaces(v)).collect::>(); diff --git a/crates/oxc_linter/src/utils/react.rs b/crates/oxc_linter/src/utils/react.rs index 0d78eaac4174c..793b1e7406a3d 100644 --- a/crates/oxc_linter/src/utils/react.rs +++ b/crates/oxc_linter/src/utils/react.rs @@ -333,3 +333,21 @@ pub fn is_react_function_call(call: &CallExpression, expected_call: &str) -> boo true } } + +/// Checks if a JSX opening element is a React Fragment. +/// Recognizes both `` and `` forms. +pub fn is_jsx_fragment(elem: &JSXOpeningElement) -> bool { + match &elem.name { + JSXElementName::IdentifierReference(ident) => ident.name == "Fragment", + JSXElementName::MemberExpression(mem_expr) => { + if let JSXMemberExpressionObject::IdentifierReference(ident) = &mem_expr.object { + ident.name == "React" && mem_expr.property.name == "Fragment" + } else { + false + } + } + JSXElementName::NamespacedName(_) + | JSXElementName::Identifier(_) + | JSXElementName::ThisExpression(_) => false, + } +}