Skip to content

Commit

Permalink
fix: support arbitrary length member expr
Browse files Browse the repository at this point in the history
  • Loading branch information
IWANABETHATGUY committed Nov 29, 2024
1 parent 47ec49f commit c650d33
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 18 deletions.
55 changes: 39 additions & 16 deletions crates/oxc_transformer/src/jsx/jsx_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Atom<'a>>,
properties: Vec<Atom<'a>>,
}

impl<'a> Pragma<'a> {
Expand All @@ -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)
}
Expand All @@ -359,15 +350,47 @@ 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 {
if self.properties.is_empty() {
Expression::Identifier(ctx.alloc(object))
} else {
let member_expr =
Self::create_arbitrary_length_member_expr(object, &self.properties, ctx).unwrap();
member_expr
}
}

/// 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(
object: IdentifierReference<'a>,
list: &[Atom<'a>],
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
match &list {
[item] => {
let ident = ctx.ast.identifier_name(SPAN, item.clone());
Some(
ctx.ast
.member_expression_static(
SPAN,
Expression::Identifier(ctx.alloc(object)),
ident,
false,
)
.into(),
)
}
[rest @ .., last_element] => {
let object = Self::create_arbitrary_length_member_expr(object, rest, ctx)?;
let property = ctx.ast.identifier_name(SPAN, last_element.clone());
Some(ctx.ast.member_expression_static(SPAN, object, property, false).into())
}
[] => None,
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions tasks/transform_conformance/snapshots/oxc.snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
commit: 54a8389f

Passed: 90/101
Passed: 91/102

# All Passed:
* babel-plugin-transform-class-static-block
Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<test></test>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"plugins": [
[
"transform-react-jsx",
{
"runtime": "classic",
"pragma": "a.b.c"
}
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a.b.c("test", null);

0 comments on commit c650d33

Please sign in to comment.