Skip to content

Commit

Permalink
fix(transformer/arrow-functions): reaches unreachable when `<this.f…
Browse files Browse the repository at this point in the history
…oo>` is inside an arrow function (#5356)

Fixes: #5353 (comment)
  • Loading branch information
Dunqing committed Sep 2, 2024
1 parent 01cc2ce commit 94ff94c
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 17 deletions.
39 changes: 24 additions & 15 deletions crates/oxc_transformer/src/es2015/arrow_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,22 +137,31 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
return;
}

let ident = match name {
JSXElementName::Identifier(ident) => ident,
JSXElementName::MemberExpression(member_expr) => {
member_expr.get_object_identifier_mut()
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 <this.foo></this.foo> to <_this.foo></_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 mut new_ident = self.get_this_name(ctx).create_read_reference(ctx);
new_ident.span = ident.span;
*node = ctx.ast.jsx_member_expression_object_from_identifier_reference(new_ident);
}
JSXElementName::IdentifierReference(_) | JSXElementName::NamespacedName(_) => return,
};
if ident.name == "this" {
// We can't produce a proper identifier with a `ReferenceId` because `JSXIdentifier`
// lacks that field. https://github.com/oxc-project/oxc/issues/3528
// So generate a reference and just use its name.
// If JSX transform is enabled, that transform runs before this and will have converted
// this to a proper `ThisExpression`, and this visitor won't run.
// So only a problem if JSX transform is disabled.
let new_ident = self.get_this_name(ctx).create_read_reference(ctx);
ident.name = new_ident.name;
}
}

Expand Down
10 changes: 10 additions & 0 deletions crates/oxc_transformer/src/es2015/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ impl<'a> Traverse<'a> for ES2015<'a> {
}
}

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);
Expand Down
8 changes: 8 additions & 0 deletions crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,14 @@ impl<'a> Traverse<'a> for Transformer<'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>,
Expand Down
11 changes: 9 additions & 2 deletions tasks/transform_conformance/oxc.snap.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
commit: 3bcfee23

Passed: 10/38
Passed: 10/39

# All Passed:
* babel-plugin-transform-optional-catch-binding
* babel-plugin-transform-arrow-functions


# babel-plugin-transform-nullish-coalescing-operator (0/1)
Expand All @@ -15,6 +14,14 @@ Passed: 10/38



# babel-plugin-transform-arrow-functions (1/2)
* with-this-member-expression/input.jsx
x Unresolved references mismatch:
| after transform: ["this"]
| rebuilt : []



# babel-plugin-transform-typescript (2/8)
* class-property-definition/input.ts
x Unresolved references mismatch:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
() => {
<this.foo></this.foo>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var _this = this;
(function() {
<_this.foo></_this.foo>;
});

0 comments on commit 94ff94c

Please sign in to comment.