diff --git a/crates/oxc_ast/src/ast/jsx.rs b/crates/oxc_ast/src/ast/jsx.rs
index 974c446d6e38d..de5784e4a5331 100644
--- a/crates/oxc_ast/src/ast/jsx.rs
+++ b/crates/oxc_ast/src/ast/jsx.rs
@@ -173,6 +173,8 @@ pub enum JSXElementName<'a> {
NamespacedName(Box<'a, JSXNamespacedName<'a>>) = 2,
/// ``
MemberExpression(Box<'a, JSXMemberExpression<'a>>) = 3,
+ /// ``
+ ThisExpression(Box<'a, ThisExpression>) = 4,
}
/// JSX Namespaced Name
@@ -233,6 +235,7 @@ pub struct JSXMemberExpression<'a> {
pub enum JSXMemberExpressionObject<'a> {
IdentifierReference(Box<'a, IdentifierReference<'a>>) = 0,
MemberExpression(Box<'a, JSXMemberExpression<'a>>) = 1,
+ ThisExpression(Box<'a, ThisExpression>) = 2,
}
/// JSX Expression Container
diff --git a/crates/oxc_ast/src/ast_impl/jsx.rs b/crates/oxc_ast/src/ast_impl/jsx.rs
index 3ddeea6e918c8..e62f6640fa514 100644
--- a/crates/oxc_ast/src/ast_impl/jsx.rs
+++ b/crates/oxc_ast/src/ast_impl/jsx.rs
@@ -46,6 +46,7 @@ impl<'a> fmt::Display for JSXMemberExpressionObject<'a> {
match self {
Self::IdentifierReference(id) => id.fmt(f),
Self::MemberExpression(expr) => expr.fmt(f),
+ Self::ThisExpression(_) => "this".fmt(f),
}
}
}
@@ -57,6 +58,7 @@ impl<'a> fmt::Display for JSXElementName<'a> {
Self::IdentifierReference(ident) => ident.fmt(f),
Self::NamespacedName(namespaced) => namespaced.fmt(f),
Self::MemberExpression(member_expr) => member_expr.fmt(f),
+ Self::ThisExpression(_) => "this".fmt(f),
}
}
}
diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs
index 12aba6284fba8..c28960d3bc0c7 100644
--- a/crates/oxc_ast/src/generated/ast_builder.rs
+++ b/crates/oxc_ast/src/generated/ast_builder.rs
@@ -12903,6 +12903,26 @@ impl<'a> AstBuilder<'a> {
JSXElementName::MemberExpression(inner.into_in(self.allocator))
}
+ /// Build a [`JSXElementName::ThisExpression`]
+ ///
+ /// This node contains a [`ThisExpression`] that will be stored in the memory arena.
+ ///
+ /// ## Parameters
+ /// - span: The [`Span`] covering this node
+ #[inline]
+ pub fn jsx_element_name_this_expression(self, span: Span) -> JSXElementName<'a> {
+ JSXElementName::ThisExpression(self.alloc(self.this_expression(span)))
+ }
+
+ /// Convert a [`ThisExpression`] into a [`JSXElementName::ThisExpression`]
+ #[inline]
+ pub fn jsx_element_name_from_this_expression(self, inner: T) -> JSXElementName<'a>
+ where
+ T: IntoIn<'a, Box<'a, ThisExpression>>,
+ {
+ JSXElementName::ThisExpression(inner.into_in(self.allocator))
+ }
+
/// Builds a [`JSXNamespacedName`]
///
/// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_jsx_namespaced_name`] instead.
@@ -13040,6 +13060,32 @@ impl<'a> AstBuilder<'a> {
JSXMemberExpressionObject::MemberExpression(inner.into_in(self.allocator))
}
+ /// Build a [`JSXMemberExpressionObject::ThisExpression`]
+ ///
+ /// This node contains a [`ThisExpression`] that will be stored in the memory arena.
+ ///
+ /// ## Parameters
+ /// - span: The [`Span`] covering this node
+ #[inline]
+ pub fn jsx_member_expression_object_this_expression(
+ self,
+ span: Span,
+ ) -> JSXMemberExpressionObject<'a> {
+ JSXMemberExpressionObject::ThisExpression(self.alloc(self.this_expression(span)))
+ }
+
+ /// Convert a [`ThisExpression`] into a [`JSXMemberExpressionObject::ThisExpression`]
+ #[inline]
+ pub fn jsx_member_expression_object_from_this_expression(
+ self,
+ inner: T,
+ ) -> JSXMemberExpressionObject<'a>
+ where
+ T: IntoIn<'a, Box<'a, ThisExpression>>,
+ {
+ JSXMemberExpressionObject::ThisExpression(inner.into_in(self.allocator))
+ }
+
/// Builds a [`JSXExpressionContainer`]
///
/// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_jsx_expression_container`] instead.
diff --git a/crates/oxc_ast/src/generated/derive_clone_in.rs b/crates/oxc_ast/src/generated/derive_clone_in.rs
index a112c5cdac176..347458a83dd57 100644
--- a/crates/oxc_ast/src/generated/derive_clone_in.rs
+++ b/crates/oxc_ast/src/generated/derive_clone_in.rs
@@ -3507,6 +3507,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for JSXElementName<'old_alloc>
}
Self::NamespacedName(it) => JSXElementName::NamespacedName(it.clone_in(allocator)),
Self::MemberExpression(it) => JSXElementName::MemberExpression(it.clone_in(allocator)),
+ Self::ThisExpression(it) => JSXElementName::ThisExpression(it.clone_in(allocator)),
}
}
}
@@ -3543,6 +3544,9 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for JSXMemberExpressionObject<'
Self::MemberExpression(it) => {
JSXMemberExpressionObject::MemberExpression(it.clone_in(allocator))
}
+ Self::ThisExpression(it) => {
+ JSXMemberExpressionObject::ThisExpression(it.clone_in(allocator))
+ }
}
}
}
diff --git a/crates/oxc_ast/src/generated/derive_content_eq.rs b/crates/oxc_ast/src/generated/derive_content_eq.rs
index e16f730686952..2e1d5d750576c 100644
--- a/crates/oxc_ast/src/generated/derive_content_eq.rs
+++ b/crates/oxc_ast/src/generated/derive_content_eq.rs
@@ -3555,6 +3555,9 @@ impl<'a> ContentEq for JSXElementName<'a> {
Self::MemberExpression(it) => {
matches!(other, Self::MemberExpression(other) if it.content_eq(other))
}
+ Self::ThisExpression(it) => {
+ matches!(other, Self::ThisExpression(other) if it.content_eq(other))
+ }
}
}
}
@@ -3580,6 +3583,9 @@ impl<'a> ContentEq for JSXMemberExpressionObject<'a> {
Self::MemberExpression(it) => {
matches!(other, Self::MemberExpression(other) if it.content_eq(other))
}
+ Self::ThisExpression(it) => {
+ matches!(other, Self::ThisExpression(other) if it.content_eq(other))
+ }
}
}
}
diff --git a/crates/oxc_ast/src/generated/derive_get_span.rs b/crates/oxc_ast/src/generated/derive_get_span.rs
index 38cde1c2ec246..5eccf7a364e27 100644
--- a/crates/oxc_ast/src/generated/derive_get_span.rs
+++ b/crates/oxc_ast/src/generated/derive_get_span.rs
@@ -2042,6 +2042,7 @@ impl<'a> GetSpan for JSXElementName<'a> {
Self::IdentifierReference(it) => it.span(),
Self::NamespacedName(it) => it.span(),
Self::MemberExpression(it) => it.span(),
+ Self::ThisExpression(it) => it.span(),
}
}
}
@@ -2065,6 +2066,7 @@ impl<'a> GetSpan for JSXMemberExpressionObject<'a> {
match self {
Self::IdentifierReference(it) => it.span(),
Self::MemberExpression(it) => it.span(),
+ Self::ThisExpression(it) => it.span(),
}
}
}
diff --git a/crates/oxc_ast/src/generated/derive_get_span_mut.rs b/crates/oxc_ast/src/generated/derive_get_span_mut.rs
index a3c4f418cc03c..81783b9662250 100644
--- a/crates/oxc_ast/src/generated/derive_get_span_mut.rs
+++ b/crates/oxc_ast/src/generated/derive_get_span_mut.rs
@@ -2042,6 +2042,7 @@ impl<'a> GetSpanMut for JSXElementName<'a> {
Self::IdentifierReference(it) => it.span_mut(),
Self::NamespacedName(it) => it.span_mut(),
Self::MemberExpression(it) => it.span_mut(),
+ Self::ThisExpression(it) => it.span_mut(),
}
}
}
@@ -2065,6 +2066,7 @@ impl<'a> GetSpanMut for JSXMemberExpressionObject<'a> {
match self {
Self::IdentifierReference(it) => it.span_mut(),
Self::MemberExpression(it) => it.span_mut(),
+ Self::ThisExpression(it) => it.span_mut(),
}
}
}
diff --git a/crates/oxc_ast/src/generated/visit.rs b/crates/oxc_ast/src/generated/visit.rs
index 0bd609e7997fc..90308a90e1ffe 100644
--- a/crates/oxc_ast/src/generated/visit.rs
+++ b/crates/oxc_ast/src/generated/visit.rs
@@ -3300,6 +3300,7 @@ pub mod walk {
JSXElementName::IdentifierReference(it) => visitor.visit_identifier_reference(it),
JSXElementName::NamespacedName(it) => visitor.visit_jsx_namespaced_name(it),
JSXElementName::MemberExpression(it) => visitor.visit_jsx_member_expression(it),
+ JSXElementName::ThisExpression(it) => visitor.visit_this_expression(it),
}
visitor.leave_node(kind);
}
@@ -3346,6 +3347,7 @@ pub mod walk {
JSXMemberExpressionObject::MemberExpression(it) => {
visitor.visit_jsx_member_expression(it)
}
+ JSXMemberExpressionObject::ThisExpression(it) => visitor.visit_this_expression(it),
}
visitor.leave_node(kind);
}
diff --git a/crates/oxc_ast/src/generated/visit_mut.rs b/crates/oxc_ast/src/generated/visit_mut.rs
index d7ce7cfd4c307..eb5460f88fbc4 100644
--- a/crates/oxc_ast/src/generated/visit_mut.rs
+++ b/crates/oxc_ast/src/generated/visit_mut.rs
@@ -3464,6 +3464,7 @@ pub mod walk_mut {
JSXElementName::IdentifierReference(it) => visitor.visit_identifier_reference(it),
JSXElementName::NamespacedName(it) => visitor.visit_jsx_namespaced_name(it),
JSXElementName::MemberExpression(it) => visitor.visit_jsx_member_expression(it),
+ JSXElementName::ThisExpression(it) => visitor.visit_this_expression(it),
}
visitor.leave_node(kind);
}
@@ -3513,6 +3514,7 @@ pub mod walk_mut {
JSXMemberExpressionObject::MemberExpression(it) => {
visitor.visit_jsx_member_expression(it)
}
+ JSXMemberExpressionObject::ThisExpression(it) => visitor.visit_this_expression(it),
}
visitor.leave_node(kind);
}
diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs
index 0647a09c74dba..80e887818ec00 100644
--- a/crates/oxc_codegen/src/gen.rs
+++ b/crates/oxc_codegen/src/gen.rs
@@ -2249,6 +2249,7 @@ impl<'a> Gen for JSXMemberExpressionObject<'a> {
match self {
Self::IdentifierReference(ident) => ident.gen(p, ctx),
Self::MemberExpression(member_expr) => member_expr.gen(p, ctx),
+ Self::ThisExpression(expr) => expr.gen(p, ctx),
}
}
}
@@ -2268,6 +2269,7 @@ impl<'a> Gen for JSXElementName<'a> {
Self::IdentifierReference(identifier) => identifier.gen(p, ctx),
Self::NamespacedName(namespaced_name) => namespaced_name.gen(p, ctx),
Self::MemberExpression(member_expr) => member_expr.gen(p, ctx),
+ Self::ThisExpression(expr) => expr.gen(p, ctx),
}
}
}
diff --git a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs
index 0e95498f2ed6f..f841ab58f4e52 100644
--- a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs
+++ b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs
@@ -35,16 +35,19 @@ declare_oxc_lint!(
fn get_resolvable_ident<'a>(node: &'a JSXElementName<'a>) -> Option<&'a IdentifierReference> {
match node {
- JSXElementName::Identifier(_) | JSXElementName::NamespacedName(_) => None,
+ JSXElementName::Identifier(_)
+ | JSXElementName::NamespacedName(_)
+ | JSXElementName::ThisExpression(_) => None,
JSXElementName::IdentifierReference(ref ident) => Some(ident),
- JSXElementName::MemberExpression(expr) => Some(get_member_ident(expr)),
+ JSXElementName::MemberExpression(expr) => get_member_ident(expr),
}
}
-fn get_member_ident<'a>(mut expr: &'a JSXMemberExpression<'a>) -> &'a IdentifierReference {
+fn get_member_ident<'a>(mut expr: &'a JSXMemberExpression<'a>) -> Option<&'a IdentifierReference> {
loop {
match &expr.object {
- JSXMemberExpressionObject::IdentifierReference(ident) => return ident,
+ JSXMemberExpressionObject::IdentifierReference(ident) => return Some(ident),
+ JSXMemberExpressionObject::ThisExpression(_) => return None,
JSXMemberExpressionObject::MemberExpression(next_expr) => {
expr = next_expr;
}
@@ -61,10 +64,6 @@ impl Rule for JsxNoUndef {
return;
}
let name = ident.name.as_str();
- // TODO: Remove this check once we have `JSXMemberExpressionObject::ThisExpression`
- if name == "this" {
- return;
- }
if ctx.globals().is_enabled(name) {
return;
}
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 93abdea4bc8ca..700b44b37d8aa 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
@@ -172,7 +172,9 @@ fn is_jsx_fragment(elem: &JSXOpeningElement) -> bool {
false
}
}
- JSXElementName::NamespacedName(_) | JSXElementName::Identifier(_) => false,
+ JSXElementName::NamespacedName(_)
+ | JSXElementName::Identifier(_)
+ | JSXElementName::ThisExpression(_) => false,
}
}
diff --git a/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/listener_map.rs b/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/listener_map.rs
index ce20e455bce0e..826aadfff37c1 100644
--- a/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/listener_map.rs
+++ b/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/listener_map.rs
@@ -791,6 +791,7 @@ impl<'a> ListenerMap for JSXElementName<'a> {
Self::Identifier(_) | Self::NamespacedName(_) => {}
Self::IdentifierReference(ident) => ident.report_effects_when_called(options),
Self::MemberExpression(member) => member.report_effects_when_called(options),
+ Self::ThisExpression(expr) => expr.report_effects_when_called(options),
}
}
}
@@ -806,6 +807,7 @@ impl<'a> ListenerMap for JSXMemberExpressionObject<'a> {
match self {
Self::IdentifierReference(ident) => ident.report_effects_when_called(options),
Self::MemberExpression(member) => member.report_effects_when_called(options),
+ Self::ThisExpression(expr) => expr.report_effects_when_called(options),
}
}
}
diff --git a/crates/oxc_parser/src/jsx/mod.rs b/crates/oxc_parser/src/jsx/mod.rs
index c666686a0511d..62cd1bccae1f5 100644
--- a/crates/oxc_parser/src/jsx/mod.rs
+++ b/crates/oxc_parser/src/jsx/mod.rs
@@ -171,6 +171,10 @@ impl<'a> ParserImpl<'a> {
let element_name = if is_reference {
let identifier = self.ast.identifier_reference(identifier.span, identifier.name);
JSXElementName::IdentifierReference(self.ast.alloc(identifier))
+ } else if name == "this" {
+ JSXElementName::ThisExpression(
+ self.ast.alloc(self.ast.this_expression(identifier.span)),
+ )
} else {
JSXElementName::Identifier(self.ast.alloc(identifier))
};
@@ -185,9 +189,15 @@ impl<'a> ParserImpl<'a> {
span: Span,
object: JSXIdentifier<'a>,
) -> Result>> {
+ let mut object = if object.name == "this" {
+ let object = self.ast.this_expression(object.span);
+ JSXMemberExpressionObject::ThisExpression(self.ast.alloc(object))
+ } else {
+ let object = self.ast.identifier_reference(object.span, object.name);
+ JSXMemberExpressionObject::IdentifierReference(self.ast.alloc(object))
+ };
+
let mut span = span;
- let object = self.ast.identifier_reference(object.span, object.name);
- let mut object = JSXMemberExpressionObject::IdentifierReference(self.ast.alloc(object));
let mut property = None;
while self.eat(Kind::Dot) && !self.at(Kind::Eof) {
@@ -434,6 +444,7 @@ impl<'a> ParserImpl<'a> {
(JSXElementName::MemberExpression(lhs), JSXElementName::MemberExpression(rhs)) => {
Self::jsx_member_expression_eq(lhs, rhs)
}
+ (JSXElementName::ThisExpression(_), JSXElementName::ThisExpression(_)) => true,
_ => false,
}
}
@@ -454,6 +465,10 @@ impl<'a> ParserImpl<'a> {
JSXMemberExpressionObject::MemberExpression(lhs),
JSXMemberExpressionObject::MemberExpression(rhs),
) => Self::jsx_member_expression_eq(lhs, rhs),
+ (
+ JSXMemberExpressionObject::ThisExpression(_),
+ JSXMemberExpressionObject::ThisExpression(_),
+ ) => true,
_ => false,
}
}
diff --git a/crates/oxc_transformer/src/es2015/arrow_functions.rs b/crates/oxc_transformer/src/es2015/arrow_functions.rs
index 3b54f4a50986b..5249b6c9fedbd 100644
--- a/crates/oxc_transformer/src/es2015/arrow_functions.rs
+++ b/crates/oxc_transformer/src/es2015/arrow_functions.rs
@@ -131,40 +131,6 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
self.insert_this_var_statement_at_the_top_of_statements(&mut body.statements);
}
- /// Change to <_this>, and mark it as found
- fn enter_jsx_element_name(&mut self, name: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
- if !self.is_inside_arrow_function() {
- return;
- }
-
- if let JSXElementName::Identifier(ident) = name {
- if ident.name == "this" {
- let mut new_ident = self.get_this_name(ctx).create_read_reference(ctx);
- new_ident.span = ident.span;
- *name = self.ctx.ast.jsx_element_name_from_identifier_reference(new_ident);
- }
- }
- }
-
- /// Change to <_this.foo>, and mark it as found
- fn enter_jsx_member_expression_object(
- &mut self,
- node: &mut JSXMemberExpressionObject<'a>,
- ctx: &mut TraverseCtx<'a>,
- ) {
- if !self.is_inside_arrow_function() {
- return;
- }
-
- if let JSXMemberExpressionObject::IdentifierReference(ident) = node {
- if ident.name == "this" {
- let new_ident = self.get_this_name(ctx).create_read_reference(ctx);
- ident.name = new_ident.name;
- ident.reference_id = new_ident.reference_id;
- }
- }
- }
-
fn enter_expression(&mut self, expr: &mut Expression<'a>, _ctx: &mut TraverseCtx<'a>) {
match expr {
Expression::ArrowFunctionExpression(_) => {
diff --git a/crates/oxc_transformer/src/es2015/mod.rs b/crates/oxc_transformer/src/es2015/mod.rs
index 3905e064113b9..c094901bc6888 100644
--- a/crates/oxc_transformer/src/es2015/mod.rs
+++ b/crates/oxc_transformer/src/es2015/mod.rs
@@ -51,22 +51,6 @@ impl<'a> Traverse<'a> for ES2015<'a> {
}
}
- fn enter_jsx_element_name(&mut self, elem: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
- if self.options.arrow_function.is_some() {
- self.arrow_functions.enter_jsx_element_name(elem, ctx);
- }
- }
-
- fn enter_jsx_member_expression_object(
- &mut self,
- node: &mut JSXMemberExpressionObject<'a>,
- ctx: &mut TraverseCtx<'a>,
- ) {
- if self.options.arrow_function.is_some() {
- self.arrow_functions.enter_jsx_member_expression_object(node, ctx);
- }
- }
-
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.enter_declaration(decl, ctx);
diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs
index 2e2a540d7d094..2eea9bae4d1fd 100644
--- a/crates/oxc_transformer/src/lib.rs
+++ b/crates/oxc_transformer/src/lib.rs
@@ -235,18 +235,6 @@ impl<'a> Traverse<'a> for Transformer<'a> {
self.x1_react.transform_jsx_opening_element(elem, ctx);
}
- fn enter_jsx_element_name(&mut self, elem: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
- self.x3_es2015.enter_jsx_element_name(elem, ctx);
- }
-
- fn enter_jsx_member_expression_object(
- &mut self,
- node: &mut JSXMemberExpressionObject<'a>,
- ctx: &mut TraverseCtx<'a>,
- ) {
- self.x3_es2015.enter_jsx_member_expression_object(node, ctx);
- }
-
fn enter_method_definition(
&mut self,
def: &mut MethodDefinition<'a>,
diff --git a/crates/oxc_transformer/src/react/jsx.rs b/crates/oxc_transformer/src/react/jsx.rs
index 5774c82c1307f..12c549bc04d33 100644
--- a/crates/oxc_transformer/src/react/jsx.rs
+++ b/crates/oxc_transformer/src/react/jsx.rs
@@ -700,11 +700,7 @@ impl<'a> ReactJsx<'a> {
fn transform_element_name(&self, name: &JSXElementName<'a>) -> Expression<'a> {
match name {
JSXElementName::Identifier(ident) => {
- if ident.name == "this" {
- self.ast().expression_this(ident.span)
- } else {
- self.ast().expression_string_literal(ident.span, &ident.name)
- }
+ self.ast().expression_string_literal(ident.span, ident.name.clone())
}
JSXElementName::IdentifierReference(ident) => {
self.ast().expression_from_identifier_reference(ident.as_ref().clone())
@@ -718,6 +714,7 @@ impl<'a> ReactJsx<'a> {
}
self.ast().expression_string_literal(namespaced.span, namespaced.to_string())
}
+ JSXElementName::ThisExpression(expr) => self.ast().expression_this(expr.span),
}
}
@@ -775,15 +772,14 @@ impl<'a> ReactJsx<'a> {
fn transform_jsx_member_expression(&self, expr: &JSXMemberExpression<'a>) -> Expression<'a> {
let object = match &expr.object {
JSXMemberExpressionObject::IdentifierReference(ident) => {
- if ident.name == "this" {
- self.ast().expression_this(ident.span)
- } else {
- self.ast().expression_from_identifier_reference(ident.as_ref().clone())
- }
+ self.ast().expression_from_identifier_reference(ident.as_ref().clone())
}
JSXMemberExpressionObject::MemberExpression(expr) => {
self.transform_jsx_member_expression(expr)
}
+ JSXMemberExpressionObject::ThisExpression(expr) => {
+ self.ast().expression_this(expr.span)
+ }
};
let property = IdentifierName::new(expr.property.span, expr.property.name.clone());
self.ast().member_expression_static(expr.span, object, property, false).into()
diff --git a/crates/oxc_traverse/src/context/ast_operations/gather_node_parts.rs b/crates/oxc_traverse/src/context/ast_operations/gather_node_parts.rs
index 8c50d4aaa1e4a..bf528effbb126 100644
--- a/crates/oxc_traverse/src/context/ast_operations/gather_node_parts.rs
+++ b/crates/oxc_traverse/src/context/ast_operations/gather_node_parts.rs
@@ -464,6 +464,7 @@ impl<'a> GatherNodeParts<'a> for JSXElementName<'a> {
JSXElementName::IdentifierReference(ident) => ident.gather(f),
JSXElementName::NamespacedName(ns) => ns.gather(f),
JSXElementName::MemberExpression(expr) => expr.gather(f),
+ JSXElementName::ThisExpression(expr) => expr.gather(f),
}
}
}
@@ -487,6 +488,7 @@ impl<'a> GatherNodeParts<'a> for JSXMemberExpressionObject<'a> {
match self {
JSXMemberExpressionObject::IdentifierReference(ident) => ident.gather(f),
JSXMemberExpressionObject::MemberExpression(expr) => expr.gather(f),
+ JSXMemberExpressionObject::ThisExpression(expr) => expr.gather(f),
}
}
}
diff --git a/crates/oxc_traverse/src/generated/walk.rs b/crates/oxc_traverse/src/generated/walk.rs
index 7846d7a4dd4d9..e60a38d3b8b9c 100644
--- a/crates/oxc_traverse/src/generated/walk.rs
+++ b/crates/oxc_traverse/src/generated/walk.rs
@@ -3268,6 +3268,9 @@ pub(crate) unsafe fn walk_jsx_element_name<'a, Tr: Traverse<'a>>(
JSXElementName::MemberExpression(node) => {
walk_jsx_member_expression(traverser, (&mut **node) as *mut _, ctx)
}
+ JSXElementName::ThisExpression(node) => {
+ walk_this_expression(traverser, (&mut **node) as *mut _, ctx)
+ }
}
traverser.exit_jsx_element_name(&mut *node, ctx);
}
@@ -3335,6 +3338,9 @@ pub(crate) unsafe fn walk_jsx_member_expression_object<'a, Tr: Traverse<'a>>(
JSXMemberExpressionObject::MemberExpression(node) => {
walk_jsx_member_expression(traverser, (&mut **node) as *mut _, ctx)
}
+ JSXMemberExpressionObject::ThisExpression(node) => {
+ walk_this_expression(traverser, (&mut **node) as *mut _, ctx)
+ }
}
traverser.exit_jsx_member_expression_object(&mut *node, ctx);
}
diff --git a/tasks/coverage/semantic_typescript.snap b/tasks/coverage/semantic_typescript.snap
index 0d3dc76419464..f53e398365eed 100644
--- a/tasks/coverage/semantic_typescript.snap
+++ b/tasks/coverage/semantic_typescript.snap
@@ -2,7 +2,7 @@ commit: a709f989
semantic_typescript Summary:
AST Parsed : 6479/6479 (100.00%)
-Positive Passed: 3256/6479 (50.25%)
+Positive Passed: 3259/6479 (50.30%)
tasks/coverage/typescript/tests/cases/compiler/2dArrays.ts
semantic error: Symbol reference IDs mismatch:
after transform: SymbolId(0): [ReferenceId(1)]
@@ -40687,11 +40687,6 @@ Symbol reference IDs mismatch:
after transform: SymbolId(3): [ReferenceId(0), ReferenceId(1)]
rebuilt : SymbolId(2): [ReferenceId(2)]
-tasks/coverage/typescript/tests/cases/conformance/jsx/tsxDynamicTagName5.tsx
-semantic error: Unresolved references mismatch:
-after transform: ["this"]
-rebuilt : []
-
tasks/coverage/typescript/tests/cases/conformance/jsx/tsxDynamicTagName6.tsx
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["JSX", "_jsxFileName", "_reactJsxRuntime", "foo", "t"]
@@ -40700,16 +40695,6 @@ Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1)]
rebuilt : ScopeId(0): []
-tasks/coverage/typescript/tests/cases/conformance/jsx/tsxDynamicTagName8.tsx
-semantic error: Unresolved references mismatch:
-after transform: ["this"]
-rebuilt : []
-
-tasks/coverage/typescript/tests/cases/conformance/jsx/tsxDynamicTagName9.tsx
-semantic error: Unresolved references mismatch:
-after transform: ["this"]
-rebuilt : []
-
tasks/coverage/typescript/tests/cases/conformance/jsx/tsxElementResolution.tsx
semantic error: Missing SymbolId: Dotted
Missing SymbolId: _Dotted
diff --git a/tasks/transform_conformance/babel.snap.md b/tasks/transform_conformance/babel.snap.md
index 1124f85e6b726..a88d5cfc285cc 100644
--- a/tasks/transform_conformance/babel.snap.md
+++ b/tasks/transform_conformance/babel.snap.md
@@ -1,6 +1,6 @@
commit: 3bcfee23
-Passed: 317/1021
+Passed: 321/1021
# All Passed:
* babel-plugin-transform-optional-catch-binding
@@ -4906,13 +4906,7 @@ TS(18010)
-# babel-plugin-transform-react-jsx (119/144)
-* react/arrow-functions/input.js
- x Unresolved references mismatch:
- | after transform: ["React", "this"]
- | rebuilt : ["React"]
-
-
+# babel-plugin-transform-react-jsx (123/144)
* react/dont-coerce-expression-containers/input.js
x Unresolved reference IDs mismatch for "Text":
| after transform: [ReferenceId(0), ReferenceId(1)]
@@ -4980,24 +4974,12 @@ TS(18010)
`----
-* react/this-tag-name/input.js
- x Unresolved references mismatch:
- | after transform: ["React", "this"]
- | rebuilt : ["React"]
-
-
* react/weird-symbols/input.js
x Unresolved reference IDs mismatch for "Text":
| after transform: [ReferenceId(1), ReferenceId(2)]
| rebuilt : [ReferenceId(2)]
-* react-automatic/arrow-functions/input.js
- x Unresolved references mismatch:
- | after transform: ["this"]
- | rebuilt : []
-
-
* react-automatic/does-not-add-source-self-automatic/input.mjs
transform-react-jsx: unknown field `autoImport`, expected one of `runtime`, `development`, `throwIfNamespace`, `pure`, `importSource`, `pragma`, `pragmaFrag`, `useBuiltIns`, `useSpread`, `refresh`
@@ -5056,12 +5038,6 @@ transform-react-jsx: unknown field `autoImport`, expected one of `runtime`, `dev
`----
-* react-automatic/this-tag-name/input.js
- x Unresolved references mismatch:
- | after transform: ["this"]
- | rebuilt : []
-
-
* react-automatic/weird-symbols/input.js
x Unresolved reference IDs mismatch for "Text":
| after transform: [ReferenceId(1), ReferenceId(2)]
diff --git a/tasks/transform_conformance/oxc.snap.md b/tasks/transform_conformance/oxc.snap.md
index 6da35ab993657..3d9ff3baed752 100644
--- a/tasks/transform_conformance/oxc.snap.md
+++ b/tasks/transform_conformance/oxc.snap.md
@@ -10,9 +10,6 @@ Passed: 13/41
# babel-plugin-transform-arrow-functions (1/2)
* with-this-member-expression/input.jsx
- x Unresolved references mismatch:
- | after transform: ["this"]
- | rebuilt : []