mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(transformer/typescript): move all entry points to implementation of Traverse trait (#5422)
This commit is contained in:
parent
0617249716
commit
c984219e06
6 changed files with 436 additions and 373 deletions
|
|
@ -120,13 +120,13 @@ impl<'a> Transformer<'a> {
|
|||
|
||||
impl<'a> Traverse<'a> for Transformer<'a> {
|
||||
fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_program(program, ctx);
|
||||
self.x0_typescript.enter_program(program, ctx);
|
||||
self.x1_react.transform_program(program, ctx);
|
||||
}
|
||||
|
||||
fn exit_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x1_react.transform_program_on_exit(program, ctx);
|
||||
self.x0_typescript.transform_program_on_exit(program, ctx);
|
||||
self.x0_typescript.exit_program(program, ctx);
|
||||
self.x3_es2015.exit_program(program, ctx);
|
||||
}
|
||||
|
||||
|
|
@ -135,22 +135,22 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
fn enter_arrow_function_expression(
|
||||
&mut self,
|
||||
expr: &mut ArrowFunctionExpression<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_arrow_expression(expr);
|
||||
self.x0_typescript.enter_arrow_function_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_binding_pattern(&mut self, pat: &mut BindingPattern<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_binding_pattern(pat);
|
||||
fn enter_binding_pattern(&mut self, pat: &mut BindingPattern<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.enter_binding_pattern(pat, ctx);
|
||||
}
|
||||
|
||||
fn enter_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_call_expression(expr);
|
||||
self.x0_typescript.enter_call_expression(expr, ctx);
|
||||
self.x1_react.transform_call_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_class(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_class(class);
|
||||
self.x0_typescript.enter_class(class, ctx);
|
||||
self.x3_es2015.enter_class(class, ctx);
|
||||
}
|
||||
|
||||
|
|
@ -158,19 +158,19 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
self.x3_es2015.exit_class(class, ctx);
|
||||
}
|
||||
|
||||
fn enter_class_body(&mut self, body: &mut ClassBody<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_class_body(body);
|
||||
fn enter_class_body(&mut self, body: &mut ClassBody<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.enter_class_body(body, ctx);
|
||||
}
|
||||
fn enter_ts_module_declaration(
|
||||
&mut self,
|
||||
decl: &mut TSModuleDeclaration<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_ts_module_declaration(decl);
|
||||
self.x0_typescript.enter_ts_module_declaration(decl, ctx);
|
||||
}
|
||||
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_expression(expr);
|
||||
self.x0_typescript.enter_expression(expr, ctx);
|
||||
self.x1_react.transform_expression(expr, ctx);
|
||||
self.x2_es2021.enter_expression(expr, ctx);
|
||||
self.x2_es2020.enter_expression(expr, ctx);
|
||||
|
|
@ -187,44 +187,43 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
fn enter_simple_assignment_target(
|
||||
&mut self,
|
||||
node: &mut SimpleAssignmentTarget<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_simple_assignment_target(node);
|
||||
self.x0_typescript.enter_simple_assignment_target(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_assignment_target(
|
||||
&mut self,
|
||||
node: &mut AssignmentTarget<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_assignment_target(node);
|
||||
self.x0_typescript.enter_assignment_target(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_formal_parameter(
|
||||
&mut self,
|
||||
param: &mut FormalParameter<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_formal_parameter(param);
|
||||
self.x0_typescript.enter_formal_parameter(param, ctx);
|
||||
}
|
||||
|
||||
fn enter_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_function(func);
|
||||
self.x3_es2015.enter_function(func, ctx);
|
||||
}
|
||||
|
||||
fn exit_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_function(func);
|
||||
self.x0_typescript.exit_function(func, ctx);
|
||||
self.x1_react.transform_function_on_exit(func, ctx);
|
||||
self.x3_es2015.exit_function(func, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_element(&mut self, node: &mut JSXElement<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_jsx_element(node);
|
||||
fn enter_jsx_element(&mut self, node: &mut JSXElement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.enter_jsx_element(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_fragment(&mut self, node: &mut JSXFragment<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_jsx_fragment(node);
|
||||
fn enter_jsx_fragment(&mut self, node: &mut JSXFragment<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.enter_jsx_fragment(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_opening_element(
|
||||
|
|
@ -232,7 +231,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
elem: &mut JSXOpeningElement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_jsx_opening_element(elem);
|
||||
self.x0_typescript.enter_jsx_opening_element(elem, ctx);
|
||||
self.x1_react.transform_jsx_opening_element(elem, ctx);
|
||||
}
|
||||
|
||||
|
|
@ -251,9 +250,9 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
fn enter_method_definition(
|
||||
&mut self,
|
||||
def: &mut MethodDefinition<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_method_definition(def);
|
||||
self.x0_typescript.enter_method_definition(def, ctx);
|
||||
}
|
||||
|
||||
fn exit_method_definition(
|
||||
|
|
@ -261,31 +260,31 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
def: &mut MethodDefinition<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_method_definition_on_exit(def, ctx);
|
||||
self.x0_typescript.exit_method_definition(def, ctx);
|
||||
}
|
||||
|
||||
fn enter_new_expression(&mut self, expr: &mut NewExpression<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_new_expression(expr);
|
||||
fn enter_new_expression(&mut self, expr: &mut NewExpression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.enter_new_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_property_definition(
|
||||
&mut self,
|
||||
def: &mut PropertyDefinition<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_property_definition(def);
|
||||
self.x0_typescript.enter_property_definition(def, ctx);
|
||||
}
|
||||
|
||||
fn enter_accessor_property(
|
||||
&mut self,
|
||||
node: &mut AccessorProperty<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_accessor_property(node);
|
||||
self.x0_typescript.enter_accessor_property(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_statements(stmts);
|
||||
self.x0_typescript.enter_statements(stmts, ctx);
|
||||
self.x1_react.transform_statements(stmts, ctx);
|
||||
self.x2_es2021.enter_statements(stmts, ctx);
|
||||
self.x2_es2020.enter_statements(stmts, ctx);
|
||||
|
|
@ -315,7 +314,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
}
|
||||
|
||||
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_statements_on_exit(stmts, ctx);
|
||||
self.x0_typescript.exit_statements(stmts, ctx);
|
||||
self.x1_react.transform_statements_on_exit(stmts, ctx);
|
||||
self.x2_es2021.exit_statements(stmts, ctx);
|
||||
self.x2_es2020.exit_statements(stmts, ctx);
|
||||
|
|
@ -325,17 +324,17 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
fn enter_tagged_template_expression(
|
||||
&mut self,
|
||||
expr: &mut TaggedTemplateExpression<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_tagged_template_expression(expr);
|
||||
self.x0_typescript.enter_tagged_template_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_statement(stmt, ctx);
|
||||
self.x0_typescript.enter_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_declaration(decl, ctx);
|
||||
self.x0_typescript.enter_declaration(decl, ctx);
|
||||
self.x3_es2015.enter_declaration(decl, ctx);
|
||||
}
|
||||
|
||||
|
|
@ -344,11 +343,11 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
}
|
||||
|
||||
fn enter_if_statement(&mut self, stmt: &mut IfStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_if_statement(stmt, ctx);
|
||||
self.x0_typescript.enter_if_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_while_statement(&mut self, stmt: &mut WhileStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_while_statement(stmt, ctx);
|
||||
self.x0_typescript.enter_while_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_do_while_statement(
|
||||
|
|
@ -356,19 +355,19 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
stmt: &mut DoWhileStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_do_while_statement(stmt, ctx);
|
||||
self.x0_typescript.enter_do_while_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_for_statement(&mut self, stmt: &mut ForStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_for_statement(stmt, ctx);
|
||||
self.x0_typescript.enter_for_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_for_of_statement(&mut self, stmt: &mut ForOfStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_for_of_statement(stmt, ctx);
|
||||
self.x0_typescript.enter_for_of_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_for_in_statement(&mut self, stmt: &mut ForInStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_for_in_statement(stmt, ctx);
|
||||
self.x0_typescript.enter_for_in_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_catch_clause(&mut self, clause: &mut CatchClause<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
|
|
@ -410,8 +409,8 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
fn enter_ts_export_assignment(
|
||||
&mut self,
|
||||
export_assignment: &mut TSExportAssignment<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x0_typescript.transform_ts_export_assignment(export_assignment);
|
||||
self.x0_typescript.enter_ts_export_assignment(export_assignment, ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use oxc_syntax::{
|
|||
scope::{ScopeFlags, ScopeId},
|
||||
symbol::SymbolId,
|
||||
};
|
||||
use oxc_traverse::TraverseCtx;
|
||||
use oxc_traverse::{Traverse, TraverseCtx};
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::{context::Ctx, TypeScriptOptions};
|
||||
|
|
@ -59,20 +59,9 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
type_identifier_names: FxHashSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the given name is a JSX pragma or fragment pragma import
|
||||
/// and if the file contains JSX elements or fragments
|
||||
fn is_jsx_imports(&self, name: &str) -> bool {
|
||||
self.has_jsx_element && name == self.jsx_element_import_name
|
||||
|| self.has_jsx_fragment && name == self.jsx_fragment_import_name
|
||||
}
|
||||
|
||||
// Remove type only imports/exports
|
||||
pub fn transform_program_on_exit(
|
||||
&mut self,
|
||||
program: &mut Program<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
}
|
||||
impl<'a> Traverse<'a> for TypeScriptAnnotations<'a> {
|
||||
fn exit_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
let mut no_modules_remaining = true;
|
||||
let mut some_modules_deleted = false;
|
||||
|
||||
|
|
@ -166,13 +155,16 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
program.body.push(self.ctx.ast.statement_module_declaration(export_decl));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) {
|
||||
fn enter_arrow_function_expression(
|
||||
&mut self,
|
||||
expr: &mut ArrowFunctionExpression<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
expr.type_parameters = None;
|
||||
expr.return_type = None;
|
||||
}
|
||||
|
||||
pub fn transform_binding_pattern(&mut self, pat: &mut BindingPattern<'a>) {
|
||||
fn enter_binding_pattern(&mut self, pat: &mut BindingPattern<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
pat.type_annotation = None;
|
||||
|
||||
if pat.kind.is_binding_identifier() {
|
||||
|
|
@ -180,18 +172,18 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn transform_call_expression(&mut self, expr: &mut CallExpression<'a>) {
|
||||
fn enter_call_expression(&mut self, expr: &mut CallExpression<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
expr.type_parameters = None;
|
||||
}
|
||||
|
||||
pub fn transform_class(&mut self, class: &mut Class<'a>) {
|
||||
fn enter_class(&mut self, class: &mut Class<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
class.type_parameters = None;
|
||||
class.super_type_parameters = None;
|
||||
class.implements = None;
|
||||
class.r#abstract = false;
|
||||
}
|
||||
|
||||
pub fn transform_class_body(&mut self, body: &mut ClassBody<'a>) {
|
||||
fn enter_class_body(&mut self, body: &mut ClassBody<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
// Remove type only members
|
||||
body.body.retain(|elem| match elem {
|
||||
ClassElement::MethodDefinition(method) => {
|
||||
|
|
@ -213,14 +205,18 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
if expr.is_typescript_syntax() {
|
||||
let inner_expr = expr.get_inner_expression_mut();
|
||||
*expr = self.ctx.ast.move_expression(inner_expr);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_simple_assignment_target(&mut self, target: &mut SimpleAssignmentTarget<'a>) {
|
||||
fn enter_simple_assignment_target(
|
||||
&mut self,
|
||||
target: &mut SimpleAssignmentTarget<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if let Some(expr) = target.get_expression_mut() {
|
||||
match expr.get_inner_expression_mut() {
|
||||
// `foo!++` to `foo++`
|
||||
|
|
@ -245,7 +241,11 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn transform_assignment_target(&mut self, target: &mut AssignmentTarget<'a>) {
|
||||
fn enter_assignment_target(
|
||||
&mut self,
|
||||
target: &mut AssignmentTarget<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if let Some(expr) = target.get_expression_mut() {
|
||||
let inner_expr = expr.get_inner_expression_mut();
|
||||
if inner_expr.is_member_expression() {
|
||||
|
|
@ -256,21 +256,33 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn transform_formal_parameter(&mut self, param: &mut FormalParameter<'a>) {
|
||||
fn enter_formal_parameter(
|
||||
&mut self,
|
||||
param: &mut FormalParameter<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
param.accessibility = None;
|
||||
}
|
||||
|
||||
pub fn transform_function(&mut self, func: &mut Function<'a>) {
|
||||
fn exit_function(&mut self, func: &mut Function<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
func.this_param = None;
|
||||
func.type_parameters = None;
|
||||
func.return_type = None;
|
||||
}
|
||||
|
||||
pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
|
||||
fn enter_jsx_opening_element(
|
||||
&mut self,
|
||||
elem: &mut JSXOpeningElement<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
elem.type_parameters = None;
|
||||
}
|
||||
|
||||
pub fn transform_method_definition(&mut self, def: &mut MethodDefinition<'a>) {
|
||||
fn enter_method_definition(
|
||||
&mut self,
|
||||
def: &mut MethodDefinition<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
// Collects parameter properties so that we can add an assignment
|
||||
// for each of them in the constructor body.
|
||||
if def.kind == MethodDefinitionKind::Constructor {
|
||||
|
|
@ -296,7 +308,7 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
def.r#override = false;
|
||||
}
|
||||
|
||||
pub fn transform_method_definition_on_exit(
|
||||
fn exit_method_definition(
|
||||
&mut self,
|
||||
def: &mut MethodDefinition<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
|
|
@ -327,11 +339,15 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn transform_new_expression(&mut self, expr: &mut NewExpression<'a>) {
|
||||
fn enter_new_expression(&mut self, expr: &mut NewExpression<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
expr.type_parameters = None;
|
||||
}
|
||||
|
||||
pub fn transform_property_definition(&mut self, def: &mut PropertyDefinition<'a>) {
|
||||
fn enter_property_definition(
|
||||
&mut self,
|
||||
def: &mut PropertyDefinition<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
assert!(
|
||||
!(def.declare && def.value.is_some()),
|
||||
"Fields with the 'declare' modifier cannot be initialized here, but only in the constructor"
|
||||
|
|
@ -351,13 +367,21 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
def.type_annotation = None;
|
||||
}
|
||||
|
||||
pub fn transform_accessor_property(&mut self, def: &mut AccessorProperty<'a>) {
|
||||
fn enter_accessor_property(
|
||||
&mut self,
|
||||
def: &mut AccessorProperty<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
def.accessibility = None;
|
||||
def.definite = false;
|
||||
def.type_annotation = None;
|
||||
}
|
||||
|
||||
pub fn transform_statements(&mut self, stmts: &mut ArenaVec<'a, Statement<'a>>) {
|
||||
fn enter_statements(
|
||||
&mut self,
|
||||
stmts: &mut ArenaVec<'a, Statement<'a>>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
// Remove declare declaration
|
||||
stmts.retain(
|
||||
|stmt| {
|
||||
|
|
@ -370,7 +394,7 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn transform_statements_on_exit(
|
||||
fn exit_statements(
|
||||
&mut self,
|
||||
stmts: &mut ArenaVec<'a, Statement<'a>>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
|
|
@ -415,11 +439,7 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
/// // to
|
||||
/// if (true) { super() } else { super() }
|
||||
/// ```
|
||||
pub fn transform_if_statement(
|
||||
&mut self,
|
||||
stmt: &mut IfStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
fn enter_if_statement(&mut self, stmt: &mut IfStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if !self.assignments.is_empty() {
|
||||
let consequent_span = match &stmt.consequent {
|
||||
Statement::ExpressionStatement(expr)
|
||||
|
|
@ -455,6 +475,78 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn enter_for_statement(&mut self, stmt: &mut ForStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
Self::replace_for_statement_body_with_empty_block_if_ts(
|
||||
&mut stmt.body,
|
||||
&stmt.scope_id,
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
|
||||
fn enter_for_in_statement(&mut self, stmt: &mut ForInStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
Self::replace_for_statement_body_with_empty_block_if_ts(
|
||||
&mut stmt.body,
|
||||
&stmt.scope_id,
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
|
||||
fn enter_for_of_statement(&mut self, stmt: &mut ForOfStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
Self::replace_for_statement_body_with_empty_block_if_ts(
|
||||
&mut stmt.body,
|
||||
&stmt.scope_id,
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
|
||||
fn enter_while_statement(&mut self, stmt: &mut WhileStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx.current_scope_id(), ctx);
|
||||
}
|
||||
|
||||
fn enter_do_while_statement(
|
||||
&mut self,
|
||||
stmt: &mut DoWhileStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx.current_scope_id(), ctx);
|
||||
}
|
||||
|
||||
fn enter_tagged_template_expression(
|
||||
&mut self,
|
||||
expr: &mut TaggedTemplateExpression<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
expr.type_parameters = None;
|
||||
}
|
||||
|
||||
fn enter_jsx_element(&mut self, _elem: &mut JSXElement<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.has_jsx_element = true;
|
||||
}
|
||||
|
||||
fn enter_jsx_fragment(&mut self, _elem: &mut JSXFragment<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.has_jsx_fragment = true;
|
||||
}
|
||||
|
||||
fn enter_ts_module_declaration(
|
||||
&mut self,
|
||||
decl: &mut TSModuleDeclaration<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
// NB: Namespace transform happens in `enter_program` visitor, and replaces retained
|
||||
// namespaces with functions. This visitor is called after, by which time any remaining
|
||||
// namespaces need to be deleted.
|
||||
self.type_identifier_names.insert(decl.id.name().clone());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TypeScriptAnnotations<'a> {
|
||||
/// Check if the given name is a JSX pragma or fragment pragma import
|
||||
/// and if the file contains JSX elements or fragments
|
||||
fn is_jsx_imports(&self, name: &str) -> bool {
|
||||
self.has_jsx_element && name == self.jsx_element_import_name
|
||||
|| self.has_jsx_fragment && name == self.jsx_fragment_import_name
|
||||
}
|
||||
|
||||
fn create_block_with_statement(
|
||||
stmt: Statement<'a>,
|
||||
span: Span,
|
||||
|
|
@ -466,58 +558,6 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
Statement::BlockStatement(ctx.ast.alloc(block))
|
||||
}
|
||||
|
||||
pub fn transform_for_statement(
|
||||
&mut self,
|
||||
stmt: &mut ForStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
Self::replace_for_statement_body_with_empty_block_if_ts(
|
||||
&mut stmt.body,
|
||||
&stmt.scope_id,
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn transform_for_in_statement(
|
||||
&mut self,
|
||||
stmt: &mut ForInStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
Self::replace_for_statement_body_with_empty_block_if_ts(
|
||||
&mut stmt.body,
|
||||
&stmt.scope_id,
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn transform_for_of_statement(
|
||||
&mut self,
|
||||
stmt: &mut ForOfStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
Self::replace_for_statement_body_with_empty_block_if_ts(
|
||||
&mut stmt.body,
|
||||
&stmt.scope_id,
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn transform_while_statement(
|
||||
&mut self,
|
||||
stmt: &mut WhileStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx.current_scope_id(), ctx);
|
||||
}
|
||||
|
||||
pub fn transform_do_while_statement(
|
||||
&mut self,
|
||||
stmt: &mut DoWhileStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx.current_scope_id(), ctx);
|
||||
}
|
||||
|
||||
fn replace_for_statement_body_with_empty_block_if_ts(
|
||||
body: &mut Statement<'a>,
|
||||
scope_id: &Cell<Option<ScopeId>>,
|
||||
|
|
@ -543,28 +583,6 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn transform_tagged_template_expression(
|
||||
&mut self,
|
||||
expr: &mut TaggedTemplateExpression<'a>,
|
||||
) {
|
||||
expr.type_parameters = None;
|
||||
}
|
||||
|
||||
pub fn transform_jsx_element(&mut self, _elem: &mut JSXElement<'a>) {
|
||||
self.has_jsx_element = true;
|
||||
}
|
||||
|
||||
pub fn transform_jsx_fragment(&mut self, _elem: &mut JSXFragment<'a>) {
|
||||
self.has_jsx_fragment = true;
|
||||
}
|
||||
|
||||
pub fn transform_ts_module_declaration(&mut self, decl: &mut TSModuleDeclaration<'a>) {
|
||||
// NB: Namespace transform happens in `enter_program` visitor, and replaces retained
|
||||
// namespaces with functions. This visitor is called after, by which time any remaining
|
||||
// namespaces need to be deleted.
|
||||
self.type_identifier_names.insert(decl.id.name().clone());
|
||||
}
|
||||
|
||||
pub fn has_value_reference(&self, name: &str, ctx: &TraverseCtx<'a>) -> bool {
|
||||
if let Some(symbol_id) = ctx.scopes().get_root_binding(name) {
|
||||
// `import T from 'mod'; const T = 1;` The T has a value redeclaration
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use oxc_syntax::{
|
|||
reference::ReferenceFlags,
|
||||
symbol::SymbolFlags,
|
||||
};
|
||||
use oxc_traverse::TraverseCtx;
|
||||
use oxc_traverse::{Traverse, TraverseCtx};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::context::Ctx;
|
||||
|
|
@ -24,8 +24,10 @@ impl<'a> TypeScriptEnum<'a> {
|
|||
pub fn new(ctx: Ctx<'a>) -> Self {
|
||||
Self { ctx, enums: FxHashMap::default() }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
impl<'a> Traverse<'a> for TypeScriptEnum<'a> {
|
||||
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
let new_stmt = match stmt {
|
||||
Statement::TSEnumDeclaration(ts_enum_decl) => {
|
||||
self.transform_ts_enum(ts_enum_decl, None, ctx)
|
||||
|
|
@ -45,7 +47,9 @@ impl<'a> TypeScriptEnum<'a> {
|
|||
*stmt = new_stmt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TypeScriptEnum<'a> {
|
||||
/// ```TypeScript
|
||||
/// enum Foo {
|
||||
/// X = 1,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ mod rewrite_extensions;
|
|||
|
||||
use std::rc::Rc;
|
||||
|
||||
use module::TypeScriptModule;
|
||||
use namespace::TypeScriptNamespace;
|
||||
use oxc_allocator::Vec;
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_traverse::{Traverse, TraverseCtx};
|
||||
|
|
@ -45,6 +47,8 @@ pub struct TypeScript<'a> {
|
|||
|
||||
annotations: TypeScriptAnnotations<'a>,
|
||||
r#enum: TypeScriptEnum<'a>,
|
||||
namespace: TypeScriptNamespace<'a>,
|
||||
module: TypeScriptModule<'a>,
|
||||
rewrite_extensions: TypeScriptRewriteExtensions,
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +62,8 @@ impl<'a> TypeScript<'a> {
|
|||
rewrite_extensions: TypeScriptRewriteExtensions::new(
|
||||
options.rewrite_import_extensions.clone().unwrap_or_default(),
|
||||
),
|
||||
namespace: TypeScriptNamespace::new(Rc::clone(&options), Rc::clone(&ctx)),
|
||||
module: TypeScriptModule::new(Rc::clone(&ctx)),
|
||||
options,
|
||||
ctx,
|
||||
}
|
||||
|
|
@ -65,6 +71,189 @@ impl<'a> TypeScript<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Traverse<'a> for TypeScript<'a> {
|
||||
fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.ctx.source_type.is_typescript_definition() {
|
||||
// Output empty file for TS definitions
|
||||
program.directives.clear();
|
||||
program.hashbang = None;
|
||||
program.body.clear();
|
||||
} else {
|
||||
self.namespace.enter_program(program, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.exit_program(program, ctx);
|
||||
}
|
||||
|
||||
fn enter_arrow_function_expression(
|
||||
&mut self,
|
||||
expr: &mut ArrowFunctionExpression<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_arrow_function_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_binding_pattern(&mut self, pat: &mut BindingPattern<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_binding_pattern(pat, ctx);
|
||||
}
|
||||
|
||||
fn enter_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_call_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_class(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_class(class, ctx);
|
||||
}
|
||||
|
||||
fn enter_class_body(&mut self, body: &mut ClassBody<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_class_body(body, ctx);
|
||||
}
|
||||
|
||||
fn enter_ts_module_declaration(
|
||||
&mut self,
|
||||
decl: &mut TSModuleDeclaration<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_ts_module_declaration(decl, ctx);
|
||||
}
|
||||
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_simple_assignment_target(
|
||||
&mut self,
|
||||
target: &mut SimpleAssignmentTarget<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_simple_assignment_target(target, ctx);
|
||||
}
|
||||
|
||||
fn enter_assignment_target(
|
||||
&mut self,
|
||||
target: &mut AssignmentTarget<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_assignment_target(target, ctx);
|
||||
}
|
||||
|
||||
fn enter_formal_parameter(
|
||||
&mut self,
|
||||
param: &mut FormalParameter<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_formal_parameter(param, ctx);
|
||||
}
|
||||
|
||||
fn exit_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.exit_function(func, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_opening_element(
|
||||
&mut self,
|
||||
elem: &mut JSXOpeningElement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_jsx_opening_element(elem, ctx);
|
||||
}
|
||||
|
||||
fn enter_method_definition(
|
||||
&mut self,
|
||||
def: &mut MethodDefinition<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_method_definition(def, ctx);
|
||||
}
|
||||
|
||||
fn exit_method_definition(
|
||||
&mut self,
|
||||
def: &mut MethodDefinition<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.exit_method_definition(def, ctx);
|
||||
}
|
||||
|
||||
fn enter_new_expression(&mut self, expr: &mut NewExpression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_new_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_property_definition(
|
||||
&mut self,
|
||||
def: &mut PropertyDefinition<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_property_definition(def, ctx);
|
||||
}
|
||||
|
||||
fn enter_accessor_property(
|
||||
&mut self,
|
||||
def: &mut AccessorProperty<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_accessor_property(def, ctx);
|
||||
}
|
||||
|
||||
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_statements(stmts, ctx);
|
||||
}
|
||||
|
||||
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.exit_statements(stmts, ctx);
|
||||
}
|
||||
|
||||
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.r#enum.enter_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_if_statement(&mut self, stmt: &mut IfStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_if_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_while_statement(&mut self, stmt: &mut WhileStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_while_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_do_while_statement(
|
||||
&mut self,
|
||||
stmt: &mut DoWhileStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_do_while_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_for_statement(&mut self, stmt: &mut ForStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_for_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_for_in_statement(&mut self, stmt: &mut ForInStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_for_in_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_for_of_statement(&mut self, stmt: &mut ForOfStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_for_of_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_tagged_template_expression(
|
||||
&mut self,
|
||||
expr: &mut TaggedTemplateExpression<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.enter_tagged_template_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_element(&mut self, elem: &mut JSXElement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_jsx_element(elem, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_fragment(&mut self, elem: &mut JSXFragment<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.annotations.enter_jsx_fragment(elem, ctx);
|
||||
}
|
||||
|
||||
fn enter_declaration(&mut self, node: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.module.enter_declaration(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_import_declaration(
|
||||
&mut self,
|
||||
node: &mut ImportDeclaration<'a>,
|
||||
|
|
@ -94,177 +283,12 @@ impl<'a> Traverse<'a> for TypeScript<'a> {
|
|||
self.rewrite_extensions.enter_export_named_declaration(node, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms
|
||||
impl<'a> TypeScript<'a> {
|
||||
pub fn transform_program(&self, program: &mut Program<'a>, ctx: &mut TraverseCtx) {
|
||||
if self.ctx.source_type.is_typescript_definition() {
|
||||
// Output empty file for TS definitions
|
||||
program.directives.clear();
|
||||
program.hashbang = None;
|
||||
program.body.clear();
|
||||
} else {
|
||||
self.transform_program_for_namespace(program, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_program_on_exit(
|
||||
fn enter_ts_export_assignment(
|
||||
&mut self,
|
||||
program: &mut Program<'a>,
|
||||
node: &mut TSExportAssignment<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_program_on_exit(program, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) {
|
||||
self.annotations.transform_arrow_expression(expr);
|
||||
}
|
||||
|
||||
pub fn transform_binding_pattern(&mut self, pat: &mut BindingPattern<'a>) {
|
||||
self.annotations.transform_binding_pattern(pat);
|
||||
}
|
||||
|
||||
pub fn transform_call_expression(&mut self, expr: &mut CallExpression<'a>) {
|
||||
self.annotations.transform_call_expression(expr);
|
||||
}
|
||||
|
||||
pub fn transform_class(&mut self, class: &mut Class<'a>) {
|
||||
self.annotations.transform_class(class);
|
||||
}
|
||||
|
||||
pub fn transform_class_body(&mut self, body: &mut ClassBody<'a>) {
|
||||
self.annotations.transform_class_body(body);
|
||||
}
|
||||
|
||||
pub fn transform_ts_module_declaration(&mut self, decl: &mut TSModuleDeclaration<'a>) {
|
||||
self.annotations.transform_ts_module_declaration(decl);
|
||||
}
|
||||
|
||||
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
||||
self.annotations.transform_expression(expr);
|
||||
}
|
||||
|
||||
pub fn transform_simple_assignment_target(&mut self, target: &mut SimpleAssignmentTarget<'a>) {
|
||||
self.annotations.transform_simple_assignment_target(target);
|
||||
}
|
||||
|
||||
pub fn transform_assignment_target(&mut self, target: &mut AssignmentTarget<'a>) {
|
||||
self.annotations.transform_assignment_target(target);
|
||||
}
|
||||
|
||||
pub fn transform_formal_parameter(&mut self, param: &mut FormalParameter<'a>) {
|
||||
self.annotations.transform_formal_parameter(param);
|
||||
}
|
||||
|
||||
pub fn transform_function(&mut self, func: &mut Function<'a>) {
|
||||
self.annotations.transform_function(func);
|
||||
}
|
||||
|
||||
pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
|
||||
self.annotations.transform_jsx_opening_element(elem);
|
||||
}
|
||||
|
||||
pub fn transform_method_definition(&mut self, def: &mut MethodDefinition<'a>) {
|
||||
self.annotations.transform_method_definition(def);
|
||||
}
|
||||
|
||||
pub fn transform_method_definition_on_exit(
|
||||
&mut self,
|
||||
def: &mut MethodDefinition<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_method_definition_on_exit(def, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_new_expression(&mut self, expr: &mut NewExpression<'a>) {
|
||||
self.annotations.transform_new_expression(expr);
|
||||
}
|
||||
|
||||
pub fn transform_property_definition(&mut self, def: &mut PropertyDefinition<'a>) {
|
||||
self.annotations.transform_property_definition(def);
|
||||
}
|
||||
|
||||
pub fn transform_accessor_property(&mut self, def: &mut AccessorProperty<'a>) {
|
||||
self.annotations.transform_accessor_property(def);
|
||||
}
|
||||
|
||||
pub fn transform_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
|
||||
self.annotations.transform_statements(stmts);
|
||||
}
|
||||
|
||||
pub fn transform_statements_on_exit(
|
||||
&mut self,
|
||||
stmts: &mut Vec<'a, Statement<'a>>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_statements_on_exit(stmts, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.r#enum.transform_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_if_statement(
|
||||
&mut self,
|
||||
stmt: &mut IfStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_if_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_while_statement(
|
||||
&mut self,
|
||||
stmt: &mut WhileStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_while_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_do_while_statement(
|
||||
&mut self,
|
||||
stmt: &mut DoWhileStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_do_while_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_for_statement(
|
||||
&mut self,
|
||||
stmt: &mut ForStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_for_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_for_in_statement(
|
||||
&mut self,
|
||||
stmt: &mut ForInStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_for_in_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_for_of_statement(
|
||||
&mut self,
|
||||
stmt: &mut ForOfStatement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.annotations.transform_for_of_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
pub fn transform_tagged_template_expression(
|
||||
&mut self,
|
||||
expr: &mut TaggedTemplateExpression<'a>,
|
||||
) {
|
||||
self.annotations.transform_tagged_template_expression(expr);
|
||||
}
|
||||
|
||||
pub fn transform_jsx_element(&mut self, elem: &mut JSXElement<'a>) {
|
||||
self.annotations.transform_jsx_element(elem);
|
||||
}
|
||||
|
||||
pub fn transform_jsx_fragment(&mut self, elem: &mut JSXFragment<'a>) {
|
||||
self.annotations.transform_jsx_fragment(elem);
|
||||
self.module.enter_ts_export_assignment(node, ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,21 @@ use oxc_allocator::Box;
|
|||
use oxc_ast::ast::*;
|
||||
use oxc_span::SPAN;
|
||||
use oxc_syntax::reference::ReferenceFlags;
|
||||
use oxc_traverse::TraverseCtx;
|
||||
use oxc_traverse::{Traverse, TraverseCtx};
|
||||
|
||||
use super::TypeScript;
|
||||
use crate::context::Ctx;
|
||||
|
||||
impl<'a> TypeScript<'a> {
|
||||
pub struct TypeScriptModule<'a> {
|
||||
ctx: Ctx<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TypeScriptModule<'a> {
|
||||
pub fn new(ctx: Ctx<'a>) -> Self {
|
||||
Self { ctx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Traverse<'a> for TypeScriptModule<'a> {
|
||||
/// ```TypeScript
|
||||
/// import b = babel;
|
||||
/// import AliasModule = LongNameModule;
|
||||
|
|
@ -15,7 +25,7 @@ impl<'a> TypeScript<'a> {
|
|||
/// var b = babel;
|
||||
/// var AliasModule = LongNameModule;
|
||||
/// ```
|
||||
pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
match decl {
|
||||
Declaration::TSImportEqualsDeclaration(ts_import_equals)
|
||||
if ts_import_equals.import_kind.is_value() =>
|
||||
|
|
@ -26,6 +36,19 @@ impl<'a> TypeScript<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn enter_ts_export_assignment(
|
||||
&mut self,
|
||||
export_assignment: &mut TSExportAssignment<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if self.ctx.source_type.is_module() {
|
||||
self.ctx
|
||||
.error(super::diagnostics::export_assignment_unsupported(export_assignment.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TypeScriptModule<'a> {
|
||||
fn transform_ts_import_equals(
|
||||
&self,
|
||||
decl: &mut Box<'a, TSImportEqualsDeclaration<'a>>,
|
||||
|
|
@ -34,8 +57,8 @@ impl<'a> TypeScript<'a> {
|
|||
let kind = VariableDeclarationKind::Var;
|
||||
let decls = {
|
||||
let binding_pattern_kind =
|
||||
self.ctx.ast.binding_pattern_kind_binding_identifier(SPAN, &decl.id.name);
|
||||
let binding = self.ctx.ast.binding_pattern(
|
||||
ctx.ast.binding_pattern_kind_binding_identifier(SPAN, &decl.id.name);
|
||||
let binding = ctx.ast.binding_pattern(
|
||||
binding_pattern_kind,
|
||||
Option::<TSTypeAnnotation>::None,
|
||||
false,
|
||||
|
|
@ -53,11 +76,11 @@ impl<'a> TypeScript<'a> {
|
|||
));
|
||||
}
|
||||
|
||||
let callee = self.ctx.ast.expression_identifier_reference(SPAN, "require");
|
||||
let arguments = self.ctx.ast.vec1(Argument::from(
|
||||
self.ctx.ast.expression_from_string_literal(reference.expression.clone()),
|
||||
let callee = ctx.ast.expression_identifier_reference(SPAN, "require");
|
||||
let arguments = ctx.ast.vec1(Argument::from(
|
||||
ctx.ast.expression_from_string_literal(reference.expression.clone()),
|
||||
));
|
||||
self.ctx.ast.expression_call(
|
||||
ctx.ast.expression_call(
|
||||
SPAN,
|
||||
callee,
|
||||
Option::<TSTypeParameterInstantiation>::None,
|
||||
|
|
@ -66,18 +89,13 @@ impl<'a> TypeScript<'a> {
|
|||
)
|
||||
}
|
||||
};
|
||||
self.ctx.ast.vec1(self.ctx.ast.variable_declarator(
|
||||
SPAN,
|
||||
kind,
|
||||
binding,
|
||||
Some(init),
|
||||
false,
|
||||
))
|
||||
ctx.ast.vec1(ctx.ast.variable_declarator(SPAN, kind, binding, Some(init), false))
|
||||
};
|
||||
|
||||
self.ctx.ast.declaration_variable(SPAN, kind, decls, false)
|
||||
ctx.ast.declaration_variable(SPAN, kind, decls, false)
|
||||
}
|
||||
|
||||
#[allow(clippy::only_used_in_recursion)]
|
||||
fn transform_ts_type_name(
|
||||
&self,
|
||||
type_name: &mut TSTypeName<'a>,
|
||||
|
|
@ -89,10 +107,9 @@ impl<'a> TypeScript<'a> {
|
|||
let reference_id = ident.reference_id.get().unwrap();
|
||||
let reference = ctx.symbols_mut().get_reference_mut(reference_id);
|
||||
*reference.flags_mut() = ReferenceFlags::Read;
|
||||
self.ctx.ast.expression_from_identifier_reference(ident)
|
||||
ctx.ast.expression_from_identifier_reference(ident)
|
||||
}
|
||||
TSTypeName::QualifiedName(qualified_name) => self
|
||||
.ctx
|
||||
TSTypeName::QualifiedName(qualified_name) => ctx
|
||||
.ast
|
||||
.member_expression_static(
|
||||
SPAN,
|
||||
|
|
@ -103,14 +120,4 @@ impl<'a> TypeScript<'a> {
|
|||
.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_ts_export_assignment(
|
||||
&mut self,
|
||||
export_assignment: &mut TSExportAssignment<'a>,
|
||||
) {
|
||||
if self.ctx.source_type.is_module() {
|
||||
self.ctx
|
||||
.error(super::diagnostics::export_assignment_unsupported(export_assignment.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use oxc_allocator::{Box, Vec};
|
||||
use oxc_ast::{ast::*, syntax_directed_operations::BoundNames};
|
||||
use oxc_span::{Atom, CompactStr, SPAN};
|
||||
|
|
@ -6,23 +8,30 @@ use oxc_syntax::{
|
|||
scope::{ScopeFlags, ScopeId},
|
||||
symbol::SymbolFlags,
|
||||
};
|
||||
use oxc_traverse::TraverseCtx;
|
||||
use oxc_traverse::{Traverse, TraverseCtx};
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::context::Ctx;
|
||||
|
||||
use super::{
|
||||
diagnostics::{ambient_module_nested, namespace_exporting_non_const, namespace_not_supported},
|
||||
TypeScript,
|
||||
TypeScriptOptions,
|
||||
};
|
||||
|
||||
// TODO:
|
||||
// 1. register scope for the newly created function: <https://github.com/babel/babel/blob/08b0472069cd207f043dd40a4d157addfdd36011/packages/babel-plugin-transform-typescript/src/namespace.ts#L38>
|
||||
impl<'a> TypeScript<'a> {
|
||||
pub struct TypeScriptNamespace<'a> {
|
||||
ctx: Ctx<'a>,
|
||||
options: Rc<TypeScriptOptions>,
|
||||
}
|
||||
|
||||
impl<'a> TypeScriptNamespace<'a> {
|
||||
pub fn new(options: Rc<TypeScriptOptions>, ctx: Ctx<'a>) -> Self {
|
||||
Self { ctx, options }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Traverse<'a> for TypeScriptNamespace<'a> {
|
||||
// `namespace Foo { }` -> `let Foo; (function (_Foo) { })(Foo || (Foo = {}));`
|
||||
pub(super) fn transform_program_for_namespace(
|
||||
&self,
|
||||
program: &mut Program<'a>,
|
||||
ctx: &mut TraverseCtx,
|
||||
) {
|
||||
fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
// namespace declaration is only allowed at the top level
|
||||
|
||||
if !has_namespace(program.body.as_slice()) {
|
||||
|
|
@ -129,7 +138,9 @@ impl<'a> TypeScript<'a> {
|
|||
|
||||
program.body = new_stmts;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TypeScriptNamespace<'a> {
|
||||
fn handle_nested(
|
||||
&self,
|
||||
decl: TSModuleDeclaration<'a>,
|
||||
|
|
|
|||
Loading…
Reference in a new issue