diff --git a/crates/oxc_transformer/src/context.rs b/crates/oxc_transformer/src/context.rs index a1fc84f4e..2941d8f42 100644 --- a/crates/oxc_transformer/src/context.rs +++ b/crates/oxc_transformer/src/context.rs @@ -2,7 +2,6 @@ use std::{ cell::RefCell, mem, path::{Path, PathBuf}, - rc::Rc, }; use oxc_allocator::Allocator; @@ -12,8 +11,6 @@ use oxc_span::SourceType; use crate::{helpers::module_imports::ModuleImports, TransformOptions}; -pub type Ctx<'a> = Rc>; - pub struct TransformCtx<'a> { errors: RefCell>, diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index ea7eb224b..227f02b18 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -30,7 +30,7 @@ mod helpers { pub mod stack; } -use std::{path::Path, rc::Rc}; +use std::path::Path; use es2016::ES2016; use es2018::ES2018; @@ -53,12 +53,7 @@ pub use crate::{ react::{ReactJsxRuntime, ReactOptions, ReactRefreshOptions}, typescript::{RewriteExtensionsMode, TypeScriptOptions}, }; -use crate::{ - context::{Ctx, TransformCtx}, - es2015::ES2015, - react::React, - typescript::TypeScript, -}; +use crate::{context::TransformCtx, es2015::ES2015, react::React, typescript::TypeScript}; pub struct TransformerReturn { pub errors: std::vec::Vec, @@ -67,17 +62,8 @@ pub struct TransformerReturn { } pub struct Transformer<'a> { - ctx: Ctx<'a>, - // NOTE: all callbacks must run in order. - x0_typescript: TypeScript<'a>, - x1_react: React<'a>, - x2_es2021: ES2021<'a>, - x2_es2020: ES2020<'a>, - x2_es2019: ES2019, - x2_es2018: ES2018, - x2_es2016: ES2016<'a>, - x3_es2015: ES2015<'a>, - x4_regexp: RegExp<'a>, + ctx: TransformCtx<'a>, + options: TransformOptions, } impl<'a> Transformer<'a> { @@ -89,41 +75,50 @@ impl<'a> Transformer<'a> { trivias: Trivias, options: TransformOptions, ) -> Self { - let ctx = Rc::new(TransformCtx::new( - allocator, - source_path, - source_type, - source_text, - trivias, - &options, - )); - Self { - ctx: Rc::clone(&ctx), - x0_typescript: TypeScript::new(options.typescript, Rc::clone(&ctx)), - x1_react: React::new(options.react, Rc::clone(&ctx)), - x2_es2021: ES2021::new(options.es2021), - x2_es2020: ES2020::new(options.es2020), - x2_es2019: ES2019::new(options.es2019), - x2_es2018: ES2018::new(options.es2018), - x2_es2016: ES2016::new(options.es2016), - x3_es2015: ES2015::new(options.es2015), - x4_regexp: RegExp::new(options.regexp, ctx), - } + let ctx = + TransformCtx::new(allocator, source_path, source_type, source_text, trivias, &options); + Self { ctx, options } } pub fn build_with_symbols_and_scopes( - mut self, + self, symbols: SymbolTable, scopes: ScopeTree, program: &mut Program<'a>, ) -> TransformerReturn { let allocator = self.ctx.ast.allocator; - let (symbols, scopes) = traverse_mut(&mut self, allocator, program, symbols, scopes); + + let mut transformer = TransformerImpl { + x0_typescript: TypeScript::new(self.options.typescript, &self.ctx), + x1_react: React::new(self.options.react, &self.ctx), + x2_es2021: ES2021::new(self.options.es2021), + x2_es2020: ES2020::new(self.options.es2020), + x2_es2019: ES2019::new(self.options.es2019), + x2_es2018: ES2018::new(self.options.es2018), + x2_es2016: ES2016::new(self.options.es2016), + x3_es2015: ES2015::new(self.options.es2015), + x4_regexp: RegExp::new(self.options.regexp, &self.ctx), + }; + + let (symbols, scopes) = traverse_mut(&mut transformer, allocator, program, symbols, scopes); TransformerReturn { errors: self.ctx.take_errors(), symbols, scopes } } } -impl<'a> Traverse<'a> for Transformer<'a> { +struct TransformerImpl<'a, 'ctx> { + // NOTE: all callbacks must run in order. + x0_typescript: TypeScript<'a, 'ctx>, + x1_react: React<'a, 'ctx>, + x2_es2021: ES2021<'a>, + x2_es2020: ES2020<'a>, + x2_es2019: ES2019, + x2_es2018: ES2018, + x2_es2016: ES2016<'a>, + x3_es2015: ES2015<'a>, + x4_regexp: RegExp<'a, 'ctx>, +} + +impl<'a, 'ctx> Traverse<'a> for TransformerImpl<'a, 'ctx> { fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) { self.x0_typescript.enter_program(program, ctx); self.x1_react.enter_program(program, ctx); @@ -189,6 +184,7 @@ impl<'a> Traverse<'a> for Transformer<'a> { self.x0_typescript.enter_ts_module_declaration(decl, ctx); } + #[inline] fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) { self.x0_typescript.enter_expression(expr, ctx); self.x1_react.enter_expression(expr, ctx); diff --git a/crates/oxc_transformer/src/react/display_name.rs b/crates/oxc_transformer/src/react/display_name.rs index b0c58d3e0..6beedf1e9 100644 --- a/crates/oxc_transformer/src/react/display_name.rs +++ b/crates/oxc_transformer/src/react/display_name.rs @@ -50,19 +50,19 @@ use oxc_ast::ast::*; use oxc_span::{Atom, SPAN}; use oxc_traverse::{Ancestor, Traverse, TraverseCtx}; -use crate::context::Ctx; +use crate::TransformCtx; -pub struct ReactDisplayName<'a> { - ctx: Ctx<'a>, +pub struct ReactDisplayName<'a, 'ctx> { + ctx: &'ctx TransformCtx<'a>, } -impl<'a> ReactDisplayName<'a> { - pub fn new(ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> ReactDisplayName<'a, 'ctx> { + pub fn new(ctx: &'ctx TransformCtx<'a>) -> Self { Self { ctx } } } -impl<'a> Traverse<'a> for ReactDisplayName<'a> { +impl<'a, 'ctx> Traverse<'a> for ReactDisplayName<'a, 'ctx> { fn enter_call_expression( &mut self, call_expr: &mut CallExpression<'a>, @@ -129,7 +129,7 @@ impl<'a> Traverse<'a> for ReactDisplayName<'a> { } } -impl<'a> ReactDisplayName<'a> { +impl<'a, 'ctx> ReactDisplayName<'a, 'ctx> { /// Get the object from `React.createClass({})` or `createReactClass({})` fn get_object_from_create_class<'b>( call_expr: &'b mut CallExpression<'a>, diff --git a/crates/oxc_transformer/src/react/jsx.rs b/crates/oxc_transformer/src/react/jsx.rs index d97fb9833..f3fa613ab 100644 --- a/crates/oxc_transformer/src/react/jsx.rs +++ b/crates/oxc_transformer/src/react/jsx.rs @@ -88,8 +88,6 @@ //! //! * Babel plugin implementation: -use std::rc::Rc; - use oxc_allocator::Vec; use oxc_ast::{ast::*, AstBuilder, NONE}; use oxc_span::{Atom, GetSpan, Span, SPAN}; @@ -108,29 +106,29 @@ pub use super::{ options::{ReactJsxRuntime, ReactOptions}, }; use crate::{ - context::{Ctx, TransformCtx}, helpers::{bindings::BoundIdentifier, module_imports::NamedImport}, + TransformCtx, }; -pub struct ReactJsx<'a> { +pub struct ReactJsx<'a, 'ctx> { options: ReactOptions, - ctx: Ctx<'a>, + ctx: &'ctx TransformCtx<'a>, - pub(super) jsx_self: ReactJsxSelf<'a>, - pub(super) jsx_source: ReactJsxSource<'a>, + pub(super) jsx_self: ReactJsxSelf<'a, 'ctx>, + pub(super) jsx_source: ReactJsxSource<'a, 'ctx>, // States - bindings: Bindings<'a>, + bindings: Bindings<'a, 'ctx>, } /// Bindings for different import options -enum Bindings<'a> { +enum Bindings<'a, 'ctx> { Classic(ClassicBindings<'a>), - AutomaticScript(AutomaticScriptBindings<'a>), - AutomaticModule(AutomaticModuleBindings<'a>), + AutomaticScript(AutomaticScriptBindings<'a, 'ctx>), + AutomaticModule(AutomaticModuleBindings<'a, 'ctx>), } -impl<'a> Bindings<'a> { +impl<'a, 'ctx> Bindings<'a, 'ctx> { #[inline] fn is_classic(&self) -> bool { matches!(self, Self::Classic(_)) @@ -142,8 +140,8 @@ struct ClassicBindings<'a> { pragma_frag: Pragma<'a>, } -struct AutomaticScriptBindings<'a> { - ctx: Ctx<'a>, +struct AutomaticScriptBindings<'a, 'ctx> { + ctx: &'ctx TransformCtx<'a>, jsx_runtime_importer: Atom<'a>, react_importer_len: u32, require_create_element: Option>, @@ -151,9 +149,9 @@ struct AutomaticScriptBindings<'a> { is_development: bool, } -impl<'a> AutomaticScriptBindings<'a> { +impl<'a, 'ctx> AutomaticScriptBindings<'a, 'ctx> { fn new( - ctx: Ctx<'a>, + ctx: &'ctx TransformCtx<'a>, jsx_runtime_importer: Atom<'a>, react_importer_len: u32, is_development: bool, @@ -206,8 +204,8 @@ impl<'a> AutomaticScriptBindings<'a> { } } -struct AutomaticModuleBindings<'a> { - ctx: Ctx<'a>, +struct AutomaticModuleBindings<'a, 'ctx> { + ctx: &'ctx TransformCtx<'a>, jsx_runtime_importer: Atom<'a>, react_importer_len: u32, import_create_element: Option>, @@ -217,9 +215,9 @@ struct AutomaticModuleBindings<'a> { is_development: bool, } -impl<'a> AutomaticModuleBindings<'a> { +impl<'a, 'ctx> AutomaticModuleBindings<'a, 'ctx> { fn new( - ctx: Ctx<'a>, + ctx: &'ctx TransformCtx<'a>, jsx_runtime_importer: Atom<'a>, react_importer_len: u32, is_development: bool, @@ -371,15 +369,15 @@ impl<'a> Pragma<'a> { } } -impl<'a> ReactJsx<'a> { - pub fn new(options: ReactOptions, ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> ReactJsx<'a, 'ctx> { + pub fn new(options: ReactOptions, ctx: &'ctx TransformCtx<'a>) -> Self { let bindings = match options.runtime { ReactJsxRuntime::Classic => { if options.import_source.is_some() { ctx.error(diagnostics::import_source_cannot_be_set()); } - let pragma = Pragma::parse(options.pragma.as_ref(), "createElement", &ctx); - let pragma_frag = Pragma::parse(options.pragma_frag.as_ref(), "Fragment", &ctx); + let pragma = Pragma::parse(options.pragma.as_ref(), "createElement", ctx); + let pragma_frag = Pragma::parse(options.pragma_frag.as_ref(), "Fragment", ctx); Bindings::Classic(ClassicBindings { pragma, pragma_frag }) } ReactJsxRuntime::Automatic => { @@ -419,14 +417,14 @@ impl<'a> ReactJsx<'a> { if ctx.source_type.is_script() { Bindings::AutomaticScript(AutomaticScriptBindings::new( - Rc::clone(&ctx), + ctx, jsx_runtime_importer, source_len, is_development, )) } else { Bindings::AutomaticModule(AutomaticModuleBindings::new( - Rc::clone(&ctx), + ctx, jsx_runtime_importer, source_len, is_development, @@ -437,15 +435,15 @@ impl<'a> ReactJsx<'a> { Self { options, - ctx: Rc::clone(&ctx), - jsx_self: ReactJsxSelf::new(Rc::clone(&ctx)), + ctx, + jsx_self: ReactJsxSelf::new(ctx), jsx_source: ReactJsxSource::new(ctx), bindings, } } } -impl<'a> Traverse<'a> for ReactJsx<'a> { +impl<'a, 'ctx> Traverse<'a> for ReactJsx<'a, 'ctx> { fn exit_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) { self.add_runtime_imports(program, ctx); } @@ -461,7 +459,7 @@ impl<'a> Traverse<'a> for ReactJsx<'a> { } } -impl<'a> ReactJsx<'a> { +impl<'a, 'ctx> ReactJsx<'a, 'ctx> { fn is_script(&self) -> bool { self.ctx.source_type.is_script() } diff --git a/crates/oxc_transformer/src/react/jsx_self.rs b/crates/oxc_transformer/src/react/jsx_self.rs index 5f96e1fb3..e83c38aae 100644 --- a/crates/oxc_transformer/src/react/jsx_self.rs +++ b/crates/oxc_transformer/src/react/jsx_self.rs @@ -33,21 +33,21 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_span::{Span, SPAN}; use oxc_traverse::{Ancestor, Traverse, TraverseCtx}; -use crate::context::Ctx; +use crate::TransformCtx; const SELF: &str = "__self"; -pub struct ReactJsxSelf<'a> { - ctx: Ctx<'a>, +pub struct ReactJsxSelf<'a, 'ctx> { + ctx: &'ctx TransformCtx<'a>, } -impl<'a> ReactJsxSelf<'a> { - pub fn new(ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> ReactJsxSelf<'a, 'ctx> { + pub fn new(ctx: &'ctx TransformCtx<'a>) -> Self { Self { ctx } } } -impl<'a> Traverse<'a> for ReactJsxSelf<'a> { +impl<'a, 'ctx> Traverse<'a> for ReactJsxSelf<'a, 'ctx> { fn enter_jsx_opening_element( &mut self, elem: &mut JSXOpeningElement<'a>, @@ -57,7 +57,7 @@ impl<'a> Traverse<'a> for ReactJsxSelf<'a> { } } -impl<'a> ReactJsxSelf<'a> { +impl<'a, 'ctx> ReactJsxSelf<'a, 'ctx> { pub fn report_error(&self, span: Span) { let error = OxcDiagnostic::warn("Duplicate __self prop found.").with_label(span); self.ctx.error(error); diff --git a/crates/oxc_transformer/src/react/jsx_source.rs b/crates/oxc_transformer/src/react/jsx_source.rs index 29a64d3d5..330f5086d 100644 --- a/crates/oxc_transformer/src/react/jsx_source.rs +++ b/crates/oxc_transformer/src/react/jsx_source.rs @@ -41,24 +41,24 @@ use oxc_traverse::{Traverse, TraverseCtx}; use ropey::Rope; use super::utils::get_line_column; -use crate::{context::Ctx, helpers::bindings::BoundIdentifier}; +use crate::{helpers::bindings::BoundIdentifier, TransformCtx}; const SOURCE: &str = "__source"; const FILE_NAME_VAR: &str = "jsxFileName"; -pub struct ReactJsxSource<'a> { +pub struct ReactJsxSource<'a, 'ctx> { filename_var: Option>, source_rope: Option, - ctx: Ctx<'a>, + ctx: &'ctx TransformCtx<'a>, } -impl<'a> ReactJsxSource<'a> { - pub fn new(ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> ReactJsxSource<'a, 'ctx> { + pub fn new(ctx: &'ctx TransformCtx<'a>) -> Self { Self { filename_var: None, source_rope: None, ctx } } } -impl<'a> Traverse<'a> for ReactJsxSource<'a> { +impl<'a, 'ctx> Traverse<'a> for ReactJsxSource<'a, 'ctx> { fn exit_program(&mut self, program: &mut Program<'a>, _ctx: &mut TraverseCtx<'a>) { if let Some(stmt) = self.get_var_file_name_statement() { program.body.insert(0, stmt); @@ -74,7 +74,7 @@ impl<'a> Traverse<'a> for ReactJsxSource<'a> { } } -impl<'a> ReactJsxSource<'a> { +impl<'a, 'ctx> ReactJsxSource<'a, 'ctx> { pub fn get_line_column(&mut self, offset: u32) -> (usize, usize) { if self.source_rope.is_none() { self.source_rope = Some(Rope::from_str(self.ctx.source_text)); diff --git a/crates/oxc_transformer/src/react/mod.rs b/crates/oxc_transformer/src/react/mod.rs index 9984c5525..26e7e194d 100644 --- a/crates/oxc_transformer/src/react/mod.rs +++ b/crates/oxc_transformer/src/react/mod.rs @@ -7,8 +7,6 @@ mod options; mod refresh; mod utils; -use std::rc::Rc; - use oxc_allocator::Vec; use oxc_ast::ast::*; use oxc_traverse::{Traverse, TraverseCtx}; @@ -19,7 +17,7 @@ pub use self::{ jsx::ReactJsx, options::{ReactJsxRuntime, ReactOptions, ReactRefreshOptions}, }; -use crate::context::Ctx; +use crate::TransformCtx; /// [Preset React](https://babel.dev/docs/babel-preset-react) /// @@ -29,10 +27,10 @@ use crate::context::Ctx; /// * [plugin-transform-react-jsx-self](https://babeljs.io/docs/babel-plugin-transform-react-jsx-self) /// * [plugin-transform-react-jsx-source](https://babel.dev/docs/babel-plugin-transform-react-jsx-source) /// * [plugin-transform-react-display-name](https://babeljs.io/docs/babel-plugin-transform-react-display-name) -pub struct React<'a> { - jsx: ReactJsx<'a>, - display_name: ReactDisplayName<'a>, - refresh: ReactRefresh<'a>, +pub struct React<'a, 'ctx> { + jsx: ReactJsx<'a, 'ctx>, + display_name: ReactDisplayName<'a, 'ctx>, + refresh: ReactRefresh<'a, 'ctx>, jsx_plugin: bool, display_name_plugin: bool, jsx_self_plugin: bool, @@ -41,10 +39,10 @@ pub struct React<'a> { } // Constructors -impl<'a> React<'a> { - pub fn new(mut options: ReactOptions, ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> React<'a, 'ctx> { + pub fn new(mut options: ReactOptions, ctx: &'ctx TransformCtx<'a>) -> Self { if options.jsx_plugin || options.development { - options.update_with_comments(&ctx); + options.update_with_comments(ctx); options.conform(); } let ReactOptions { @@ -56,8 +54,8 @@ impl<'a> React<'a> { } = options; let refresh = options.refresh.clone(); Self { - jsx: ReactJsx::new(options, Rc::clone(&ctx)), - display_name: ReactDisplayName::new(Rc::clone(&ctx)), + jsx: ReactJsx::new(options, ctx), + display_name: ReactDisplayName::new(ctx), jsx_plugin, display_name_plugin, jsx_self_plugin, @@ -68,7 +66,7 @@ impl<'a> React<'a> { } } -impl<'a> Traverse<'a> for React<'a> { +impl<'a, 'ctx> Traverse<'a> for React<'a, 'ctx> { fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) { if self.jsx_plugin { program.source_type = program.source_type.with_standard(true); diff --git a/crates/oxc_transformer/src/react/refresh.rs b/crates/oxc_transformer/src/react/refresh.rs index 4c1fcebbd..d870e8ec5 100644 --- a/crates/oxc_transformer/src/react/refresh.rs +++ b/crates/oxc_transformer/src/react/refresh.rs @@ -11,7 +11,7 @@ use rustc_hash::FxHashMap; use sha1::{Digest, Sha1}; use super::options::ReactRefreshOptions; -use crate::context::Ctx; +use crate::TransformCtx; /// Parse a string into a `RefreshIdentifierResolver` and convert it into an `Expression` #[derive(Debug)] @@ -94,11 +94,11 @@ impl<'a> RefreshIdentifierResolver<'a> { /// /// * /// * -pub struct ReactRefresh<'a> { +pub struct ReactRefresh<'a, 'ctx> { refresh_reg: RefreshIdentifierResolver<'a>, refresh_sig: RefreshIdentifierResolver<'a>, emit_full_signatures: bool, - ctx: Ctx<'a>, + ctx: &'ctx TransformCtx<'a>, // States registrations: Vec<(SymbolId, Atom<'a>)>, signature_declarator_items: Vec>>, @@ -111,8 +111,8 @@ pub struct ReactRefresh<'a> { non_builtin_hooks_callee: FxHashMap>>>, } -impl<'a> ReactRefresh<'a> { - pub fn new(options: &ReactRefreshOptions, ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> ReactRefresh<'a, 'ctx> { + pub fn new(options: &ReactRefreshOptions, ctx: &'ctx TransformCtx<'a>) -> Self { Self { refresh_reg: RefreshIdentifierResolver::parse(&options.refresh_reg, ctx.ast), refresh_sig: RefreshIdentifierResolver::parse(&options.refresh_sig, ctx.ast), @@ -128,7 +128,7 @@ impl<'a> ReactRefresh<'a> { } } -impl<'a> Traverse<'a> for ReactRefresh<'a> { +impl<'a, 'ctx> Traverse<'a> for ReactRefresh<'a, 'ctx> { fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) { let mut new_statements = ctx.ast.vec_with_capacity(program.body.len()); for mut statement in program.body.drain(..) { @@ -455,7 +455,7 @@ impl<'a> Traverse<'a> for ReactRefresh<'a> { } // Internal Methods -impl<'a> ReactRefresh<'a> { +impl<'a, 'ctx> ReactRefresh<'a, 'ctx> { fn create_registration( &mut self, persistent_id: Atom<'a>, diff --git a/crates/oxc_transformer/src/regexp/mod.rs b/crates/oxc_transformer/src/regexp/mod.rs index 1dc22f4e1..2fb433494 100644 --- a/crates/oxc_transformer/src/regexp/mod.rs +++ b/crates/oxc_transformer/src/regexp/mod.rs @@ -55,13 +55,13 @@ use oxc_semantic::ReferenceFlags; use oxc_span::{Atom, SPAN}; use oxc_traverse::{Traverse, TraverseCtx}; -use crate::context::Ctx; +use crate::TransformCtx; mod options; pub use options::RegExpOptions; -pub struct RegExp<'a> { - ctx: Ctx<'a>, +pub struct RegExp<'a, 'ctx> { + ctx: &'ctx TransformCtx<'a>, unsupported_flags: RegExpFlags, some_unsupported_patterns: bool, look_behind_assertions: bool, @@ -69,8 +69,8 @@ pub struct RegExp<'a> { unicode_property_escapes: bool, } -impl<'a> RegExp<'a> { - pub fn new(options: RegExpOptions, ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> RegExp<'a, 'ctx> { + pub fn new(options: RegExpOptions, ctx: &'ctx TransformCtx<'a>) -> Self { // Get unsupported flags let mut unsupported_flags = RegExpFlags::empty(); if options.dot_all_flag { @@ -111,7 +111,7 @@ impl<'a> RegExp<'a> { } } -impl<'a> Traverse<'a> for RegExp<'a> { +impl<'a, 'ctx> Traverse<'a> for RegExp<'a, 'ctx> { fn enter_expression( &mut self, expr: &mut Expression<'a>, @@ -190,7 +190,7 @@ impl<'a> Traverse<'a> for RegExp<'a> { } } -impl<'a> RegExp<'a> { +impl<'a, 'ctx> RegExp<'a, 'ctx> { /// Check if the regular expression contains any unsupported syntax. /// /// Based on parsed regular expression pattern. diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index 29650080d..66a0791cc 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -16,12 +16,12 @@ use oxc_syntax::{ use oxc_traverse::{Traverse, TraverseCtx}; use rustc_hash::FxHashSet; -use crate::{context::Ctx, TypeScriptOptions}; +use crate::{TransformCtx, TypeScriptOptions}; -pub struct TypeScriptAnnotations<'a> { +pub struct TypeScriptAnnotations<'a, 'ctx> { #[allow(dead_code)] options: Rc, - ctx: Ctx<'a>, + ctx: &'ctx TransformCtx<'a>, /// Assignments to be added to the constructor body assignments: Vec>, has_super_call: bool, @@ -33,8 +33,8 @@ pub struct TypeScriptAnnotations<'a> { type_identifier_names: FxHashSet>, } -impl<'a> TypeScriptAnnotations<'a> { - pub fn new(options: Rc, ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> TypeScriptAnnotations<'a, 'ctx> { + pub fn new(options: Rc, ctx: &'ctx TransformCtx<'a>) -> Self { let jsx_element_import_name = if options.jsx_pragma.contains('.') { options.jsx_pragma.split('.').next().map(String::from).unwrap() } else { @@ -60,7 +60,8 @@ impl<'a> TypeScriptAnnotations<'a> { } } } -impl<'a> Traverse<'a> for TypeScriptAnnotations<'a> { + +impl<'a, 'ctx> Traverse<'a> for TypeScriptAnnotations<'a, 'ctx> { 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; @@ -548,7 +549,7 @@ impl<'a> Traverse<'a> for TypeScriptAnnotations<'a> { } } -impl<'a> TypeScriptAnnotations<'a> { +impl<'a, 'ctx> TypeScriptAnnotations<'a, 'ctx> { /// 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 { diff --git a/crates/oxc_transformer/src/typescript/enum.rs b/crates/oxc_transformer/src/typescript/enum.rs index 9ca940c70..3099d9e0b 100644 --- a/crates/oxc_transformer/src/typescript/enum.rs +++ b/crates/oxc_transformer/src/typescript/enum.rs @@ -11,20 +11,20 @@ use oxc_syntax::{ use oxc_traverse::{Traverse, TraverseCtx}; use rustc_hash::FxHashMap; -use crate::context::Ctx; +use crate::TransformCtx; -pub struct TypeScriptEnum<'a> { - ctx: Ctx<'a>, +pub struct TypeScriptEnum<'a, 'ctx> { + ctx: &'ctx TransformCtx<'a>, enums: FxHashMap, FxHashMap, ConstantValue>>, } -impl<'a> TypeScriptEnum<'a> { - pub fn new(ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> TypeScriptEnum<'a, 'ctx> { + pub fn new(ctx: &'ctx TransformCtx<'a>) -> Self { Self { ctx, enums: FxHashMap::default() } } } -impl<'a> Traverse<'a> for TypeScriptEnum<'a> { +impl<'a, 'ctx> Traverse<'a> for TypeScriptEnum<'a, 'ctx> { fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) { let new_stmt = match stmt { Statement::TSEnumDeclaration(ts_enum_decl) => { @@ -47,7 +47,7 @@ impl<'a> Traverse<'a> for TypeScriptEnum<'a> { } } -impl<'a> TypeScriptEnum<'a> { +impl<'a, 'ctx> TypeScriptEnum<'a, 'ctx> { /// ```TypeScript /// enum Foo { /// X = 1, @@ -366,7 +366,7 @@ enum ConstantValue { String(String), } -impl<'a> TypeScriptEnum<'a> { +impl<'a, 'ctx> TypeScriptEnum<'a, 'ctx> { /// Evaluate the expression to a constant value. /// Refer to [babel](https://github.com/babel/babel/blob/610897a9a96c5e344e77ca9665df7613d2f88358/packages/babel-plugin-transform-typescript/src/enum.ts#L241C1-L394C2) fn computed_constant_value( diff --git a/crates/oxc_transformer/src/typescript/mod.rs b/crates/oxc_transformer/src/typescript/mod.rs index 3249610c7..8d42bb797 100644 --- a/crates/oxc_transformer/src/typescript/mod.rs +++ b/crates/oxc_transformer/src/typescript/mod.rs @@ -17,7 +17,7 @@ use rewrite_extensions::TypeScriptRewriteExtensions; pub use self::options::{RewriteExtensionsMode, TypeScriptOptions}; use self::{annotations::TypeScriptAnnotations, r#enum::TypeScriptEnum}; -use crate::context::Ctx; +use crate::TransformCtx; /// [Preset TypeScript](https://babeljs.io/docs/babel-preset-typescript) /// @@ -40,36 +40,36 @@ use crate::context::Ctx; /// /// In: `const x: number = 0;` /// Out: `const x = 0;` -pub struct TypeScript<'a> { +pub struct TypeScript<'a, 'ctx> { options: Rc, - ctx: Ctx<'a>, + ctx: &'ctx TransformCtx<'a>, - annotations: TypeScriptAnnotations<'a>, - r#enum: TypeScriptEnum<'a>, - namespace: TypeScriptNamespace<'a>, - module: TypeScriptModule<'a>, + annotations: TypeScriptAnnotations<'a, 'ctx>, + r#enum: TypeScriptEnum<'a, 'ctx>, + namespace: TypeScriptNamespace<'a, 'ctx>, + module: TypeScriptModule<'a, 'ctx>, rewrite_extensions: TypeScriptRewriteExtensions, } -impl<'a> TypeScript<'a> { - pub fn new(options: TypeScriptOptions, ctx: Ctx<'a>) -> Self { - let options = Rc::new(options.update_with_comments(&ctx)); +impl<'a, 'ctx> TypeScript<'a, 'ctx> { + pub fn new(options: TypeScriptOptions, ctx: &'ctx TransformCtx<'a>) -> Self { + let options = Rc::new(options.update_with_comments(ctx)); Self { - annotations: TypeScriptAnnotations::new(Rc::clone(&options), Rc::clone(&ctx)), - r#enum: TypeScriptEnum::new(Rc::clone(&ctx)), + annotations: TypeScriptAnnotations::new(Rc::clone(&options), ctx), + r#enum: TypeScriptEnum::new(ctx), 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)), + namespace: TypeScriptNamespace::new(Rc::clone(&options), ctx), + module: TypeScriptModule::new(ctx), options, ctx, } } } -impl<'a> Traverse<'a> for TypeScript<'a> { +impl<'a, 'ctx> Traverse<'a> for TypeScript<'a, 'ctx> { 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 diff --git a/crates/oxc_transformer/src/typescript/module.rs b/crates/oxc_transformer/src/typescript/module.rs index 9c2fe70ed..0762f756e 100644 --- a/crates/oxc_transformer/src/typescript/module.rs +++ b/crates/oxc_transformer/src/typescript/module.rs @@ -4,19 +4,19 @@ use oxc_span::SPAN; use oxc_syntax::reference::ReferenceFlags; use oxc_traverse::{Traverse, TraverseCtx}; -use crate::context::Ctx; +use crate::TransformCtx; -pub struct TypeScriptModule<'a> { - ctx: Ctx<'a>, +pub struct TypeScriptModule<'a, 'ctx> { + ctx: &'ctx TransformCtx<'a>, } -impl<'a> TypeScriptModule<'a> { - pub fn new(ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> TypeScriptModule<'a, 'ctx> { + pub fn new(ctx: &'ctx TransformCtx<'a>) -> Self { Self { ctx } } } -impl<'a> Traverse<'a> for TypeScriptModule<'a> { +impl<'a, 'ctx> Traverse<'a> for TypeScriptModule<'a, 'ctx> { /// ```TypeScript /// import b = babel; /// import AliasModule = LongNameModule; @@ -48,7 +48,7 @@ impl<'a> Traverse<'a> for TypeScriptModule<'a> { } } -impl<'a> TypeScriptModule<'a> { +impl<'a, 'ctx> TypeScriptModule<'a, 'ctx> { fn transform_ts_import_equals( &self, decl: &mut Box<'a, TSImportEqualsDeclaration<'a>>, diff --git a/crates/oxc_transformer/src/typescript/namespace.rs b/crates/oxc_transformer/src/typescript/namespace.rs index 8647f1994..f3e3c202d 100644 --- a/crates/oxc_transformer/src/typescript/namespace.rs +++ b/crates/oxc_transformer/src/typescript/namespace.rs @@ -15,20 +15,20 @@ use super::{ diagnostics::{ambient_module_nested, namespace_exporting_non_const, namespace_not_supported}, TypeScriptOptions, }; -use crate::context::Ctx; +use crate::TransformCtx; -pub struct TypeScriptNamespace<'a> { - ctx: Ctx<'a>, +pub struct TypeScriptNamespace<'a, 'ctx> { + ctx: &'ctx TransformCtx<'a>, options: Rc, } -impl<'a> TypeScriptNamespace<'a> { - pub fn new(options: Rc, ctx: Ctx<'a>) -> Self { +impl<'a, 'ctx> TypeScriptNamespace<'a, 'ctx> { + pub fn new(options: Rc, ctx: &'ctx TransformCtx<'a>) -> Self { Self { ctx, options } } } -impl<'a> Traverse<'a> for TypeScriptNamespace<'a> { +impl<'a, 'ctx> Traverse<'a> for TypeScriptNamespace<'a, 'ctx> { // `namespace Foo { }` -> `let Foo; (function (_Foo) { })(Foo || (Foo = {}));` fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) { // namespace declaration is only allowed at the top level @@ -139,7 +139,7 @@ impl<'a> Traverse<'a> for TypeScriptNamespace<'a> { } } -impl<'a> TypeScriptNamespace<'a> { +impl<'a, 'ctx> TypeScriptNamespace<'a, 'ctx> { fn handle_nested( &self, decl: TSModuleDeclaration<'a>,