diff --git a/Cargo.lock b/Cargo.lock index bf0300603ade..680eb662476b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1746,7 +1746,6 @@ dependencies = [ "napi-build", "napi-derive", "oxc_allocator", - "oxc_ast", "oxc_codegen", "oxc_diagnostics", "oxc_isolated_declarations", diff --git a/crates/oxc_codegen/examples/codegen.rs b/crates/oxc_codegen/examples/codegen.rs index 46ce7c7c316e..d4d252e44cde 100644 --- a/crates/oxc_codegen/examples/codegen.rs +++ b/crates/oxc_codegen/examples/codegen.rs @@ -2,7 +2,7 @@ use std::{env, path::Path}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::{CodeGenerator, WhitespaceRemover}; use oxc_parser::Parser; use oxc_span::SourceType; @@ -29,16 +29,11 @@ fn main() -> std::io::Result<()> { println!("Original:"); println!("{source_text}"); - let options = CodegenOptions::default(); - let printed = Codegen::::new("", &source_text, ret.trivias.clone(), options) - .build(&ret.program) - .source_text; + let printed = CodeGenerator::new().build(&ret.program).source_text; println!("Printed:"); println!("{printed}"); - let minified = Codegen::::new("", &source_text, ret.trivias, options) - .build(&ret.program) - .source_text; + let minified = WhitespaceRemover::new().build(&ret.program).source_text; println!("Minified:"); println!("{minified}"); diff --git a/crates/oxc_codegen/examples/sourcemap.rs b/crates/oxc_codegen/examples/sourcemap.rs index 6d0cddfd4e0f..5df8a8c07377 100644 --- a/crates/oxc_codegen/examples/sourcemap.rs +++ b/crates/oxc_codegen/examples/sourcemap.rs @@ -3,7 +3,7 @@ use std::{env, path::Path}; use base64::{prelude::BASE64_STANDARD, Engine}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions, CodegenReturn}; +use oxc_codegen::{CodeGenerator, CodegenReturn}; use oxc_parser::Parser; use oxc_span::SourceType; @@ -27,15 +27,9 @@ fn main() -> std::io::Result<()> { return Ok(()); } - let codegen_options = CodegenOptions { enable_source_map: true, ..Default::default() }; - - let CodegenReturn { source_text, source_map } = Codegen::::new( - path.to_string_lossy().as_ref(), - &source_text, - ret.trivias, - codegen_options, - ) - .build(&ret.program); + let CodegenReturn { source_text, source_map } = CodeGenerator::new() + .enable_source_map(path.to_string_lossy().as_ref(), &source_text) + .build(&ret.program); if let Some(source_map) = source_map { let result = source_map.to_json_string().unwrap(); diff --git a/crates/oxc_codegen/src/annotation_comment.rs b/crates/oxc_codegen/src/annotation_comment.rs index f433032f2128..8ac820e9f456 100644 --- a/crates/oxc_codegen/src/annotation_comment.rs +++ b/crates/oxc_codegen/src/annotation_comment.rs @@ -55,7 +55,7 @@ pub fn print_comment( } pub fn gen_comment(node_start: u32, codegen: &mut Codegen<{ MINIFY }>) { - if !codegen.options.preserve_annotate_comments { + if !codegen.comment_options.preserve_annotate_comments { return; } if let Some((comment_start, comment)) = codegen.try_take_moved_comment(node_start) { diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index c05efabd59f8..dd6403172144 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -11,7 +11,7 @@ use oxc_syntax::{ }; use crate::annotation_comment::{gen_comment, get_leading_annotate_comment}; -use crate::{Codegen, Context, Operator, Separator}; +use crate::{Codegen, Context, Operator}; pub trait Gen { fn gen(&self, _p: &mut Codegen<{ MINIFY }>, _ctx: Context) {} @@ -591,7 +591,7 @@ impl<'a, const MINIFY: bool> Gen for VariableDeclaration<'a> { p.print_str(b"declare "); } - if p.options.preserve_annotate_comments + if p.comment_options.preserve_annotate_comments && matches!(self.kind, VariableDeclarationKind::Const) { if let Some(declarator) = self.declarations.first() { @@ -823,7 +823,9 @@ impl<'a, const MINIFY: bool> Gen for WithClause<'a> { p.add_source_mapping(self.span.start); self.attributes_keyword.gen(p, ctx); p.print_soft_space(); - p.print_block(&self.with_entries, Separator::Comma, ctx, self.span); + p.print_block_start(self.span.start); + p.print_sequence(&self.with_entries, ctx); + p.print_block_end(self.span.end); } } @@ -845,7 +847,7 @@ impl<'a, const MINIFY: bool> Gen for ExportNamedDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); p.print_indent(); - if p.options.preserve_annotate_comments { + if p.comment_options.preserve_annotate_comments { match &self.declaration { Some(Declaration::FunctionDeclaration(_)) => { gen_comment(self.span.start, p); diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index 3c7844fe13b9..0a09d94bf9f8 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -1,10 +1,5 @@ //! Oxc Codegen //! -//! Supports -//! -//! * whitespace removal -//! * sourcemaps -//! //! Code adapted from //! * [esbuild](https://github.com/evanw/esbuild/blob/main/internal/js_printer/js_printer.go) @@ -16,8 +11,9 @@ mod sourcemap_builder; use std::{borrow::Cow, ops::Range}; -#[allow(clippy::wildcard_imports)] -use oxc_ast::ast::*; +use rustc_hash::FxHashMap; + +use oxc_ast::ast::{BlockStatement, Directive, Expression, Program, Statement}; use oxc_ast::{Comment, Trivias}; use oxc_span::{Atom, Span}; use oxc_syntax::{ @@ -26,23 +22,23 @@ use oxc_syntax::{ precedence::Precedence, symbol::SymbolId, }; -use rustc_hash::FxHashMap; -use sourcemap_builder::SourcemapBuilder; + +use crate::operator::Operator; +use crate::sourcemap_builder::SourcemapBuilder; pub use crate::{ context::Context, gen::{Gen, GenExpr}, - operator::Operator, }; -// use crate::mangler::Mangler; -pub type MoveCommentMap = FxHashMap; +/// Code generator without whitespace removal. +pub type CodeGenerator<'a> = Codegen<'a, false>; -#[derive(Debug, Default, Clone, Copy)] -pub struct CodegenOptions { - /// Pass in the filename to enable source map support. - pub enable_source_map: bool, +/// Code generator with whitespace removal. +pub type WhitespaceRemover<'a> = Codegen<'a, true>; +#[derive(Default, Clone, Copy)] +pub struct CommentOptions { /// Enable preserve annotate comments, like `/* #__PURE__ */` and `/* #__NO_SIDE_EFFECTS__ */`. pub preserve_annotate_comments: bool, } @@ -52,31 +48,13 @@ pub struct CodegenReturn { pub source_map: Option, } -impl From for String { - fn from(val: CodegenReturn) -> Self { - val.source_text - } -} - -impl<'a, const MINIFY: bool> From> for String { - fn from(mut val: Codegen<'a, MINIFY>) -> Self { - val.into_source_text() - } -} -impl<'a, const MINIFY: bool> From> for Cow<'a, str> { - fn from(mut val: Codegen<'a, MINIFY>) -> Self { - Cow::Owned(val.into_source_text()) - } -} - pub struct Codegen<'a, const MINIFY: bool> { - options: CodegenOptions, + comment_options: CommentOptions, source_text: &'a str, trivias: Trivias, - // mangler: Option, /// Output Code code: Vec, @@ -107,37 +85,33 @@ pub struct Codegen<'a, const MINIFY: bool> { move_comment_map: MoveCommentMap, } -#[derive(Debug, Clone, Copy)] -pub enum Separator { - Comma, - Semicolon, - None, +impl<'a, const MINIFY: bool> Default for Codegen<'a, MINIFY> { + fn default() -> Self { + Self::new() + } } -impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { - pub fn new( - source_name: &str, - source_text: &'a str, - trivias: Trivias, - options: CodegenOptions, - ) -> Self { - // Initialize the output code buffer to reduce memory reallocation. - // Minification will reduce by at least half of the original size. - let source_len = source_text.len(); - let capacity = if MINIFY { source_len / 2 } else { source_len }; - - let sourcemap_builder = options.enable_source_map.then(|| { - let mut sourcemap_builder = SourcemapBuilder::default(); - sourcemap_builder.with_name_and_source(source_name, source_text); - sourcemap_builder - }); +impl<'a, const MINIFY: bool> From> for String { + fn from(mut val: Codegen<'a, MINIFY>) -> Self { + val.into_source_text() + } +} + +impl<'a, const MINIFY: bool> From> for Cow<'a, str> { + fn from(mut val: Codegen<'a, MINIFY>) -> Self { + Cow::Owned(val.into_source_text()) + } +} +// Public APIs +impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { + #[must_use] + pub fn new() -> Self { Self { - options, - source_text, - trivias, - // mangler: None, - code: Vec::with_capacity(capacity), + comment_options: CommentOptions::default(), + source_text: "", + trivias: Trivias::default(), + code: vec![], needs_semicolon: false, need_space_before_dot: 0, print_next_indent_as_space: false, @@ -148,15 +122,42 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { start_of_arrow_expr: 0, start_of_default_export: 0, indent: 0, - sourcemap_builder, + sourcemap_builder: None, move_comment_map: MoveCommentMap::default(), } } - // fn with_mangler(&mut self, mangler: Mangler) { - // self.mangler = Some(mangler); - // } + #[must_use] + pub fn enable_comment( + mut self, + source_text: &'a str, + trivias: Trivias, + options: CommentOptions, + ) -> Self { + self.source_text = source_text; + self.trivias = trivias; + self.comment_options = options; + self + } + + #[must_use] + pub fn enable_source_map(mut self, source_name: &str, source_text: &str) -> Self { + let mut sourcemap_builder = SourcemapBuilder::default(); + sourcemap_builder.with_name_and_source(source_name, source_text); + self.sourcemap_builder = Some(sourcemap_builder); + self + } + + /// Initialize the output code buffer to reduce memory reallocation. + /// Minification will reduce by at least half of the original size. + #[must_use] + pub fn with_capacity(mut self, source_text_len: usize) -> Self { + let capacity = if MINIFY { source_text_len / 2 } else { source_text_len }; + self.code = Vec::with_capacity(capacity); + self + } + #[must_use] pub fn build(mut self, program: &Program<'_>) -> CodegenReturn { program.gen(&mut self, Context::default()); let source_text = self.into_source_text(); @@ -164,6 +165,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { CodegenReturn { source_text, source_map } } + #[must_use] pub fn into_source_text(&mut self) -> String { // SAFETY: criteria of `from_utf8_unchecked` are met. #[allow(unsafe_code)] @@ -172,14 +174,6 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { } } - fn code(&self) -> &Vec { - &self.code - } - - fn code_len(&self) -> usize { - self.code().len() - } - /// Push a single character into the buffer pub fn print(&mut self, ch: u8) { self.code.push(ch); @@ -189,41 +183,16 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { pub fn print_str>(&mut self, s: T) { self.code.extend_from_slice(s.as_ref()); } +} - /// This method to avoid rustc borrow checker issue. - /// Since if you want to print a range of source code, you need to borrow the source code - /// immutable first, and call the [Self::print_str] which is a mutable borrow. - pub fn print_range_of_source_code(&mut self, range: Range) { - self.code.extend_from_slice(self.source_text[range].as_bytes()); - } - - /// In some scenario, we want to move the comment that should be codegened to another position. - /// ```js - /// /* @__NO_SIDE_EFFECTS__ */ export const a = function() { - /// - /// }, b = 10000; - /// - /// ``` - /// should generate such output: - /// ```js - /// export const /* @__NO_SIDE_EFFECTS__ */ a = function() { - /// - /// }, b = 10000; - /// ``` - pub fn move_comment(&mut self, position: u32, full_comment_info: (u32, Comment)) { - self.move_comment_map.insert(position, full_comment_info); - } - - pub fn try_get_leading_comment(&self, start: u32) -> Option<(&u32, &Comment)> { - self.trivias.comments_range(0..start).next_back() - } - - pub fn try_take_moved_comment(&mut self, node_start: u32) -> Option<(u32, Comment)> { - self.move_comment_map.remove(&node_start) +// Private APIs +impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { + fn code(&self) -> &Vec { + &self.code } - pub fn try_get_leading_comment_from_move_map(&self, start: u32) -> Option<&(u32, Comment)> { - self.move_comment_map.get(&start) + fn code_len(&self) -> usize { + self.code().len() } #[inline] @@ -331,14 +300,10 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { self.print(b'='); } - fn print_sequence>(&mut self, items: &[T], separator: Separator, ctx: Context) { + fn print_sequence>(&mut self, items: &[T], ctx: Context) { for item in items { item.gen(self, ctx); - match separator { - Separator::Semicolon => self.print_semicolon(), - Separator::Comma => self.print(b','), - Separator::None => {} - } + self.print_comma(); } } @@ -400,18 +365,6 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { self.needs_semicolon = false; } - fn print_block>( - &mut self, - items: &[T], - separator: Separator, - ctx: Context, - span: Span, - ) { - self.print_block_start(span.start); - self.print_sequence(items, separator, ctx); - self.print_block_end(span.end); - } - fn print_list>(&mut self, items: &[T], ctx: Context) { for (index, item) in items.iter().enumerate() { if index != 0 { @@ -499,7 +452,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { #[inline] fn wrap_quote(&mut self, s: &str, mut f: F) { - let quote = choose_quote(s); + let quote = Self::choose_quote(s); self.print(quote as u8); f(self, quote); self.print(quote as u8); @@ -543,22 +496,59 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { sourcemap_builder.add_source_mapping_for_name(&self.code, span, name); } } -} -fn choose_quote(s: &str) -> char { - let mut single_cost = 0; - let mut double_cost = 0; - for c in s.chars() { - match c { - '\'' => single_cost += 1, - '"' => double_cost += 1, - _ => {} + fn choose_quote(s: &str) -> char { + let mut single_cost = 0; + let mut double_cost = 0; + for c in s.chars() { + match c { + '\'' => single_cost += 1, + '"' => double_cost += 1, + _ => {} + } } + + if single_cost > double_cost { + '"' + } else { + '\'' + } + } +} + +pub(crate) type MoveCommentMap = FxHashMap; + +// Comment related +impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { + /// This method to avoid rustc borrow checker issue. + /// Since if you want to print a range of source code, you need to borrow the source code + /// immutable first, and call the [Self::print_str] which is a mutable borrow. + fn print_range_of_source_code(&mut self, range: Range) { + self.code.extend_from_slice(self.source_text[range].as_bytes()); } - if single_cost > double_cost { - '"' - } else { - '\'' + /// In some scenario, we want to move the comment that should be codegened to another position. + /// ```js + /// /* @__NO_SIDE_EFFECTS__ */ export const a = function() { + /// + /// }, b = 10000; + /// + /// ``` + /// should generate such output: + /// ```js + /// export const /* @__NO_SIDE_EFFECTS__ */ a = function() { + /// + /// }, b = 10000; + /// ``` + fn move_comment(&mut self, position: u32, full_comment_info: (u32, Comment)) { + self.move_comment_map.insert(position, full_comment_info); + } + + fn try_get_leading_comment(&self, start: u32) -> Option<(&u32, &Comment)> { + self.trivias.comments_range(0..start).next_back() + } + + fn try_take_moved_comment(&mut self, node_start: u32) -> Option<(u32, Comment)> { + self.move_comment_map.remove(&node_start) } } diff --git a/crates/oxc_codegen/tests/mod.rs b/crates/oxc_codegen/tests/mod.rs index 658d4a76bb5b..1499fc8ae6e2 100644 --- a/crates/oxc_codegen/tests/mod.rs +++ b/crates/oxc_codegen/tests/mod.rs @@ -1,16 +1,13 @@ use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::{CodeGenerator, CommentOptions}; use oxc_parser::Parser; use oxc_span::SourceType; -fn test(source_text: &str, expected: &str, options: Option) { +fn test(source_text: &str, expected: &str) { let allocator = Allocator::default(); let source_type = SourceType::default().with_module(true); let ret = Parser::new(&allocator, source_text, source_type).parse(); - let options = options.unwrap_or_default(); - let result = Codegen::::new("", source_text, ret.trivias, options) - .build(&ret.program) - .source_text; + let result = CodeGenerator::new().build(&ret.program).source_text; assert_eq!(expected, result, "for source {source_text}, expect {expected}, got {result}"); } @@ -21,49 +18,46 @@ fn test_ts(source_text: &str, expected: &str, is_typescript_definition: bool) { .with_typescript_definition(is_typescript_definition) .with_module(true); let ret = Parser::new(&allocator, source_text, source_type).parse(); - let codegen_options = CodegenOptions::default(); - let result = Codegen::::new("", source_text, ret.trivias, codegen_options) - .build(&ret.program) - .source_text; + let result = CodeGenerator::new().build(&ret.program).source_text; assert_eq!(expected, result, "for source {source_text}, expect {expected}, got {result}"); } #[test] fn string() { - test("let x = ''", "let x = '';\n", None); - test(r"let x = '\b'", "let x = '\\b';\n", None); - test(r"let x = '\f'", "let x = '\\f';\n", None); - test("let x = '\t'", "let x = '\t';\n", None); - test(r"let x = '\v'", "let x = '\\v';\n", None); - test("let x = '\\n'", "let x = '\\n';\n", None); - test("let x = '\\''", "let x = \"'\";\n", None); - test("let x = '\\\"'", "let x = '\"';\n", None); - // test( "let x = '\\'''", "let x = `''`;\n", None); - test("let x = '\\\\'", "let x = '\\\\';\n", None); - test("let x = '\x00'", "let x = '\\0';\n", None); - test("let x = '\x00!'", "let x = '\\0!';\n", None); - test("let x = '\x001'", "let x = '\\x001';\n", None); - test("let x = '\\0'", "let x = '\\0';\n", None); - test("let x = '\\0!'", "let x = '\\0!';\n", None); - test("let x = '\x07'", "let x = '\\x07';\n", None); - test("let x = '\x07!'", "let x = '\\x07!';\n", None); - test("let x = '\x071'", "let x = '\\x071';\n", None); - test("let x = '\\7'", "let x = '\\x07';\n", None); - test("let x = '\\7!'", "let x = '\\x07!';\n", None); - test("let x = '\\01'", "let x = '\x01';\n", None); - test("let x = '\x10'", "let x = '\x10';\n", None); - test("let x = '\\x10'", "let x = '\x10';\n", None); - test("let x = '\x1B'", "let x = '\\x1B';\n", None); - test("let x = '\\x1B'", "let x = '\\x1B';\n", None); - test("let x = '\\uABCD'", "let x = 'ꯍ';\n", None); - // test( "let x = '\\uABCD'", r#"let x = '\uABCD';\n"#, None); - // test( r#"let x = '\U000123AB'"#, r#"let x = '\U000123AB';\n"#, None); - // test( "let x = '\\u{123AB}'", r#"let x = '\U000123AB';\n"#, None); - // test( "let x = '\\uD808\\uDFAB'", r#"let x = '\U000123AB';\n"#, None); - test("let x = '\\uD808'", "let x = '\\\\ud808';\n", None); - test("let x = '\\uD808X'", "let x = '\\\\ud808X';\n", None); - test("let x = '\\uDFAB'", "let x = '\\\\udfab';\n", None); - test("let x = '\\uDFABX'", "let x = '\\\\udfabX';\n", None); + test("let x = ''", "let x = '';\n"); + test(r"let x = '\b'", "let x = '\\b';\n"); + test(r"let x = '\f'", "let x = '\\f';\n"); + test("let x = '\t'", "let x = '\t';\n"); + test(r"let x = '\v'", "let x = '\\v';\n"); + test("let x = '\\n'", "let x = '\\n';\n"); + test("let x = '\\''", "let x = \"'\";\n"); + test("let x = '\\\"'", "let x = '\"';\n"); + // test( "let x = '\\'''", "let x = `''`;\n"); + test("let x = '\\\\'", "let x = '\\\\';\n"); + test("let x = '\x00'", "let x = '\\0';\n"); + test("let x = '\x00!'", "let x = '\\0!';\n"); + test("let x = '\x001'", "let x = '\\x001';\n"); + test("let x = '\\0'", "let x = '\\0';\n"); + test("let x = '\\0!'", "let x = '\\0!';\n"); + test("let x = '\x07'", "let x = '\\x07';\n"); + test("let x = '\x07!'", "let x = '\\x07!';\n"); + test("let x = '\x071'", "let x = '\\x071';\n"); + test("let x = '\\7'", "let x = '\\x07';\n"); + test("let x = '\\7!'", "let x = '\\x07!';\n"); + test("let x = '\\01'", "let x = '\x01';\n"); + test("let x = '\x10'", "let x = '\x10';\n"); + test("let x = '\\x10'", "let x = '\x10';\n"); + test("let x = '\x1B'", "let x = '\\x1B';\n"); + test("let x = '\\x1B'", "let x = '\\x1B';\n"); + test("let x = '\\uABCD'", "let x = 'ꯍ';\n"); + // test( "let x = '\\uABCD'", r#"let x = '\uABCD';\n"#); + // test( r#"let x = '\U000123AB'"#, r#"let x = '\U000123AB';\n"#); + // test( "let x = '\\u{123AB}'", r#"let x = '\U000123AB';\n"#); + // test( "let x = '\\uD808\\uDFAB'", r#"let x = '\U000123AB';\n"#); + test("let x = '\\uD808'", "let x = '\\\\ud808';\n"); + test("let x = '\\uD808X'", "let x = '\\\\ud808X';\n"); + test("let x = '\\uDFAB'", "let x = '\\\\udfab';\n"); + test("let x = '\\uDFABX'", "let x = '\\\\udfabX';\n"); // test( "let x = '\\x80'", r#"let x = '\U00000080';\n"#); // test( "let x = '\\xFF'", r#"let x = '\U000000FF';\n"#); @@ -73,72 +67,72 @@ fn string() { #[test] fn template() { - test("let x = `\\0`", "let x = `\\0`;\n", None); - test("let x = `\\x01`", "let x = `\\x01`;\n", None); - test("let x = `\\0${0}`", "let x = `\\0${0}`;\n", None); - // test("let x = `\\x01${0}`", "let x = `\x01${0}`;\n", None); - test("let x = `${0}\\0`", "let x = `${0}\\0`;\n", None); - // test("let x = `${0}\\x01`", "let x = `${0}\x01`;\n", None); - test("let x = `${0}\\0${1}`", "let x = `${0}\\0${1}`;\n", None); - // test("let x = `${0}\\x01${1}`", "let x = `${0}\x01${1}`;\n", None); + test("let x = `\\0`", "let x = `\\0`;\n"); + test("let x = `\\x01`", "let x = `\\x01`;\n"); + test("let x = `\\0${0}`", "let x = `\\0${0}`;\n"); + // test("let x = `\\x01${0}`", "let x = `\x01${0}`;\n"); + test("let x = `${0}\\0`", "let x = `${0}\\0`;\n"); + // test("let x = `${0}\\x01`", "let x = `${0}\x01`;\n"); + test("let x = `${0}\\0${1}`", "let x = `${0}\\0${1}`;\n"); + // test("let x = `${0}\\x01${1}`", "let x = `${0}\x01${1}`;\n"); - test("let x = String.raw`\\1`", "let x = String.raw`\\1`;\n", None); - test("let x = String.raw`\\x01`", "let x = String.raw`\\x01`;\n", None); - test("let x = String.raw`\\1${0}`", "let x = String.raw`\\1${0}`;\n", None); - test("let x = String.raw`\\x01${0}`", "let x = String.raw`\\x01${0}`;\n", None); - test("let x = String.raw`${0}\\1`", "let x = String.raw`${0}\\1`;\n", None); - test("let x = String.raw`${0}\\x01`", "let x = String.raw`${0}\\x01`;\n", None); - test("let x = String.raw`${0}\\1${1}`", "let x = String.raw`${0}\\1${1}`;\n", None); - test("let x = String.raw`${0}\\x01${1}`", "let x = String.raw`${0}\\x01${1}`;\n", None); + test("let x = String.raw`\\1`", "let x = String.raw`\\1`;\n"); + test("let x = String.raw`\\x01`", "let x = String.raw`\\x01`;\n"); + test("let x = String.raw`\\1${0}`", "let x = String.raw`\\1${0}`;\n"); + test("let x = String.raw`\\x01${0}`", "let x = String.raw`\\x01${0}`;\n"); + test("let x = String.raw`${0}\\1`", "let x = String.raw`${0}\\1`;\n"); + test("let x = String.raw`${0}\\x01`", "let x = String.raw`${0}\\x01`;\n"); + test("let x = String.raw`${0}\\1${1}`", "let x = String.raw`${0}\\1${1}`;\n"); + test("let x = String.raw`${0}\\x01${1}`", "let x = String.raw`${0}\\x01${1}`;\n"); - test("let x = `${y}`", "let x = `${y}`;\n", None); - test("let x = `$(y)`", "let x = `$(y)`;\n", None); - test("let x = `{y}$`", "let x = `{y}$`;\n", None); - test("let x = `$}y{`", "let x = `$}y{`;\n", None); - test("let x = `\\${y}`", "let x = `\\${y}`;\n", None); - // test("let x = `$\\{y}`", "let x = `\\${y}`;\n", None); + test("let x = `${y}`", "let x = `${y}`;\n"); + test("let x = `$(y)`", "let x = `$(y)`;\n"); + test("let x = `{y}$`", "let x = `{y}$`;\n"); + test("let x = `$}y{`", "let x = `$}y{`;\n"); + test("let x = `\\${y}`", "let x = `\\${y}`;\n"); + // test("let x = `$\\{y}`", "let x = `\\${y}`;\n"); - test("await tag`x`", "await tag`x`;\n", None); - test("await (tag`x`)", "await tag`x`;\n", None); - test("(await tag)`x`", "(await tag)`x`;\n", None); + test("await tag`x`", "await tag`x`;\n"); + test("await (tag`x`)", "await tag`x`;\n"); + test("(await tag)`x`", "(await tag)`x`;\n"); - test("await tag`${x}`", "await tag`${x}`;\n", None); - test("await (tag`${x}`)", "await tag`${x}`;\n", None); - test("(await tag)`${x}`", "(await tag)`${x}`;\n", None); + test("await tag`${x}`", "await tag`${x}`;\n"); + test("await (tag`${x}`)", "await tag`${x}`;\n"); + test("(await tag)`${x}`", "(await tag)`${x}`;\n"); - test("new tag`x`", "new tag`x`();\n", None); - test("new (tag`x`)", "new tag`x`();\n", None); - test("new tag()`x`", "new tag()`x`;\n", None); - test("(new tag)`x`", "new tag()`x`;\n", None); + test("new tag`x`", "new tag`x`();\n"); + test("new (tag`x`)", "new tag`x`();\n"); + test("new tag()`x`", "new tag()`x`;\n"); + test("(new tag)`x`", "new tag()`x`;\n"); - test("new tag`${x}`", "new tag`${x}`();\n", None); - test("new (tag`${x}`)", "new tag`${x}`();\n", None); - test("new tag()`${x}`", "new tag()`${x}`;\n", None); - test("(new tag)`${x}`", "new tag()`${x}`;\n", None); + test("new tag`${x}`", "new tag`${x}`();\n"); + test("new (tag`${x}`)", "new tag`${x}`();\n"); + test("new tag()`${x}`", "new tag()`${x}`;\n"); + test("(new tag)`${x}`", "new tag()`${x}`;\n"); } #[test] fn module_decl() { - test("export * as foo from 'foo'", "export * as foo from 'foo';\n", None); - test("import x from './foo.js' with {}", "import x from './foo.js' with {\n};\n", None); - test("import {} from './foo.js' with {}", "import {} from './foo.js' with {\n};\n", None); - test("export * from './foo.js' with {}", "export * from './foo.js' with {\n};\n", None); + test("export * as foo from 'foo'", "export * as foo from 'foo';\n"); + test("import x from './foo.js' with {}", "import x from './foo.js' with {\n};\n"); + test("import {} from './foo.js' with {}", "import {} from './foo.js' with {\n};\n"); + test("export * from './foo.js' with {}", "export * from './foo.js' with {\n};\n"); } #[test] fn new_expr() { - test("new (foo()).bar();", "new (foo()).bar();\n", None); + test("new (foo()).bar();", "new (foo()).bar();\n"); } #[test] fn for_stmt() { - test("for (let x = 0; x < 10; x++) {}", "for (let x = 0; x < 10; x++) {}\n", None); - test("for (;;) {}", "for (;;) {}\n", None); - test("for (let x = 1;;) {}", "for (let x = 1;;) {}\n", None); - test("for (;true;) {}", "for (; true;) {}\n", None); - test("for (;;i++) {}", "for (;; i++) {}\n", None); + test("for (let x = 0; x < 10; x++) {}", "for (let x = 0; x < 10; x++) {}\n"); + test("for (;;) {}", "for (;;) {}\n"); + test("for (let x = 1;;) {}", "for (let x = 1;;) {}\n"); + test("for (;true;) {}", "for (; true;) {}\n"); + test("for (;;i++) {}", "for (;; i++) {}\n"); - test("for (using x = 1;;) {}", "for (using x = 1;;) {}\n", None); + test("for (using x = 1;;) {}", "for (using x = 1;;) {}\n"); } #[test] @@ -190,12 +184,20 @@ fn typescript() { } fn test_comment_helper(source_text: &str, expected: &str) { - test( - source_text, - expected, - Some(CodegenOptions { enable_source_map: true, preserve_annotate_comments: true }), - ); + let allocator = Allocator::default(); + let source_type = SourceType::default().with_module(true); + let ret = Parser::new(&allocator, source_text, source_type).parse(); + let result = CodeGenerator::new() + .enable_comment( + source_text, + ret.trivias, + CommentOptions { preserve_annotate_comments: true }, + ) + .build(&ret.program) + .source_text; + assert_eq!(expected, result, "for source {source_text}, expect {expected}, got {result}"); } + #[test] fn annotate_comment() { test_comment_helper( @@ -337,8 +339,8 @@ const c2 = /* #__NO_SIDE_EFFECTS__ */ () => {}, c3 = () => {}; #[test] fn unicode_escape() { - test("console.log('你好');", "console.log('你好');\n", None); - test("console.log('こんにちは');", "console.log('こんにちは');\n", None); - test("console.log('안녕하세요');", "console.log('안녕하세요');\n", None); - test("console.log('🧑‍🤝‍🧑');", "console.log('🧑‍🤝‍🧑');\n", None); + test("console.log('你好');", "console.log('你好');\n"); + test("console.log('こんにちは');", "console.log('こんにちは');\n"); + test("console.log('안녕하세요');", "console.log('안녕하세요');\n"); + test("console.log('🧑‍🤝‍🧑');", "console.log('🧑‍🤝‍🧑');\n"); } diff --git a/crates/oxc_isolated_declarations/examples/isolated_declarations.rs b/crates/oxc_isolated_declarations/examples/isolated_declarations.rs index aa3544e17057..6660571c14f9 100644 --- a/crates/oxc_isolated_declarations/examples/isolated_declarations.rs +++ b/crates/oxc_isolated_declarations/examples/isolated_declarations.rs @@ -2,8 +2,7 @@ use std::{env, path::Path}; use oxc_allocator::Allocator; -use oxc_ast::Trivias; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_isolated_declarations::IsolatedDeclarations; use oxc_parser::Parser; use oxc_span::SourceType; @@ -34,10 +33,7 @@ fn main() { println!("{source_text}\n"); let ret = IsolatedDeclarations::new(&allocator).build(&ret.program); - let printed = - Codegen::::new("", &source_text, Trivias::default(), CodegenOptions::default()) - .build(&ret.program) - .source_text; + let printed = CodeGenerator::new().build(&ret.program).source_text; println!("Dts Emit:\n"); println!("{printed}\n"); diff --git a/crates/oxc_linter/src/fixer.rs b/crates/oxc_linter/src/fixer.rs index 99471fdd3e47..1913f101a9e4 100644 --- a/crates/oxc_linter/src/fixer.rs +++ b/crates/oxc_linter/src/fixer.rs @@ -1,7 +1,6 @@ use std::borrow::Cow; -use oxc_ast::Trivias; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::Codegen; use oxc_diagnostics::OxcDiagnostic; use oxc_span::{GetSpan, Span}; @@ -65,7 +64,7 @@ impl<'c, 'a: 'c> RuleFixer<'c, 'a> { #[allow(clippy::unused_self)] pub fn codegen(self) -> Codegen<'a, false> { - Codegen::::new("", "", Trivias::default(), CodegenOptions::default()) + Codegen::::new() } } diff --git a/crates/oxc_minifier/examples/minifier.rs b/crates/oxc_minifier/examples/minifier.rs index 7d0decf0703e..d4a9fd97431f 100644 --- a/crates/oxc_minifier/examples/minifier.rs +++ b/crates/oxc_minifier/examples/minifier.rs @@ -2,7 +2,7 @@ use std::path::Path; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::{CodeGenerator, WhitespaceRemover}; use oxc_minifier::{Minifier, MinifierOptions}; use oxc_parser::Parser; use oxc_span::SourceType; @@ -44,10 +44,9 @@ fn minify(source_text: &str, source_type: SourceType, mangle: bool, whitespace: let options = MinifierOptions { mangle, ..MinifierOptions::default() }; Minifier::new(options).build(&allocator, program); if whitespace { - Codegen::::new("", source_text, ret.trivias, CodegenOptions::default()).build(program) + WhitespaceRemover::new().build(program) } else { - Codegen::::new("", source_text, ret.trivias, CodegenOptions::default()) - .build(program) + CodeGenerator::new().build(program) } .source_text } diff --git a/crates/oxc_minifier/tests/mod.rs b/crates/oxc_minifier/tests/mod.rs index 572d3e0a991d..94578b542d50 100644 --- a/crates/oxc_minifier/tests/mod.rs +++ b/crates/oxc_minifier/tests/mod.rs @@ -5,7 +5,7 @@ mod tdewolff; mod terser; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::WhitespaceRemover; use oxc_minifier::{CompressOptions, Minifier, MinifierOptions}; use oxc_parser::Parser; use oxc_span::SourceType; @@ -19,9 +19,7 @@ pub(crate) fn minify( let ret = Parser::new(&allocator, source_text, source_type).parse(); let program = allocator.alloc(ret.program); Minifier::new(options).build(&allocator, program); - Codegen::::new("", source_text, ret.trivias, CodegenOptions::default()) - .build(program) - .source_text + WhitespaceRemover::new().build(program).source_text } pub(crate) fn test(source_text: &str, expected: &str) { diff --git a/crates/oxc_transformer/examples/transformer.rs b/crates/oxc_transformer/examples/transformer.rs index c6c5e96f9cf0..38e0e227bd0d 100644 --- a/crates/oxc_transformer/examples/transformer.rs +++ b/crates/oxc_transformer/examples/transformer.rs @@ -2,7 +2,7 @@ use std::{env, path::Path}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_parser::Parser; use oxc_span::SourceType; use oxc_transformer::{ @@ -57,9 +57,7 @@ fn main() { ) .build(&mut program); - let printed = Codegen::::new("", &source_text, ret.trivias, CodegenOptions::default()) - .build(&program) - .source_text; + let printed = CodeGenerator::new().build(&program).source_text; println!("Transformed:\n"); println!("{printed}"); } diff --git a/crates/oxc_wasm/src/lib.rs b/crates/oxc_wasm/src/lib.rs index 7ecae5be5bf0..b9ee8b1afd0a 100644 --- a/crates/oxc_wasm/src/lib.rs +++ b/crates/oxc_wasm/src/lib.rs @@ -8,7 +8,7 @@ use std::{cell::RefCell, path::PathBuf, rc::Rc}; use oxc::{ allocator::Allocator, ast::{CommentKind, Trivias}, - codegen::{Codegen, CodegenOptions}, + codegen::{CodeGenerator, WhitespaceRemover}, diagnostics::Error, minifier::{CompressOptions, Minifier, MinifierOptions}, parser::Parser, @@ -283,15 +283,10 @@ impl Oxc { Minifier::new(options).build(&allocator, program); } - let codegen_options = CodegenOptions::default(); self.codegen_text = if minifier_options.whitespace() { - Codegen::::new("", source_text, ret.trivias, codegen_options) - .build(program) - .source_text + WhitespaceRemover::new().build(program).source_text } else { - Codegen::::new("", source_text, ret.trivias, codegen_options) - .build(program) - .source_text + CodeGenerator::new().build(program).source_text }; Ok(()) diff --git a/napi/transform/Cargo.toml b/napi/transform/Cargo.toml index b91f12e73ae4..a2b20d5f2751 100644 --- a/napi/transform/Cargo.toml +++ b/napi/transform/Cargo.toml @@ -23,7 +23,6 @@ doctest = false [dependencies] oxc_allocator = { workspace = true } oxc_parser = { workspace = true } -oxc_ast = { workspace = true } oxc_span = { workspace = true } oxc_diagnostics = { workspace = true } oxc_codegen = { workspace = true } diff --git a/napi/transform/src/lib.rs b/napi/transform/src/lib.rs index 7bcbcad33e81..543d91160942 100644 --- a/napi/transform/src/lib.rs +++ b/napi/transform/src/lib.rs @@ -1,8 +1,7 @@ use napi_derive::napi; use oxc_allocator::Allocator; -use oxc_ast::Trivias; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_diagnostics::{Error, NamedSource}; use oxc_isolated_declarations::IsolatedDeclarations; use oxc_parser::Parser; @@ -23,14 +22,7 @@ pub fn isolated_declaration(filename: String, source_text: String) -> IsolatedDe let allocator = Allocator::default(); let parser_ret = Parser::new(&allocator, &source_text, source_type).parse(); let transformed_ret = IsolatedDeclarations::new(&allocator).build(&parser_ret.program); - let printed = Codegen::::new( - &filename, - &source_text, - Trivias::default(), - CodegenOptions::default(), - ) - .build(&transformed_ret.program) - .source_text; + let printed = CodeGenerator::new().build(&transformed_ret.program).source_text; let mut errors = vec![]; if !parser_ret.errors.is_empty() || !transformed_ret.errors.is_empty() { diff --git a/tasks/benchmark/benches/codegen_sourcemap.rs b/tasks/benchmark/benches/codegen_sourcemap.rs index f7f5c7bf6836..8d13cf13fa55 100644 --- a/tasks/benchmark/benches/codegen_sourcemap.rs +++ b/tasks/benchmark/benches/codegen_sourcemap.rs @@ -1,6 +1,6 @@ use oxc_allocator::Allocator; use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion}; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_parser::Parser; use oxc_span::SourceType; use oxc_tasks_common::TestFiles; @@ -14,17 +14,11 @@ fn bench_codegen_sourcemap(criterion: &mut Criterion) { group.bench_with_input(id, &file.source_text, |b, source_text| { let allocator = Allocator::default(); let ret = Parser::new(&allocator, source_text, source_type).parse(); - let codegen_options = - CodegenOptions { enable_source_map: true, ..CodegenOptions::default() }; b.iter_with_large_drop(|| { - Codegen::::new( - file.file_name.as_str(), - source_text, - ret.trivias.clone(), - codegen_options, - ) - .build(&ret.program) - .source_map + CodeGenerator::new() + .enable_source_map(file.file_name.as_str(), source_text) + .build(&ret.program) + .source_map }); }); } diff --git a/tasks/benchmark/benches/sourcemap.rs b/tasks/benchmark/benches/sourcemap.rs index 810023a6ad56..25c609e991b9 100644 --- a/tasks/benchmark/benches/sourcemap.rs +++ b/tasks/benchmark/benches/sourcemap.rs @@ -1,6 +1,6 @@ use oxc_allocator::Allocator; use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion}; -use oxc_codegen::{Codegen, CodegenOptions, CodegenReturn}; +use oxc_codegen::{CodeGenerator, CodegenReturn}; use oxc_parser::Parser; use oxc_sourcemap::ConcatSourceMapBuilder; use oxc_span::SourceType; @@ -16,16 +16,10 @@ fn bench_sourcemap(criterion: &mut Criterion) { group.bench_with_input(id, &file.source_text, |b, source_text| { let allocator = Allocator::default(); let ret = Parser::new(&allocator, source_text, source_type).parse(); - let codegen_options = - CodegenOptions { enable_source_map: true, ..CodegenOptions::default() }; b.iter(|| { - let CodegenReturn { source_map, source_text } = Codegen::::new( - file.file_name.as_str(), - source_text, - ret.trivias.clone(), - codegen_options, - ) - .build(&ret.program); + let CodegenReturn { source_map, source_text } = CodeGenerator::new() + .enable_source_map(file.file_name.as_str(), source_text) + .build(&ret.program); let line = source_text.matches('\n').count() as u32; if let Some(sourcemap) = source_map { let mut concat_sourcemap_builder = ConcatSourceMapBuilder::default(); diff --git a/tasks/coverage/src/codegen.rs b/tasks/coverage/src/codegen.rs index 128cb324b6cf..5a6ea7bb22c0 100644 --- a/tasks/coverage/src/codegen.rs +++ b/tasks/coverage/src/codegen.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::{CodeGenerator, WhitespaceRemover}; use oxc_parser::Parser; use oxc_span::SourceType; @@ -29,36 +29,25 @@ fn get_result(source_text: &str, source_type: SourceType) -> TestResult { /// Idempotency test fn get_normal_result(source_text: &str, source_type: SourceType) -> bool { - let options = CodegenOptions::default(); let allocator = Allocator::default(); let source_text1 = { let ret = Parser::new(&allocator, source_text, source_type).parse(); - Codegen::::new("", source_text, ret.trivias, options).build(&ret.program).source_text + CodeGenerator::new().build(&ret.program).source_text }; - let source_text2 = { let ret = Parser::new(&allocator, &source_text1, source_type).parse(); - Codegen::::new("", &source_text1, ret.trivias, options) - .build(&ret.program) - .source_text + CodeGenerator::new().build(&ret.program).source_text }; - source_text1 == source_text2 } /// Minify idempotency test fn get_minify_result(source_text: &str, source_type: SourceType) -> bool { - let options = CodegenOptions::default(); let allocator = Allocator::default(); let parse_result1 = Parser::new(&allocator, source_text, source_type).parse(); - let source_text1 = - Codegen::::new("", source_text, parse_result1.trivias.clone(), options) - .build(&parse_result1.program) - .source_text; + let source_text1 = WhitespaceRemover::new().build(&parse_result1.program).source_text; let parse_result2 = Parser::new(&allocator, source_text1.as_str(), source_type).parse(); - let source_text2 = Codegen::::new("", &source_text1, parse_result2.trivias, options) - .build(&parse_result2.program) - .source_text; + let source_text2 = WhitespaceRemover::new().build(&parse_result2.program).source_text; source_text1 == source_text2 } diff --git a/tasks/coverage/src/minifier.rs b/tasks/coverage/src/minifier.rs index b968922d95b0..b343cf91cf08 100644 --- a/tasks/coverage/src/minifier.rs +++ b/tasks/coverage/src/minifier.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::WhitespaceRemover; use oxc_minifier::{CompressOptions, Minifier, MinifierOptions}; use oxc_parser::Parser; use oxc_span::SourceType; @@ -100,7 +100,5 @@ fn minify(source_text: &str, source_type: SourceType, options: MinifierOptions) let ret = Parser::new(&allocator, source_text, source_type).parse(); let program = allocator.alloc(ret.program); Minifier::new(options).build(&allocator, program); - Codegen::::new("", source_text, ret.trivias, CodegenOptions::default()) - .build(program) - .source_text + WhitespaceRemover::new().build(program).source_text } diff --git a/tasks/coverage/src/runtime/mod.rs b/tasks/coverage/src/runtime/mod.rs index bbd9880ff3cd..cfa28da695c4 100644 --- a/tasks/coverage/src/runtime/mod.rs +++ b/tasks/coverage/src/runtime/mod.rs @@ -9,7 +9,7 @@ use oxc_tasks_common::{agent, project_root}; use phf::{phf_set, Set}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_parser::Parser; use oxc_span::SourceType; use serde_json::json; @@ -141,10 +141,7 @@ impl Case for CodegenRuntimeTest262Case { let source_type = SourceType::default().with_module(is_module); let allocator = Allocator::default(); let ret = Parser::new(&allocator, source_text, source_type).parse(); - let mut text = - Codegen::::new("", source_text, ret.trivias, CodegenOptions::default()) - .build(&ret.program) - .source_text; + let mut text = CodeGenerator::new().build(&ret.program).source_text; if is_only_strict { text = format!("\"use strict\";\n{text}"); } diff --git a/tasks/coverage/src/sourcemap.rs b/tasks/coverage/src/sourcemap.rs index d3348d869eaf..458bb052183d 100644 --- a/tasks/coverage/src/sourcemap.rs +++ b/tasks/coverage/src/sourcemap.rs @@ -5,7 +5,7 @@ use std::{ }; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_parser::Parser; use oxc_sourcemap::SourcemapVisualizer; use oxc_span::SourceType; @@ -127,15 +127,9 @@ impl Case for SourcemapCase { } } - let codegen_options = - CodegenOptions { enable_source_map: true, ..CodegenOptions::default() }; - let codegen_ret = Codegen::::new( - self.path.to_string_lossy().as_ref(), - source_text, - ret.trivias, - codegen_options, - ) - .build(&ret.program); + let codegen_ret = CodeGenerator::new() + .enable_source_map(self.path.to_string_lossy().as_ref(), source_text) + .build(&ret.program); TestResult::Snapshot( SourcemapVisualizer::new(&codegen_ret.source_text, &codegen_ret.source_map.unwrap()) diff --git a/tasks/coverage/src/transformer.rs b/tasks/coverage/src/transformer.rs index b5c97d58583b..33cb038f05ab 100644 --- a/tasks/coverage/src/transformer.rs +++ b/tasks/coverage/src/transformer.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_parser::Parser; use oxc_span::SourceType; use oxc_transformer::{ @@ -25,7 +25,6 @@ fn get_result( options: Option, ) -> TestResult { let allocator = Allocator::default(); - let filename = source_path.file_name().unwrap().to_string_lossy(); let options = options.unwrap_or_else(get_default_transformer_options); // First pass @@ -40,14 +39,7 @@ fn get_result( options.clone(), ) .build(&mut ret1.program); - Codegen::::new( - &filename, - source_text, - ret1.trivias.clone(), - CodegenOptions::default(), - ) - .build(&ret1.program) - .source_text + CodeGenerator::new().build(&ret1.program).source_text }; // Second pass with only JavaScript parsing @@ -63,9 +55,7 @@ fn get_result( options, ) .build(&mut ret2.program); - Codegen::::new(&filename, source_text, ret2.trivias, CodegenOptions::default()) - .build(&ret2.program) - .source_text + CodeGenerator::new().build(&ret2.program).source_text }; if transformed1 == transformed2 { diff --git a/tasks/coverage/src/typescript/meta.rs b/tasks/coverage/src/typescript/meta.rs index 775e13cecee2..96c965b3c230 100644 --- a/tasks/coverage/src/typescript/meta.rs +++ b/tasks/coverage/src/typescript/meta.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, fs, path::Path, sync::Arc}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_diagnostics::{NamedSource, OxcDiagnostic}; use oxc_parser::Parser; use oxc_span::SourceType; @@ -177,10 +177,7 @@ impl Baseline { let allocator = Allocator::default(); let source_type = SourceType::from_path(Path::new(&self.name)).unwrap(); let ret = Parser::new(&allocator, &self.original, source_type).parse(); - let printed = - Codegen::::new("", &self.original, ret.trivias, CodegenOptions::default()) - .build(&ret.program) - .source_text; + let printed = CodeGenerator::new().build(&ret.program).source_text; self.oxc_printed = printed; } diff --git a/tasks/coverage/src/typescript/transpile_runner.rs b/tasks/coverage/src/typescript/transpile_runner.rs index f3624b7fa255..d34d45873a34 100644 --- a/tasks/coverage/src/typescript/transpile_runner.rs +++ b/tasks/coverage/src/typescript/transpile_runner.rs @@ -3,8 +3,7 @@ use std::path::{Path, PathBuf}; use oxc_allocator::Allocator; -use oxc_ast::Trivias; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_diagnostics::OxcDiagnostic; use oxc_isolated_declarations::IsolatedDeclarations; use oxc_parser::Parser; @@ -166,8 +165,6 @@ fn transpile(path: &Path, source_text: &str) -> (String, Vec) { let source_type = SourceType::from_path(path).unwrap(); let ret = Parser::new(&allocator, source_text, source_type).parse(); let ret = IsolatedDeclarations::new(&allocator).build(&ret.program); - let printed = Codegen::::new("", "", Trivias::default(), CodegenOptions::default()) - .build(&ret.program) - .source_text; + let printed = CodeGenerator::new().build(&ret.program).source_text; (printed, ret.errors) } diff --git a/tasks/minsize/src/lib.rs b/tasks/minsize/src/lib.rs index 8de1682fc52c..af8c188712bd 100644 --- a/tasks/minsize/src/lib.rs +++ b/tasks/minsize/src/lib.rs @@ -8,7 +8,7 @@ use flate2::{write::GzEncoder, Compression}; use humansize::{format_size, DECIMAL}; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::WhitespaceRemover; use oxc_minifier::{CompressOptions, Minifier, MinifierOptions}; use oxc_parser::Parser; use oxc_span::SourceType; @@ -74,9 +74,7 @@ fn minify(source_text: &str, source_type: SourceType, options: MinifierOptions) let ret = Parser::new(&allocator, source_text, source_type).parse(); let program = allocator.alloc(ret.program); Minifier::new(options).build(&allocator, program); - Codegen::::new("", source_text, ret.trivias, CodegenOptions::default()) - .build(program) - .source_text + WhitespaceRemover::new().build(program).source_text } fn gzip_size(s: &str) -> usize { diff --git a/tasks/transform_conformance/src/test_case.rs b/tasks/transform_conformance/src/test_case.rs index b7268f0eca03..9430aa1ec053 100644 --- a/tasks/transform_conformance/src/test_case.rs +++ b/tasks/transform_conformance/src/test_case.rs @@ -4,7 +4,7 @@ use std::{ }; use oxc_allocator::Allocator; -use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_codegen::CodeGenerator; use oxc_diagnostics::{Error, OxcDiagnostic}; use oxc_parser::Parser; use oxc_span::{SourceType, VALID_EXTENSIONS}; @@ -180,12 +180,7 @@ pub trait TestCase { transform_options.clone(), ) .build(&mut program); - - result.map(|()| { - Codegen::::new("", &source_text, ret.trivias, CodegenOptions::default()) - .build(&program) - .source_text - }) + result.map(|()| CodeGenerator::new().build(&program).source_text) } } @@ -251,7 +246,6 @@ impl TestCase for ConformanceTestCase { println!("output_path: {output_path:?}"); } - let codegen_options = CodegenOptions::default(); let mut transformed_code = String::new(); let mut actual_errors = String::new(); @@ -270,10 +264,7 @@ impl TestCase for ConformanceTestCase { ); let result = transformer.build(&mut program); if result.is_ok() { - transformed_code = - Codegen::::new("", &input, ret.trivias, codegen_options) - .build(&program) - .source_text; + transformed_code = CodeGenerator::new().build(&program).source_text; } else { let error = result .err() @@ -315,9 +306,7 @@ impl TestCase for ConformanceTestCase { |output| { // Get expected code by parsing the source text, so we can get the same code generated result. let ret = Parser::new(&allocator, &output, source_type).parse(); - Codegen::::new("", &output, ret.trivias, codegen_options) - .build(&ret.program) - .source_text + CodeGenerator::new().build(&ret.program).source_text }, ); @@ -382,17 +371,8 @@ impl ExecTestCase { let source_text = fs::read_to_string(&target_path).unwrap(); let source_type = SourceType::from_path(&target_path).unwrap(); let transformed_ret = Parser::new(&allocator, &source_text, source_type).parse(); - let result = Codegen::::new( - "", - &source_text, - transformed_ret.trivias, - CodegenOptions::default(), - ) - .build(&transformed_ret.program) - .source_text; - + let result = CodeGenerator::new().build(&transformed_ret.program).source_text; fs::write(&target_path, result).unwrap(); - target_path } }