Skip to content

Commit

Permalink
fix(transformer): arrow function transform handle this in arrow fun…
Browse files Browse the repository at this point in the history
…ction in class static block
  • Loading branch information
overlookmotel committed Sep 18, 2024
1 parent 3120c6c commit d538c38
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 4 deletions.
24 changes: 21 additions & 3 deletions crates/oxc_transformer/src/es2015/arrow_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ impl<'a> ArrowFunctions<'a> {
}

impl<'a> Traverse<'a> for ArrowFunctions<'a> {
// Note: No visitors for `TSModuleBlock` because `this` is not legal in TS module blocks.
// <https://www.typescriptlang.org/play/?#code/HYQwtgpgzgDiDGEAEAxA9mpBvAsAKCSXjWCgBckANJAXiQAoBKWgPiTIAsBLKAbnwC++fGDQATAK4AbZACEQAJ2z5CxUhWp0mrdtz6D8QA>

/// Insert `var _this = this;` for the global scope.
fn exit_program(&mut self, program: &mut Program<'a>, _ctx: &mut TraverseCtx<'a>) {
debug_assert!(self.inside_arrow_function_stack.len() == 1);
Expand Down Expand Up @@ -168,6 +171,18 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
self.inside_arrow_function_stack.pop().unwrap();
}

fn enter_static_block(&mut self, _block: &mut StaticBlock<'a>, _ctx: &mut TraverseCtx<'a>) {
self.this_var_stack.push(None);
// No need to push to `inside_arrow_function_stack` because `enter_class` already pushed `false`
}

fn exit_static_block(&mut self, block: &mut StaticBlock<'a>, _ctx: &mut TraverseCtx<'a>) {
let this_var = self.this_var_stack.pop().unwrap();
if let Some(this_var) = this_var {
self.insert_this_var_statement_at_the_top_of_statements(&mut block.body, &this_var);
}
}

fn enter_jsx_element_name(
&mut self,
element_name: &mut JSXElementName<'a>,
Expand Down Expand Up @@ -255,13 +270,16 @@ impl<'a> ArrowFunctions<'a> {
let target_scope_id = ctx
.scopes()
.ancestors(ctx.current_scope_id())
// We're inside arrow function, so parent scope can't be what we're looking for.
// It's either the arrow function, or a block nested within arrow function.
.skip(1)
.find(|&scope_id| {
let scope_flags = ctx.scopes().get_flags(scope_id);
// Function but not arrow function
scope_flags & (ScopeFlags::Function | ScopeFlags::Arrow) == ScopeFlags::Function
scope_flags.intersects(
ScopeFlags::Function | ScopeFlags::Top | ScopeFlags::ClassStaticBlock,
) && !scope_flags.contains(ScopeFlags::Arrow)
})
.unwrap_or(ctx.scopes().root_scope_id());
.unwrap();

this_var.replace(BoundIdentifier::new_uid(
"this",
Expand Down
12 changes: 12 additions & 0 deletions crates/oxc_transformer/src/es2015/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ impl<'a> Traverse<'a> for ES2015<'a> {
}
}

fn enter_static_block(&mut self, block: &mut StaticBlock<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.enter_static_block(block, ctx);
}
}

fn exit_static_block(&mut self, block: &mut StaticBlock<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.exit_static_block(block, ctx);
}
}

fn enter_variable_declarator(
&mut self,
node: &mut VariableDeclarator<'a>,
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 @@ -167,6 +167,14 @@ impl<'a> Traverse<'a> for Transformer<'a> {
self.x0_typescript.enter_class_body(body, ctx);
}

fn enter_static_block(&mut self, block: &mut StaticBlock<'a>, ctx: &mut TraverseCtx<'a>) {
self.x3_es2015.enter_static_block(block, ctx);
}

fn exit_static_block(&mut self, block: &mut StaticBlock<'a>, ctx: &mut TraverseCtx<'a>) {
self.x3_es2015.exit_static_block(block, ctx);
}

fn enter_ts_module_declaration(
&mut self,
decl: &mut TSModuleDeclaration<'a>,
Expand Down
2 changes: 1 addition & 1 deletion tasks/transform_conformance/oxc.snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
commit: 3bcfee23

Passed: 43/53
Passed: 44/54

# All Passed:
* babel-plugin-transform-nullish-coalescing-operator
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
let f;
class C {
static {
f = () => this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let f;
class C {
static {
var _this = this;
f = function() {
return _this;
};
}
}

0 comments on commit d538c38

Please sign in to comment.