From aea3e9a3f57ad983f349e63ac23c373759d58183 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Thu, 20 Jun 2024 01:33:11 +0000 Subject: [PATCH] fix(transformer): correct spans for TS annotations transform (#3782) Correct spans in output for TS annotations transform. --- crates/oxc_ast/src/ast/js.rs | 12 ++++ .../src/typescript/annotations.rs | 62 +++++++++++-------- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index a4ea0d6553b23..1e710768a874a 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -2203,6 +2203,10 @@ impl<'a> BindingPattern<'a> { pub fn get_identifier(&self) -> Option<&Atom<'a>> { self.kind.get_identifier() } + + pub fn get_binding_identifier(&self) -> Option<&BindingIdentifier<'a>> { + self.kind.get_binding_identifier() + } } #[visited_node] @@ -2232,6 +2236,14 @@ impl<'a> BindingPatternKind<'a> { } } + pub fn get_binding_identifier(&self) -> Option<&BindingIdentifier<'a>> { + match self { + Self::BindingIdentifier(ident) => Some(ident), + Self::AssignmentPattern(assign) => assign.left.get_binding_identifier(), + _ => None, + } + } + pub fn is_destructuring_pattern(&self) -> bool { match self { Self::ObjectPattern(_) | Self::ArrayPattern(_) => true, diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index da062094a7255..399e70e16cd6e 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -4,7 +4,7 @@ use std::rc::Rc; use oxc_allocator::Vec; use oxc_ast::ast::*; -use oxc_span::{Atom, SPAN}; +use oxc_span::{Atom, GetSpan, SPAN}; use oxc_syntax::operator::AssignmentOperator; use oxc_traverse::TraverseCtx; use rustc_hash::FxHashSet; @@ -61,7 +61,7 @@ impl<'a> TypeScriptAnnotations<'a> { } // Creates `this.name = name` - fn create_this_property_assignment(&self, name: &Atom<'a>) -> Statement<'a> { + fn create_this_property_assignment(&self, id: &BindingIdentifier<'a>) -> Statement<'a> { let ast = self.ctx.ast; ast.expression_statement( @@ -72,10 +72,10 @@ impl<'a> TypeScriptAnnotations<'a> { ast.simple_assignment_target_member_expression(ast.static_member( SPAN, ast.this_expression(SPAN), - ast.identifier_name(SPAN, name), + ast.identifier_name(id.span, &id.name), false, )), - ast.identifier_reference_expression(ast.identifier_reference(SPAN, name)), + ast.identifier_reference_expression(ast.identifier_reference(id.span, &id.name)), ), ) } @@ -303,7 +303,7 @@ impl<'a> TypeScriptAnnotations<'a> { if def.kind == MethodDefinitionKind::Constructor { for param in def.value.params.items.as_mut_slice() { if param.is_public() { - if let Some(id) = param.pattern.get_identifier() { + if let Some(id) = param.pattern.get_binding_identifier() { let assignment = self.create_this_property_assignment(id); self.assignments.push(assignment); } @@ -414,29 +414,35 @@ impl<'a> TypeScriptAnnotations<'a> { /// ``` pub fn transform_if_statement(&mut self, stmt: &mut IfStatement<'a>) { if !self.assignments.is_empty() { - if matches!(&stmt.consequent, Statement::ExpressionStatement(expr) if expr.expression.is_super_call_expression()) - { - stmt.consequent = - self.ctx.ast.block_statement(self.ctx.ast.block( - SPAN, + if let Statement::ExpressionStatement(expr) = &stmt.consequent { + if expr.expression.is_super_call_expression() { + stmt.consequent = self.ctx.ast.block_statement(self.ctx.ast.block( + expr.span, self.ctx.ast.new_vec_single(self.ctx.ast.copy(&stmt.consequent)), )); + } } - if let Some(alternate) = &stmt.alternate { - if matches!(alternate, Statement::ExpressionStatement(expr) if expr.expression.is_super_call_expression()) + + let alternate_span = match &stmt.alternate { + Some(Statement::ExpressionStatement(expr)) + if expr.expression.is_super_call_expression() => { - stmt.alternate = - Some(self.ctx.ast.block_statement(self.ctx.ast.block( - SPAN, - self.ctx.ast.new_vec_single(self.ctx.ast.copy(alternate)), - ))); + Some(expr.span) } + _ => None, + }; + if let Some(span) = alternate_span { + let alternate = stmt.alternate.take().unwrap(); + stmt.alternate = Some(self.ctx.ast.block_statement( + self.ctx.ast.block(span, self.ctx.ast.new_vec_single(alternate)), + )); } } if stmt.consequent.is_typescript_syntax() { - stmt.consequent = - self.ctx.ast.block_statement(self.ctx.ast.block(SPAN, self.ctx.ast.new_vec())); + stmt.consequent = self.ctx.ast.block_statement( + self.ctx.ast.block(stmt.consequent.span(), self.ctx.ast.new_vec()), + ); } if stmt.alternate.as_ref().is_some_and(Statement::is_typescript_syntax) { @@ -446,22 +452,28 @@ impl<'a> TypeScriptAnnotations<'a> { pub fn transform_for_statement(&mut self, stmt: &mut ForStatement<'a>) { if stmt.body.is_typescript_syntax() { - stmt.body = - self.ctx.ast.block_statement(self.ctx.ast.block(SPAN, self.ctx.ast.new_vec())); + stmt.body = self + .ctx + .ast + .block_statement(self.ctx.ast.block(stmt.body.span(), self.ctx.ast.new_vec())); } } pub fn transform_while_statement(&mut self, stmt: &mut WhileStatement<'a>) { if stmt.body.is_typescript_syntax() { - stmt.body = - self.ctx.ast.block_statement(self.ctx.ast.block(SPAN, self.ctx.ast.new_vec())); + stmt.body = self + .ctx + .ast + .block_statement(self.ctx.ast.block(stmt.body.span(), self.ctx.ast.new_vec())); } } pub fn transform_do_while_statement(&mut self, stmt: &mut DoWhileStatement<'a>) { if stmt.body.is_typescript_syntax() { - stmt.body = - self.ctx.ast.block_statement(self.ctx.ast.block(SPAN, self.ctx.ast.new_vec())); + stmt.body = self + .ctx + .ast + .block_statement(self.ctx.ast.block(stmt.body.span(), self.ctx.ast.new_vec())); } }