fix(transformer): remove an AstBuilder::copy call for TS AssignmentTarget transform (#4984)

Add `AssignmentTarget::get_expression_mut` method and use it to remove an unsound `AstBuilder::copy` call from TS transform for `AssignmentTarget`s.
This commit is contained in:
overlookmotel 2024-08-19 21:09:08 +00:00
parent edacf936ec
commit 1365feb6b1
2 changed files with 12 additions and 4 deletions

View file

@ -626,6 +626,10 @@ impl<'a> AssignmentTarget<'a> {
pub fn get_expression(&self) -> Option<&Expression<'a>> {
self.as_simple_assignment_target().and_then(SimpleAssignmentTarget::get_expression)
}
pub fn get_expression_mut(&mut self) -> Option<&mut Expression<'a>> {
self.as_simple_assignment_target_mut().and_then(SimpleAssignmentTarget::get_expression_mut)
}
}
impl<'a> SimpleAssignmentTarget<'a> {

View file

@ -250,10 +250,14 @@ impl<'a> TypeScriptAnnotations<'a> {
}
pub fn transform_assignment_target(&mut self, target: &mut AssignmentTarget<'a>) {
if let Some(expr) = target.get_expression() {
if let Some(member_expr) = expr.get_inner_expression().as_member_expression() {
// SAFETY: `ast.copy` is unsound! We need to fix.
*target = AssignmentTarget::from(unsafe { self.ctx.ast.copy(member_expr) });
if let Some(expr) = target.get_expression_mut() {
let inner_expr = expr.get_inner_expression_mut();
if inner_expr.is_member_expression() {
let inner_expr = self.ctx.ast.move_expression(inner_expr);
let Ok(member_expr) = MemberExpression::try_from(inner_expr) else {
unreachable!();
};
*target = AssignmentTarget::from(member_expr);
}
}
}