diff --git a/crates/oxc_transformer/src/jsx/jsx_impl.rs b/crates/oxc_transformer/src/jsx/jsx_impl.rs index 30ad791538660..bc78e178334a9 100644 --- a/crates/oxc_transformer/src/jsx/jsx_impl.rs +++ b/crates/oxc_transformer/src/jsx/jsx_impl.rs @@ -315,7 +315,7 @@ fn get_import_source(jsx_runtime_importer: &str, react_importer_len: u32) -> Ato /// Pragma used in classic mode struct Pragma<'a> { object: Atom<'a>, - property: Option>, + properties: Vec>, } impl<'a> Pragma<'a> { @@ -335,19 +335,10 @@ impl<'a> Pragma<'a> { if object_name.is_empty() { return Self::invalid(default_property_name, ctx); } - - let property = match parts.next() { - Some(property_name) => { - if property_name.is_empty() || parts.next().is_some() { - return Self::invalid(default_property_name, ctx); - } - Some(ast.atom(property_name)) - } - None => None, - }; + let props = parts.map(|item| ast.atom(item)).collect(); let object = ast.atom(object_name); - Self { object, property } + Self { object, properties: props } } else { Self::default(default_property_name) } @@ -359,16 +350,27 @@ impl<'a> Pragma<'a> { } fn default(default_property_name: &'static str) -> Self { - Self { object: Atom::from("React"), property: Some(Atom::from(default_property_name)) } + Self { object: Atom::from("React"), properties: vec![Atom::from(default_property_name)] } } fn create_expression(&self, ctx: &mut TraverseCtx<'a>) -> Expression<'a> { let object = get_read_identifier_reference(SPAN, self.object.clone(), ctx); - if let Some(property) = self.property.as_ref() { - create_static_member_expression(object, property.clone(), ctx) - } else { - Expression::Identifier(ctx.alloc(object)) + Self::create_arbitrary_length_member_expr_or_ident(object, &self.properties, ctx) + } + + /// create a static member expression without caring about the referenceId, + /// this function is always used to creat a tail part of a real member expression + fn create_arbitrary_length_member_expr_or_ident( + object: IdentifierReference<'a>, + list: &[Atom<'a>], + ctx: &mut TraverseCtx<'a>, + ) -> Expression<'a> { + let mut expr = Expression::Identifier(ctx.alloc(object)); + for item in list { + let name = ctx.ast.identifier_name(SPAN, item.clone()); + expr = ctx.ast.member_expression_static(SPAN, expr, name, false).into(); } + expr } } diff --git a/tasks/transform_conformance/snapshots/oxc.snap.md b/tasks/transform_conformance/snapshots/oxc.snap.md index 96175c5e464c2..f3efa311d8cb6 100644 --- a/tasks/transform_conformance/snapshots/oxc.snap.md +++ b/tasks/transform_conformance/snapshots/oxc.snap.md @@ -1,6 +1,6 @@ commit: 54a8389f -Passed: 90/101 +Passed: 91/102 # All Passed: * babel-plugin-transform-class-static-block @@ -170,7 +170,7 @@ rebuilt : SymbolId(2): [] x Output mismatch -# babel-plugin-transform-react-jsx (31/34) +# babel-plugin-transform-react-jsx (32/35) * refresh/does-not-transform-it-because-it-is-not-used-in-the-AST/input.jsx x Output mismatch diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/input.jsx b/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/input.jsx new file mode 100644 index 0000000000000..219305e43aa35 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/input.jsx @@ -0,0 +1 @@ + diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/options.json b/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/options.json new file mode 100644 index 0000000000000..20a6d968e977d --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/options.json @@ -0,0 +1,11 @@ +{ + "plugins": [ + [ + "transform-react-jsx", + { + "runtime": "classic", + "pragma": "a.b.c" + } + ] + ] +} diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/output.js b/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/output.js new file mode 100644 index 0000000000000..75d23870df8d2 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/misc/arbitrary_length_member_expr/output.js @@ -0,0 +1 @@ +a.b.c("test", null);