From 534242a7295c8bb5bf54a8daeddf5a25bf8c458d Mon Sep 17 00:00:00 2001 From: Boshen Date: Fri, 14 Jun 2024 21:56:00 +0800 Subject: [PATCH] feat(codegen)!: remove `CodegenOptions::enable_typescript` (#3674) The typescript transform pass is now required to strip typescript syntax for codegen to print things properly. Codegen will now print whatever is in the AST. --- crates/oxc_codegen/examples/codegen.rs | 3 +- crates/oxc_codegen/examples/sourcemap.rs | 3 +- crates/oxc_codegen/src/gen.rs | 264 ++++++------------ crates/oxc_codegen/src/gen_ts.rs | 27 +- crates/oxc_codegen/src/lib.rs | 18 +- crates/oxc_codegen/tests/mod.rs | 29 +- crates/oxc_minifier/tests/esbuild/mod.rs | 8 +- crates/oxc_minifier/tests/oxc/precedence.rs | 22 +- .../{transformer.rs => transformer_dts.rs} | 0 crates/oxc_transformer_dts/src/lib.rs | 2 +- crates/oxc_wasm/src/lib.rs | 7 +- tasks/coverage/codegen_sourcemap.snap | 11 +- tasks/coverage/src/codegen.rs | 4 +- tasks/coverage/src/transformer.rs | 2 +- tasks/transform_conformance/src/test_case.rs | 15 +- 15 files changed, 144 insertions(+), 271 deletions(-) rename crates/oxc_transformer_dts/examples/{transformer.rs => transformer_dts.rs} (100%) diff --git a/crates/oxc_codegen/examples/codegen.rs b/crates/oxc_codegen/examples/codegen.rs index 806c9a698..21e54474e 100644 --- a/crates/oxc_codegen/examples/codegen.rs +++ b/crates/oxc_codegen/examples/codegen.rs @@ -28,8 +28,7 @@ fn main() -> std::io::Result<()> { println!("Original:"); println!("{source_text}"); - let options = - CodegenOptions { enable_source_map: false, enable_typescript: true, ..Default::default() }; + let options = CodegenOptions { enable_source_map: false, ..Default::default() }; let printed = Codegen::::new("", &source_text, ret.trivias, options) .build(&ret.program) .source_text; diff --git a/crates/oxc_codegen/examples/sourcemap.rs b/crates/oxc_codegen/examples/sourcemap.rs index 40c559b17..3803d66c1 100644 --- a/crates/oxc_codegen/examples/sourcemap.rs +++ b/crates/oxc_codegen/examples/sourcemap.rs @@ -26,8 +26,7 @@ fn main() -> std::io::Result<()> { return Ok(()); } - let codegen_options = - CodegenOptions { enable_source_map: true, enable_typescript: true, ..Default::default() }; + let codegen_options = CodegenOptions { enable_source_map: true, ..Default::default() }; let CodegenReturn { source_text, source_map } = Codegen::::new( path.to_string_lossy().as_ref(), diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 46943e79f..8f1b760ce 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -511,18 +511,14 @@ impl<'a, const MINIFY: bool> Gen for ModuleDeclaration<'a> { Self::ExportDefaultDeclaration(decl) => decl.gen(p, ctx), Self::ExportNamedDeclaration(decl) => decl.gen(p, ctx), Self::TSExportAssignment(decl) => { - if p.options.enable_typescript { - p.print_str(b"export = "); - decl.expression.gen_expr(p, Precedence::lowest(), ctx); - p.print_semicolon_after_statement(); - } + p.print_str(b"export = "); + decl.expression.gen_expr(p, Precedence::lowest(), ctx); + p.print_semicolon_after_statement(); } Self::TSNamespaceExportDeclaration(decl) => { - if p.options.enable_typescript { - p.print_str(b"export as namespace "); - decl.id.gen(p, ctx); - p.print_semicolon_after_statement(); - } + p.print_str(b"export as namespace "); + decl.id.gen(p, ctx); + p.print_semicolon_after_statement(); } } } @@ -532,28 +528,21 @@ impl<'a, const MINIFY: bool> Gen for Declaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { match self { Self::VariableDeclaration(decl) => { - // Codegen is not intended to be used as a code formatting tool, so we need filter out the TypeScript syntax here. - if p.options.enable_typescript || !decl.is_typescript_syntax() { - p.print_indent(); - decl.gen(p, ctx); - p.print_semicolon_after_statement(); - } + p.print_indent(); + decl.gen(p, ctx); + p.print_semicolon_after_statement(); } Self::FunctionDeclaration(decl) => { - if p.options.enable_typescript || !decl.is_typescript_syntax() { - p.print_indent(); - p.print_space_before_identifier(); - decl.gen(p, ctx); - p.print_soft_newline(); - } + p.print_indent(); + p.print_space_before_identifier(); + decl.gen(p, ctx); + p.print_soft_newline(); } Self::ClassDeclaration(decl) => { - if p.options.enable_typescript || !decl.is_typescript_syntax() { - p.print_indent(); - p.print_space_before_identifier(); - decl.gen(p, ctx); - p.print_soft_newline(); - } + p.print_indent(); + p.print_space_before_identifier(); + decl.gen(p, ctx); + p.print_soft_newline(); } Self::UsingDeclaration(declaration) => { p.print_space_before_identifier(); @@ -561,14 +550,9 @@ impl<'a, const MINIFY: bool> Gen for Declaration<'a> { p.print_soft_newline(); } Self::TSModuleDeclaration(decl) => { - if p.options.enable_typescript { - decl.gen(p, ctx); - } + decl.gen(p, ctx); } Self::TSTypeAliasDeclaration(decl) => { - if !p.options.enable_typescript { - return; - } if decl.modifiers.contains(ModifierKind::Export) { p.print_str(b"export "); } @@ -590,9 +574,7 @@ impl<'a, const MINIFY: bool> Gen for Declaration<'a> { Declaration::TSInterfaceDeclaration(decl) => decl.gen(p, ctx), Declaration::TSEnumDeclaration(decl) => decl.gen(p, ctx), Declaration::TSImportEqualsDeclaration(decl) => { - if p.options.enable_typescript { - decl.gen(p, ctx); - } + decl.gen(p, ctx); } } } @@ -614,7 +596,7 @@ impl<'a, const MINIFY: bool> Gen for UsingDeclaration<'a> { impl<'a, const MINIFY: bool> Gen for VariableDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); - if p.options.enable_typescript && self.modifiers.contains(ModifierKind::Declare) { + if self.modifiers.contains(ModifierKind::Declare) { p.print_str(b"declare "); } @@ -658,13 +640,10 @@ impl<'a, const MINIFY: bool> Gen for Function<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); self.gen_comment(p, ctx); - if !p.options.enable_typescript && self.is_typescript_syntax() { - return; - } let n = p.code_len(); let wrap = self.is_expression() && (p.start_of_stmt == n || p.start_of_default_export == n); p.wrap(wrap, |p| { - if p.options.enable_typescript && self.modifiers.contains(ModifierKind::Declare) { + if self.modifiers.contains(ModifierKind::Declare) { p.print_str(b"declare "); } if self.r#async { @@ -679,24 +658,20 @@ impl<'a, const MINIFY: bool> Gen for Function<'a> { p.print_space_before_identifier(); id.gen(p, ctx); } - if p.options.enable_typescript { - if let Some(type_parameters) = &self.type_parameters { - type_parameters.gen(p, ctx); - } + if let Some(type_parameters) = &self.type_parameters { + type_parameters.gen(p, ctx); } p.print(b'('); self.params.gen(p, ctx); p.print(b')'); - if p.options.enable_typescript { - if let Some(return_type) = &self.return_type { - p.print_str(b": "); - return_type.gen(p, ctx); - } + if let Some(return_type) = &self.return_type { + p.print_str(b": "); + return_type.gen(p, ctx); } p.print_soft_space(); if let Some(body) = &self.body { body.gen(p, ctx); - } else if p.options.enable_typescript { + } else { p.print_semicolon_after_statement(); } }); @@ -720,13 +695,11 @@ impl<'a, const MINIFY: bool> Gen for FunctionBody<'a> { impl<'a, const MINIFY: bool> Gen for FormalParameter<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { self.decorators.gen(p, ctx); - if p.options.enable_typescript { - if self.readonly { - p.print_str(b"readonly "); - } - if let Some(accessibility) = self.accessibility { - accessibility.gen(p, ctx); - } + if self.readonly { + p.print_str(b"readonly "); + } + if let Some(accessibility) = self.accessibility { + accessibility.gen(p, ctx); } self.pattern.gen(p, ctx); } @@ -749,7 +722,7 @@ impl<'a, const MINIFY: bool> Gen for ImportDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); p.print_str(b"import "); - if p.options.enable_typescript && self.import_kind.is_type() { + if self.import_kind.is_type() { p.print_str(b"type "); } if let Some(specifiers) = &self.specifiers { @@ -798,7 +771,7 @@ impl<'a, const MINIFY: bool> Gen for ImportDeclaration<'a> { p.print(b'{'); } - if p.options.enable_typescript && spec.import_kind.is_type() { + if spec.import_kind.is_type() { p.print_str(b"type "); } @@ -870,9 +843,6 @@ impl<'a, const MINIFY: bool> Gen for ImportAttribute<'a> { 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); - if !p.options.enable_typescript && self.is_typescript_syntax() { - return; - } if p.options.preserve_annotate_comments { match &self.declaration { Some(Declaration::FunctionDeclaration(_)) => { @@ -895,7 +865,7 @@ impl<'a, const MINIFY: bool> Gen for ExportNamedDeclaration<'a> { }; } p.print_str(b"export "); - if p.options.enable_typescript && self.export_kind.is_type() { + if self.export_kind.is_type() { p.print_str(b"type "); } match &self.declaration { @@ -922,7 +892,7 @@ impl<'a, const MINIFY: bool> Gen for ExportNamedDeclaration<'a> { impl<'a, const MINIFY: bool> Gen for ExportSpecifier<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if p.options.enable_typescript && self.export_kind.is_type() { + if self.export_kind.is_type() { p.print_str(b"type "); } self.local.gen(p, ctx); @@ -947,11 +917,8 @@ impl<'a, const MINIFY: bool> Gen for ModuleExportName<'a> { impl<'a, const MINIFY: bool> Gen for ExportAllDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); - if !p.options.enable_typescript && self.is_typescript_syntax() { - return; - } p.print_str(b"export "); - if p.options.enable_typescript && self.export_kind.is_type() { + if self.export_kind.is_type() { p.print_str(b"type "); } p.print(b'*'); @@ -975,9 +942,6 @@ impl<'a, const MINIFY: bool> Gen for ExportAllDeclaration<'a> { impl<'a, const MINIFY: bool> Gen for ExportDefaultDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); - if !p.options.enable_typescript && self.is_typescript_syntax() { - return; - } p.print_str(b"export default "); self.declaration.gen(p, ctx); } @@ -1043,10 +1007,8 @@ impl<'a, const MINIFY: bool> GenExpr for Expression<'a> { Self::TSAsExpression(e) => e.gen_expr(p, precedence, ctx), Self::TSSatisfiesExpression(e) => { e.expression.gen_expr(p, precedence, ctx); - if p.options.enable_typescript { - p.print_str(b" satisfies "); - e.type_annotation.gen(p, ctx); - } + p.print_str(b" satisfies "); + e.type_annotation.gen(p, ctx); } Self::TSTypeAssertion(e) => e.gen_expr(p, precedence, ctx), Self::TSNonNullExpression(e) => e.expression.gen_expr(p, precedence, ctx), @@ -1069,15 +1031,11 @@ impl GenComment for Function<'_> { impl<'a, const MINIFY: bool> GenExpr for TSAsExpression<'a> { fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) { - if p.options.enable_typescript { - p.print_str(b"("); - } + p.print_str(b"("); self.expression.gen_expr(p, precedence, ctx); - if p.options.enable_typescript { - p.print_str(b" as "); - self.type_annotation.gen(p, ctx); - p.print_str(b")"); - } + p.print_str(b" as "); + self.type_annotation.gen(p, ctx); + p.print_str(b")"); } } impl<'a, const MINIFY: bool> Gen for IdentifierReference<'a> { @@ -1427,10 +1385,8 @@ impl<'a, const MINIFY: bool> GenExpr for CallExpression<'a> { if self.optional { p.print_str(b"?."); } - if p.options.enable_typescript { - if let Some(type_parameters) = &self.type_parameters { - type_parameters.gen(p, ctx); - } + if let Some(type_parameters) = &self.type_parameters { + type_parameters.gen(p, ctx); } p.print(b'('); p.print_list(&self.arguments, ctx); @@ -1553,10 +1509,8 @@ impl<'a, const MINIFY: bool> Gen for ObjectProperty<'a> { if self.computed { p.print(b']'); } - if p.options.enable_typescript { - if let Some(type_parameters) = &func.type_parameters { - type_parameters.gen(p, ctx); - } + if let Some(type_parameters) = &func.type_parameters { + type_parameters.gen(p, ctx); } p.print(b'('); func.params.gen(p, ctx); @@ -1604,32 +1558,21 @@ impl<'a, const MINIFY: bool> GenExpr for ArrowFunctionExpression<'a> { p.print_str(b"async"); } - // No wrap for `a => {}` - let nowrap = self.params.rest.is_none() - && self.params.items.len() == 1 - && self.params.items[0].pattern.kind.is_binding_identifier() - && !p.options.enable_typescript; - if nowrap && self.r#async { + if self.r#async { p.print_hard_space(); } - if p.options.enable_typescript { - if let Some(type_parameters) = &self.type_parameters { - type_parameters.gen(p, ctx); - } + if let Some(type_parameters) = &self.type_parameters { + type_parameters.gen(p, ctx); } - if !nowrap { - p.add_source_mapping(self.span.start); - } - p.wrap(!nowrap, |p| { - self.params.gen(p, ctx); - }); - if p.options.enable_typescript { - if let Some(return_type) = &self.return_type { - p.print_str(b":"); - p.print_soft_space(); - return_type.gen(p, ctx); - } + p.add_source_mapping(self.span.start); + p.print(b'('); + self.params.gen(p, ctx); + p.print(b')'); + if let Some(return_type) = &self.return_type { + p.print_str(b":"); + p.print_soft_space(); + return_type.gen(p, ctx); } p.print_soft_space(); p.print_str(b"=>"); @@ -2082,16 +2025,11 @@ impl<'a, const MINIFY: bool> Gen for MetaProperty<'a> { impl<'a, const MINIFY: bool> Gen for Class<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); - if !p.options.enable_typescript && self.is_declare() { - return; + if self.modifiers.is_contains_declare() { + p.print_str(b"declare "); } - if p.options.enable_typescript { - if self.modifiers.is_contains_declare() { - p.print_str(b"declare "); - } - if self.modifiers.is_contains_abstract() { - p.print_str(b"abstract "); - } + if self.modifiers.is_contains_abstract() { + p.print_str(b"abstract "); } let n = p.code_len(); let wrap = self.is_expression() && (p.start_of_stmt == n || p.start_of_default_export == n); @@ -2109,9 +2047,6 @@ impl<'a, const MINIFY: bool> Gen for Class<'a> { p.print_soft_space(); p.print_block_start(self.body.span.start); for item in &self.body.body { - if !p.options.enable_typescript && item.is_typescript_syntax() { - continue; - } p.print_indent(); p.print_semicolon_if_needed(); item.gen(p, ctx); @@ -2361,15 +2296,10 @@ impl<'a, const MINIFY: bool> Gen for StaticBlock<'a> { impl<'a, const MINIFY: bool> Gen for MethodDefinition<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if !p.options.enable_typescript && self.value.is_typescript_syntax() { - return; - } p.add_source_mapping(self.span.start); self.decorators.gen(p, ctx); - if p.options.enable_typescript - && self.r#type == MethodDefinitionType::TSAbstractMethodDefinition - { + if self.r#type == MethodDefinitionType::TSAbstractMethodDefinition { p.print_str(b"abstract "); } @@ -2405,16 +2335,14 @@ impl<'a, const MINIFY: bool> Gen for MethodDefinition<'a> { p.print(b'('); self.value.params.gen(p, ctx); p.print(b')'); - if p.options.enable_typescript { - if let Some(return_type) = &self.value.return_type { - p.print_colon(); - p.print_soft_space(); - return_type.gen(p, ctx); - } + if let Some(return_type) = &self.value.return_type { + p.print_colon(); + p.print_soft_space(); + return_type.gen(p, ctx); } if let Some(body) = &self.value.body { body.gen(p, ctx); - } else if p.options.enable_typescript { + } else { p.print_semicolon_after_statement(); } } @@ -2424,21 +2352,19 @@ impl<'a, const MINIFY: bool> Gen for PropertyDefinition<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); self.decorators.gen(p, ctx); - if p.options.enable_typescript { - if self.r#type == PropertyDefinitionType::TSAbstractPropertyDefinition { - p.print_str(b"abstract "); - } - if let Some(accessibility) = &self.accessibility { - match accessibility { - TSAccessibility::Private => { - p.print_str(b"private "); - } - TSAccessibility::Protected => { - p.print_str(b"protected "); - } - TSAccessibility::Public => { - p.print_str(b"public "); - } + if self.r#type == PropertyDefinitionType::TSAbstractPropertyDefinition { + p.print_str(b"abstract "); + } + if let Some(accessibility) = &self.accessibility { + match accessibility { + TSAccessibility::Private => { + p.print_str(b"private "); + } + TSAccessibility::Protected => { + p.print_str(b"protected "); + } + TSAccessibility::Public => { + p.print_str(b"public "); } } } @@ -2455,12 +2381,10 @@ impl<'a, const MINIFY: bool> Gen for PropertyDefinition<'a> { if self.optional { p.print_str(b"?"); } - if p.options.enable_typescript { - if let Some(type_annotation) = &self.type_annotation { - p.print_colon(); - p.print_soft_space(); - type_annotation.gen(p, ctx); - } + if let Some(type_annotation) = &self.type_annotation { + p.print_colon(); + p.print_soft_space(); + type_annotation.gen(p, ctx); } if let Some(value) = &self.value { p.print_equal(); @@ -2472,7 +2396,7 @@ impl<'a, const MINIFY: bool> Gen for PropertyDefinition<'a> { impl<'a, const MINIFY: bool> Gen for AccessorProperty<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); - if p.options.enable_typescript && self.r#type.is_abstract() { + if self.r#type.is_abstract() { p.print_str(b"abstract "); } if self.r#static { @@ -2509,15 +2433,13 @@ impl<'a, const MINIFY: bool> Gen for BindingPattern<'a> { BindingPatternKind::ArrayPattern(pattern) => pattern.gen(p, ctx), BindingPatternKind::AssignmentPattern(pattern) => pattern.gen(p, ctx), } - if p.options.enable_typescript { - if self.optional { - p.print_str(b"?"); - } - if let Some(type_annotation) = &self.type_annotation { - p.print_colon(); - p.print_soft_space(); - type_annotation.gen(p, ctx); - } + if self.optional { + p.print_str(b"?"); + } + if let Some(type_annotation) = &self.type_annotation { + p.print_colon(); + p.print_soft_space(); + type_annotation.gen(p, ctx); } } } diff --git a/crates/oxc_codegen/src/gen_ts.rs b/crates/oxc_codegen/src/gen_ts.rs index ec8365307..5818d1e5d 100644 --- a/crates/oxc_codegen/src/gen_ts.rs +++ b/crates/oxc_codegen/src/gen_ts.rs @@ -478,9 +478,6 @@ impl<'a, const MINIFY: bool> Gen for TSTypeParameterInstantiation<'a> { impl<'a, const MINIFY: bool> Gen for TSIndexSignature<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if !p.options.enable_typescript { - return; - } p.print_str(b"["); for (index, parameter) in self.parameters.iter().enumerate() { if index != 0 { @@ -563,9 +560,6 @@ impl<'a, const MINIFY: bool> Gen for TSModuleDeclaration<'a> { impl<'a, const MINIFY: bool> Gen for TSTypeAliasDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if !p.options.enable_typescript { - return; - } p.print_str(b"type "); self.id.gen(p, ctx); if let Some(type_parameters) = &self.type_parameters { @@ -579,10 +573,6 @@ impl<'a, const MINIFY: bool> Gen for TSTypeAliasDeclaration<'a> { impl<'a, const MINIFY: bool> Gen for TSInterfaceDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if !p.options.enable_typescript { - return; - } - p.print_str(b"interface"); p.print_hard_space(); self.id.gen(p, ctx); @@ -623,15 +613,11 @@ impl<'a, const MINIFY: bool> Gen for TSInterfaceHeritage<'a> { impl<'a, const MINIFY: bool> Gen for TSEnumDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if !p.options.enable_typescript { - return; - } - p.print_indent(); if self.modifiers.contains(ModifierKind::Export) { p.print_str(b"export "); } - if p.options.enable_typescript && self.modifiers.contains(ModifierKind::Declare) { + if self.modifiers.contains(ModifierKind::Declare) { p.print_str(b"declare "); } if self.modifiers.contains(ModifierKind::Const) { @@ -684,9 +670,6 @@ impl<'a, const MINIFY: bool> Gen for TSConstructorType<'a> { impl<'a, const MINIFY: bool> Gen for TSImportEqualsDeclaration<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if !p.options.enable_typescript { - return; - } p.print_str(b"import "); self.id.gen(p, ctx); p.print_str(b" = "); @@ -709,11 +692,9 @@ impl<'a, const MINIFY: bool> Gen for TSModuleReference<'a> { impl<'a, const MINIFY: bool> GenExpr for TSTypeAssertion<'a> { fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) { - if p.options.enable_typescript { - p.print_str(b"<"); - self.type_annotation.gen(p, ctx); - p.print_str(b">"); - } + p.print_str(b"<"); + self.type_annotation.gen(p, ctx); + p.print_str(b">"); self.expression.gen_expr(p, precedence, ctx); } } diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index 687cd888e..a649922df 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -44,24 +44,10 @@ pub struct CodegenOptions { /// Pass in the filename to enable source map support. pub enable_source_map: bool, - /// Enable TypeScript code generation. - pub enable_typescript: bool, - /// Enable preserve annotate comments, like `/* #__PURE__ */` and `/* #__NO_SIDE_EFFECTS__ */`. pub preserve_annotate_comments: bool, } -impl CodegenOptions { - #[must_use] - pub fn with_typescript(mut self, yes: bool) -> Self { - if yes { - self.enable_typescript = true; - } - - self - } -} - pub struct CodegenReturn { pub source_text: String, pub source_map: Option, @@ -471,9 +457,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> { } for stmt in statements { if let Some(decl) = stmt.as_declaration() { - if decl.is_typescript_syntax() - && !self.options.enable_typescript - && !matches!(decl, Declaration::TSEnumDeclaration(_)) + if decl.is_typescript_syntax() && !matches!(decl, Declaration::TSEnumDeclaration(_)) { continue; } diff --git a/crates/oxc_codegen/tests/mod.rs b/crates/oxc_codegen/tests/mod.rs index 89e5bce2a..1f6d998dd 100644 --- a/crates/oxc_codegen/tests/mod.rs +++ b/crates/oxc_codegen/tests/mod.rs @@ -7,10 +7,10 @@ fn test(source_text: &str, expected: &str, options: Option) { let allocator = Allocator::default(); let source_type = SourceType::default().with_module(true); let ret = Parser::new(&allocator, source_text, source_type).parse(); - let program = allocator.alloc(ret.program); let options = options.unwrap_or_default(); - let result = - Codegen::::new("", source_text, ret.trivias, options).build(program).source_text; + let result = Codegen::::new("", source_text, ret.trivias, options) + .build(&ret.program) + .source_text; assert_eq!(expected, result, "for source {source_text}, expect {expected}, got {result}"); } @@ -21,10 +21,9 @@ 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 program = allocator.alloc(ret.program); - let codegen_options = CodegenOptions { enable_typescript: true, ..CodegenOptions::default() }; + let codegen_options = CodegenOptions::default(); let result = Codegen::::new("", source_text, ret.trivias, codegen_options) - .build(program) + .build(&ret.program) .source_text; assert_eq!(expected, result, "for source {source_text}, expect {expected}, got {result}"); } @@ -186,11 +185,7 @@ fn test_comment_helper(source_text: &str, expected: &str) { test( source_text, expected, - Some(CodegenOptions { - enable_source_map: true, - enable_typescript: false, - preserve_annotate_comments: true, - }), + Some(CodegenOptions { enable_source_map: true, preserve_annotate_comments: true }), ); } #[test] @@ -230,9 +225,9 @@ fn annotate_comment() { /* #__NO_SIDE_EFFECTS__ */ async () => {}, /* #__NO_SIDE_EFFECTS__ */ async (y) => (y), ])", - r"x([/* #__NO_SIDE_EFFECTS__ */ y => y, /* #__NO_SIDE_EFFECTS__ */ () => { -}, /* #__NO_SIDE_EFFECTS__ */ y => y, /* #__NO_SIDE_EFFECTS__ */ async y => y, /* #__NO_SIDE_EFFECTS__ */ async() => { -}, /* #__NO_SIDE_EFFECTS__ */ async y => y,]); + r"x([/* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ () => { +}, /* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ async (y) => y, /* #__NO_SIDE_EFFECTS__ */ async () => { +}, /* #__NO_SIDE_EFFECTS__ */ async (y) => y,]); ", ); test_comment_helper( @@ -245,9 +240,9 @@ fn annotate_comment() { /* #__NO_SIDE_EFFECTS__ */ async () => {}, /* #__NO_SIDE_EFFECTS__ */ async (y) => (y), ])", - r"x([/* #__NO_SIDE_EFFECTS__ */ y => y, /* #__NO_SIDE_EFFECTS__ */ () => { -}, /* #__NO_SIDE_EFFECTS__ */ y => y, /* #__NO_SIDE_EFFECTS__ */ async y => y, /* #__NO_SIDE_EFFECTS__ */ async() => { -}, /* #__NO_SIDE_EFFECTS__ */ async y => y,]); + r"x([/* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ () => { +}, /* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ async (y) => y, /* #__NO_SIDE_EFFECTS__ */ async () => { +}, /* #__NO_SIDE_EFFECTS__ */ async (y) => y,]); ", ); // diff --git a/crates/oxc_minifier/tests/esbuild/mod.rs b/crates/oxc_minifier/tests/esbuild/mod.rs index c4e254f14..f1e7aacb8 100644 --- a/crates/oxc_minifier/tests/esbuild/mod.rs +++ b/crates/oxc_minifier/tests/esbuild/mod.rs @@ -214,7 +214,7 @@ fn r#for() { test("for (x(a in b);;);", "for(x(a in b);;);"); test("for (x[a in b];;);", "for(x[a in b];;);"); test("for (x?.[a in b];;);", "for(x?.[a in b];;);"); - test("for ((x => a in b);;);", "for(x=>(a in b);;);"); + test("for ((x => a in b);;);", "for((x)=>(a in b);;);"); // Make sure for-of loops with commas are wrapped in parentheses test("for (let a in b, c);", "for(let a in b,c);"); @@ -303,8 +303,8 @@ fn generator() { #[test] fn arrow() { test("() => {}", "()=>{};"); - test("x => (x, 0)", "x=>(x,0);"); - test("x => {y}", "x=>{y};"); + test("x => (x, 0)", "(x)=>(x,0);"); + test("x => {y}", "(x)=>{y};"); test("(a = (b, c), ...d) => {}", "(a=(b,c),...d)=>{};"); test("({[1 + 2]: a = 3} = {[1 + 2]: 3}) => {}", "({[3]:a=3}={[3]:3})=>{};"); test( @@ -515,7 +515,7 @@ fn minify() { test("1.2", "1.2;"); test("() => {}", "()=>{};"); - test("(a) => {}", "a=>{};"); + test("(a) => {}", "(a)=>{};"); test("(...a) => {}", "(...a)=>{};"); test("(a = 0) => {}", "(a=0)=>{};"); test("(a, b) => {}", "(a,b)=>{};"); diff --git a/crates/oxc_minifier/tests/oxc/precedence.rs b/crates/oxc_minifier/tests/oxc/precedence.rs index 619eb32c4..0fecdead1 100644 --- a/crates/oxc_minifier/tests/oxc/precedence.rs +++ b/crates/oxc_minifier/tests/oxc/precedence.rs @@ -15,7 +15,7 @@ fn assignment() { test("({a,b} = (1, 2))", "({a,b}=(1,2));"); test("a *= yield b", "a*=yield b;"); test("a /= () => {}", "a/=()=>{};"); - test("a %= async () => {}", "a%=async()=>{};"); + test("a %= async () => {}", "a%=async ()=>{};"); test("a -= (1, 2)", "a-=(1,2);"); test("a >>= b >>= c", "a>>=b>>=c;"); } @@ -27,12 +27,12 @@ fn r#yield() { test("function *foo() { yield * a ? b : c }", "function*foo(){yield*a?b:c}"); test("function *foo() { yield * yield * a }", "function*foo(){yield*yield*a}"); test("function *foo() { yield * () => {} }", "function*foo(){yield*()=>{}}"); - test("function *foo() { yield * async () => {} }", "function*foo(){yield*async()=>{}}"); + test("function *foo() { yield * async () => {} }", "function*foo(){yield*async ()=>{}}"); test("function *foo() { yield a ? b : c }", "function*foo(){yield a?b:c}"); test("function *foo() { yield yield a }", "function*foo(){yield yield a}"); test("function *foo() { yield () => {} }", "function*foo(){yield ()=>{}}"); - test("function *foo() { yield async () => {} }", "function*foo(){yield async()=>{}}"); + test("function *foo() { yield async () => {} }", "function*foo(){yield async ()=>{}}"); test( "function *foo() { yield { a } = [ b ] = c ? b : d }", @@ -45,14 +45,14 @@ fn r#yield() { #[test] fn arrow() { - test("x => a, b", "x=>a,b;"); - test("x => (a, b)", "x=>(a,b);"); - test("x => (a => b)", "x=>a=>b;"); - test("x => y => a, b", "x=>y=>a,b;"); - test("x => y => (a = b)", "x=>y=>a=b;"); - test("x => y => z => a = b, c", "x=>y=>z=>a=b,c;"); - test("x => y => z => a = (b, c)", "x=>y=>z=>a=(b,c);"); - test("x => ({} + 0)", "x=>({})+0;"); + test("x => a, b", "(x)=>a,b;"); + test("x => (a, b)", "(x)=>(a,b);"); + test("x => (a => b)", "(x)=>(a)=>b;"); + test("x => y => a, b", "(x)=>(y)=>a,b;"); + test("x => y => (a = b)", "(x)=>(y)=>a=b;"); + test("x => y => z => a = b, c", "(x)=>(y)=>(z)=>a=b,c;"); + test("x => y => z => a = (b, c)", "(x)=>(y)=>(z)=>a=(b,c);"); + test("x => ({} + 0)", "(x)=>({})+0;"); } #[test] diff --git a/crates/oxc_transformer_dts/examples/transformer.rs b/crates/oxc_transformer_dts/examples/transformer_dts.rs similarity index 100% rename from crates/oxc_transformer_dts/examples/transformer.rs rename to crates/oxc_transformer_dts/examples/transformer_dts.rs diff --git a/crates/oxc_transformer_dts/src/lib.rs b/crates/oxc_transformer_dts/src/lib.rs index ff5a7bf3c..5e245f709 100644 --- a/crates/oxc_transformer_dts/src/lib.rs +++ b/crates/oxc_transformer_dts/src/lib.rs @@ -44,7 +44,7 @@ impl<'a> TransformerDts<'a> { &source_path.file_name().map(|n| n.to_string_lossy()).unwrap_or_default(), source_text, trivias, - CodegenOptions::default().with_typescript(true), + CodegenOptions::default(), ); let ctx = Rc::new(TransformDtsCtx::new(allocator)); diff --git a/crates/oxc_wasm/src/lib.rs b/crates/oxc_wasm/src/lib.rs index 245f1a65f..b7bd814b8 100644 --- a/crates/oxc_wasm/src/lib.rs +++ b/crates/oxc_wasm/src/lib.rs @@ -155,7 +155,7 @@ impl Oxc { run_options: &OxcRunOptions, parser_options: &OxcParserOptions, _linter_options: &OxcLinterOptions, - codegen_options: &OxcCodegenOptions, + _codegen_options: &OxcCodegenOptions, minifier_options: &OxcMinifierOptions, ) -> Result<(), serde_wasm_bindgen::Error> { self.diagnostics = RefCell::default(); @@ -274,10 +274,7 @@ impl Oxc { Minifier::new(options).build(&allocator, program); } - let codegen_options = CodegenOptions { - enable_typescript: codegen_options.enable_typescript, - ..CodegenOptions::default() - }; + let codegen_options = CodegenOptions::default(); self.codegen_text = if minifier_options.whitespace() { Codegen::::new("", source_text, ret.trivias, codegen_options) .build(program) diff --git a/tasks/coverage/codegen_sourcemap.snap b/tasks/coverage/codegen_sourcemap.snap index 8db3979de..e5c9844e4 100644 --- a/tasks/coverage/codegen_sourcemap.snap +++ b/tasks/coverage/codegen_sourcemap.snap @@ -374,13 +374,14 @@ Unexpected token (53:16-54:0) "};" --> (106:0-107:0) "\n};" (54:0-54:4) "\nvar" --> (107:0-107:4) "\nvar" (54:4-54:8) " z =" --> (107:4-107:8) " z =" -(54:8-54:13) " x =>" --> (107:8-107:13) " x =>" -(54:13-54:15) " {" --> (107:13-108:0) " {" +(54:8-54:13) " x =>" --> (107:8-107:15) " (x) =>" +(54:13-54:15) " {" --> (107:15-108:0) " {" (54:15-55:0) "};" --> (108:0-109:0) "\n};" (55:0-55:4) "\nvar" --> (109:0-109:4) "\nvar" -(55:4-55:9) " z = " --> (109:4-109:8) " z =" -(55:9-55:15) "(x) =>" --> (109:8-109:13) " x =>" -(55:15-55:17) " {" --> (109:13-110:0) " {" +(55:4-55:8) " z =" --> (109:4-109:8) " z =" +(55:8-55:9) " " --> (109:8-109:9) " " +(55:9-55:15) "(x) =>" --> (109:9-109:15) "(x) =>" +(55:15-55:17) " {" --> (109:15-110:0) " {" (55:17-56:0) "};" --> (110:0-111:0) "\n};" (56:0-56:4) "\nvar" --> (111:0-111:4) "\nvar" (56:4-56:8) " z =" --> (111:4-111:8) " z =" diff --git a/tasks/coverage/src/codegen.rs b/tasks/coverage/src/codegen.rs index 3421c24db..a990caa0c 100644 --- a/tasks/coverage/src/codegen.rs +++ b/tasks/coverage/src/codegen.rs @@ -65,7 +65,7 @@ fn get_normal_result( source_text: &str, source_type: SourceType, ) -> bool { - let options = CodegenOptions::default().with_typescript(source_type.is_typescript()); + 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, options) @@ -108,7 +108,7 @@ fn get_minify_result( source_text: &str, source_type: SourceType, ) -> bool { - let options = CodegenOptions::default().with_typescript(source_type.is_typescript()); + let options = CodegenOptions::default(); let allocator = Allocator::default(); let parse_result1 = Parser::new(&allocator, source_text, source_type).parse(); let source_text1 = diff --git a/tasks/coverage/src/transformer.rs b/tasks/coverage/src/transformer.rs index 1cb18893b..fdb76b19f 100644 --- a/tasks/coverage/src/transformer.rs +++ b/tasks/coverage/src/transformer.rs @@ -43,7 +43,7 @@ fn get_result( &filename, source_text, parse_result1.trivias.clone(), - CodegenOptions::default().with_typescript(true), + CodegenOptions::default(), ) .build(&program) .source_text; diff --git a/tasks/transform_conformance/src/test_case.rs b/tasks/transform_conformance/src/test_case.rs index dae0aa8bc..b7268f0ec 100644 --- a/tasks/transform_conformance/src/test_case.rs +++ b/tasks/transform_conformance/src/test_case.rs @@ -182,14 +182,9 @@ pub trait TestCase { .build(&mut program); result.map(|()| { - Codegen::::new( - "", - &source_text, - ret.trivias, - CodegenOptions::default().with_typescript(true), - ) - .build(&program) - .source_text + Codegen::::new("", &source_text, ret.trivias, CodegenOptions::default()) + .build(&program) + .source_text }) } } @@ -256,7 +251,7 @@ impl TestCase for ConformanceTestCase { println!("output_path: {output_path:?}"); } - let codegen_options = CodegenOptions::default().with_typescript(true); + let codegen_options = CodegenOptions::default(); let mut transformed_code = String::new(); let mut actual_errors = String::new(); @@ -391,7 +386,7 @@ impl ExecTestCase { "", &source_text, transformed_ret.trivias, - CodegenOptions::default().with_typescript(true), + CodegenOptions::default(), ) .build(&transformed_ret.program) .source_text;