mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
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.
This commit is contained in:
parent
4f2db46ee5
commit
534242a729
15 changed files with 144 additions and 271 deletions
|
|
@ -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::<false>::new("", &source_text, ret.trivias, options)
|
||||
.build(&ret.program)
|
||||
.source_text;
|
||||
|
|
|
|||
|
|
@ -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::<false>::new(
|
||||
path.to_string_lossy().as_ref(),
|
||||
|
|
|
|||
|
|
@ -511,18 +511,14 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> 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<MINIFY> 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<MINIFY> 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<MINIFY> for UsingDeclaration<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> 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<MINIFY> 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<MINIFY> for FunctionBody<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> 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<MINIFY> 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<MINIFY> for ImportAttribute<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> 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<MINIFY> for ExportNamedDeclaration<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> for ModuleExportName<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> for ExportAllDeclaration<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> 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<const MINIFY: bool> GenComment<MINIFY> for Function<'_> {
|
|||
|
||||
impl<'a, const MINIFY: bool> GenExpr<MINIFY> 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<MINIFY> for IdentifierReference<'a> {
|
||||
|
|
@ -1427,10 +1385,8 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> 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<MINIFY> 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<MINIFY> 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<MINIFY> for MetaProperty<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> 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<MINIFY> for StaticBlock<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> 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<MINIFY> 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<MINIFY> 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<MINIFY> for PropertyDefinition<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -478,9 +478,6 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTypeParameterInstantiation<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> for TSModuleDeclaration<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> for TSTypeAliasDeclaration<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> for TSInterfaceHeritage<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> for TSConstructorType<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> 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<MINIFY> for TSModuleReference<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> GenExpr<MINIFY> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<oxc_sourcemap::SourceMap>,
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ fn test(source_text: &str, expected: &str, options: Option<CodegenOptions>) {
|
|||
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::<false>::new("", source_text, ret.trivias, options).build(program).source_text;
|
||||
let result = Codegen::<false>::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::<false>::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,]);
|
||||
",
|
||||
);
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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)=>{};");
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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::<true>::new("", source_text, ret.trivias, codegen_options)
|
||||
.build(program)
|
||||
|
|
|
|||
|
|
@ -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 ="
|
||||
|
|
|
|||
|
|
@ -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::<false>::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 =
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -182,14 +182,9 @@ pub trait TestCase {
|
|||
.build(&mut program);
|
||||
|
||||
result.map(|()| {
|
||||
Codegen::<false>::new(
|
||||
"",
|
||||
&source_text,
|
||||
ret.trivias,
|
||||
CodegenOptions::default().with_typescript(true),
|
||||
)
|
||||
.build(&program)
|
||||
.source_text
|
||||
Codegen::<false>::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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue