fix(transformer): correctly jsx-self inside arrow-function (#3224)

This commit is contained in:
Dunqing 2024-05-11 08:48:18 +08:00 committed by GitHub
parent 20f643063e
commit 6ac8a8479e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 44 additions and 17 deletions

View file

@ -31,9 +31,10 @@ pub struct ArrowFunctions<'a> {
_options: ArrowFunctionsOptions, _options: ArrowFunctionsOptions,
uid: usize, uid: usize,
has_this: bool, has_this: bool,
can_insert: bool,
/// Stack to keep track of whether we are inside an arrow function or not. /// Stack to keep track of whether we are inside an arrow function or not.
stacks: std::vec::Vec<bool>, stacks: std::vec::Vec<bool>,
// var _this = this;
this_statements: std::vec::Vec<Option<Statement<'a>>>,
} }
impl<'a> ArrowFunctions<'a> { impl<'a> ArrowFunctions<'a> {
@ -43,8 +44,8 @@ impl<'a> ArrowFunctions<'a> {
_options: options, _options: options,
uid: 0, uid: 0,
has_this: false, has_this: false,
can_insert: false,
stacks: vec![], stacks: vec![],
this_statements: vec![],
} }
} }
@ -64,8 +65,28 @@ impl<'a> ArrowFunctions<'a> {
} }
} }
pub fn transform_statements(&mut self, _stmts: &mut Vec<'a, Statement<'a>>) {
self.this_statements.push(None);
}
/// ```ts
/// function a(){
/// () => console.log(this);
/// }
/// // to
/// function a(){
/// var _this = this;
/// (function() { return console.log(_this); });
/// }
/// ```
/// Insert the var _this = this; statement outside the arrow function
pub fn transform_statements_on_exit(&mut self, stmts: &mut Vec<'a, Statement<'a>>) { pub fn transform_statements_on_exit(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
if self.can_insert { // Insert the var _this = this;
if let Some(Some(stmt)) = self.this_statements.pop() {
stmts.insert(0, stmt);
}
if self.has_this {
let binding_pattern = self.ctx.ast.binding_pattern( let binding_pattern = self.ctx.ast.binding_pattern(
self.ctx self.ctx
.ast .ast
@ -88,13 +109,10 @@ impl<'a> ArrowFunctions<'a> {
self.ctx.ast.new_vec_single(variable_declarator), self.ctx.ast.new_vec_single(variable_declarator),
Modifiers::empty(), Modifiers::empty(),
); );
stmts.insert(0, Statement::VariableDeclaration(stmt));
self.can_insert = false;
}
// Insert to parent block statement let stmt = Statement::VariableDeclaration(stmt);
if self.has_this { // store it, insert it in last statements
self.can_insert = true; self.this_statements.last_mut().unwrap().replace(stmt);
self.has_this = false; self.has_this = false;
} }
} }
@ -199,13 +217,13 @@ impl<'a> ArrowFunctions<'a> {
pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>) { pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>) {
if let Declaration::FunctionDeclaration(_) = decl { if let Declaration::FunctionDeclaration(_) = decl {
self.stacks.push(true); self.stacks.push(false);
} }
} }
pub fn transform_declaration_on_exit(&mut self, decl: &mut Declaration<'a>) { pub fn transform_declaration_on_exit(&mut self, decl: &mut Declaration<'a>) {
if let Declaration::FunctionDeclaration(_) = decl { if let Declaration::FunctionDeclaration(_) = decl {
self.stacks.push(false); self.stacks.pop();
} }
} }
@ -214,6 +232,6 @@ impl<'a> ArrowFunctions<'a> {
} }
pub fn transform_class_on_exit(&mut self, _class: &mut Class<'a>) { pub fn transform_class_on_exit(&mut self, _class: &mut Class<'a>) {
self.stacks.push(false); self.stacks.pop();
} }
} }

View file

@ -31,7 +31,13 @@ impl<'a> ES2015<'a> {
} }
} }
pub fn transform_statements_on_exit(&mut self, stmts: &mut Vec<'a, Statement<'a>>) { pub fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.transform_statements(stmts);
}
}
pub fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
if self.options.arrow_function.is_some() { if self.options.arrow_function.is_some() {
self.arrow_functions.transform_statements_on_exit(stmts); self.arrow_functions.transform_statements_on_exit(stmts);
} }

View file

@ -188,9 +188,13 @@ impl<'a> Traverse<'a> for Transformer<'a> {
self.x0_typescript.transform_property_definition(def); self.x0_typescript.transform_property_definition(def);
} }
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, _ctx: &TraverseCtx<'a>) {
self.x3_es2015.enter_statements(stmts);
}
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, _ctx: &TraverseCtx<'a>) { fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_statements_on_exit(stmts); self.x0_typescript.transform_statements_on_exit(stmts);
self.x3_es2015.transform_statements_on_exit(stmts); self.x3_es2015.exit_statements(stmts);
} }
fn enter_tagged_template_expression( fn enter_tagged_template_expression(

View file

@ -1,4 +1,4 @@
Passed: 303/362 Passed: 304/362
# All Passed: # All Passed:
* babel-preset-react * babel-preset-react
@ -67,8 +67,7 @@ Passed: 303/362
* autoImport/complicated-scope-module/input.js * autoImport/complicated-scope-module/input.js
* react-automatic/should-throw-when-filter-is-specified/input.js * react-automatic/should-throw-when-filter-is-specified/input.js
# babel-plugin-transform-react-jsx-self (1/3) # babel-plugin-transform-react-jsx-self (2/3)
* react-source/arrow-function/input.js
* react-source/disable-with-super/input.js * react-source/disable-with-super/input.js
# babel-plugin-transform-react-jsx-development (8/12) # babel-plugin-transform-react-jsx-development (8/12)