mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
fix(transformer): arrow function transform handle this in arrow function in class static block (#5848)
Class static blocks also hold a `this` binding.
This commit is contained in:
parent
bcdbba3981
commit
49ee1dcff2
6 changed files with 57 additions and 4 deletions
|
|
@ -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);
|
||||
|
|
@ -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>,
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
commit: 3bcfee23
|
||||
|
||||
Passed: 43/53
|
||||
Passed: 44/54
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-nullish-coalescing-operator
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
let f;
|
||||
class C {
|
||||
static {
|
||||
f = () => this;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
let f;
|
||||
class C {
|
||||
static {
|
||||
var _this = this;
|
||||
f = function() {
|
||||
return _this;
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue