From 09b92b6086561d0df79202226301a0ade9d22246 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Sat, 15 Jun 2024 06:44:14 +0000 Subject: [PATCH] refactor(codegen): move `gen_ts` into `gen` to make searching things easier (#3680) --- crates/oxc_codegen/src/gen.rs | 704 ++++++++++++++++++++++++++++++ crates/oxc_codegen/src/gen_ts.rs | 709 ------------------------------- crates/oxc_codegen/src/lib.rs | 1 - 3 files changed, 704 insertions(+), 710 deletions(-) delete mode 100644 crates/oxc_codegen/src/gen_ts.rs diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 8751478df6153..9e126685681d3 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -2553,3 +2553,707 @@ impl<'a, const MINIFY: bool> Gen for Decorator<'a> { }); } } + +impl<'a, const MINIFY: bool> Gen for TSTypeParameterDeclaration<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"<"); + p.print_list(&self.params, ctx); + p.print_str(b">"); + } +} + +impl<'a, const MINIFY: bool> Gen for TSTypeAnnotation<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + self.type_annotation.gen(p, ctx); + } +} + +impl<'a, const MINIFY: bool> Gen for TSType<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + match self { + Self::TSFunctionType(decl) => decl.gen(p, ctx), + Self::TSConstructorType(decl) => { + decl.gen(p, ctx); + } + Self::TSArrayType(decl) => { + p.print_str(b"("); + decl.element_type.gen(p, ctx); + p.print_str(b")[]"); + } + Self::TSTupleType(decl) => { + p.print_str(b"["); + p.print_list(&decl.element_types, ctx); + p.print_str(b"]"); + } + Self::TSUnionType(decl) => { + if decl.types.len() == 1 { + decl.types[0].gen(p, ctx); + return; + } + + p.print_str(b"("); + for (index, item) in decl.types.iter().enumerate() { + if index != 0 { + p.print_soft_space(); + p.print_str(b"|"); + p.print_soft_space(); + } + p.print_str(b"("); + item.gen(p, ctx); + p.print_str(b")"); + } + p.print_str(b")"); + } + Self::TSIntersectionType(decl) => { + if decl.types.len() == 1 { + decl.types[0].gen(p, ctx); + return; + } + + p.print_str(b"("); + for (index, item) in decl.types.iter().enumerate() { + if index != 0 { + p.print_soft_space(); + p.print_str(b"&"); + p.print_soft_space(); + } + p.print_str(b"("); + item.gen(p, ctx); + p.print_str(b")"); + } + p.print_str(b")"); + } + Self::TSConditionalType(decl) => { + decl.check_type.gen(p, ctx); + p.print_str(b" extends ("); + decl.extends_type.gen(p, ctx); + p.print_str(b") ? "); + decl.true_type.gen(p, ctx); + p.print_str(b" : "); + decl.false_type.gen(p, ctx); + } + Self::TSInferType(decl) => { + p.print_str(b"infer "); + decl.type_parameter.gen(p, ctx); + } + Self::TSIndexedAccessType(decl) => { + decl.object_type.gen(p, ctx); + p.print_str(b"["); + decl.index_type.gen(p, ctx); + p.print_str(b"]"); + } + Self::TSMappedType(decl) => { + p.print_str(b"{"); + match decl.readonly { + TSMappedTypeModifierOperator::True => { + p.print_str(b"readonly"); + } + TSMappedTypeModifierOperator::Plus => { + p.print_str(b"+readonly"); + } + TSMappedTypeModifierOperator::Minus => { + p.print_str(b"-readonly"); + } + TSMappedTypeModifierOperator::None => {} + } + p.print_hard_space(); + p.print_str(b"["); + decl.type_parameter.name.gen(p, ctx); + if let Some(constraint) = &decl.type_parameter.constraint { + p.print_str(b" in "); + constraint.gen(p, ctx); + } + if let Some(default) = &decl.type_parameter.default { + p.print_str(b" = "); + default.gen(p, ctx); + } + p.print_str(b"]"); + match decl.optional { + TSMappedTypeModifierOperator::True => { + p.print_str(b"?"); + } + TSMappedTypeModifierOperator::Plus => { + p.print_str(b"+?"); + } + TSMappedTypeModifierOperator::Minus => { + p.print_str(b"-?"); + } + TSMappedTypeModifierOperator::None => {} + } + p.print_soft_space(); + if let Some(type_annotation) = &decl.type_annotation { + p.print_str(b":"); + p.print_soft_space(); + type_annotation.gen(p, ctx); + } + p.print_semicolon_if_needed(); + p.print_str(b"}"); + } + Self::TSNamedTupleMember(decl) => { + decl.gen(p, ctx); + } + Self::TSLiteralType(decl) => { + decl.literal.gen(p, ctx); + } + Self::TSImportType(decl) => { + decl.gen(p, ctx); + } + Self::TSQualifiedName(decl) => { + decl.left.gen(p, ctx); + p.print_str(b"."); + decl.right.gen(p, ctx); + } + Self::TSAnyKeyword(_) => { + p.print_str(b"any"); + } + Self::TSBigIntKeyword(_) => { + p.print_str(b"bigint"); + } + Self::TSBooleanKeyword(_) => { + p.print_str(b"boolean"); + } + Self::TSNeverKeyword(_) => { + p.print_str(b"never"); + } + Self::TSNullKeyword(_) => { + p.print_str(b"null"); + } + Self::TSNumberKeyword(_) => { + p.print_str(b"number"); + } + Self::TSObjectKeyword(_) => { + p.print_str(b"object"); + } + Self::TSStringKeyword(_) => { + p.print_str(b"string"); + } + Self::TSSymbolKeyword(_) => { + p.print_str(b"symbol"); + } + Self::TSThisType(_) => { + p.print_str(b"this"); + } + Self::TSUndefinedKeyword(_) => { + p.print_str(b"undefined"); + } + Self::TSUnknownKeyword(_) => { + p.print_str(b"unknown"); + } + Self::TSVoidKeyword(_) => { + p.print_str(b"void"); + } + Self::TSTemplateLiteralType(decl) => decl.gen(p, ctx), + Self::TSTypeLiteral(decl) => { + p.print_block_start(decl.span.start); + for item in &decl.members { + item.gen(p, ctx); + p.print_semicolon(); + } + p.print_block_end(decl.span.end); + } + Self::TSTypeOperatorType(decl) => { + match decl.operator { + TSTypeOperatorOperator::Keyof => { + p.print_str(b"keyof "); + } + TSTypeOperatorOperator::Unique => { + p.print_str(b"unique "); + } + TSTypeOperatorOperator::Readonly => { + p.print_str(b"readonly "); + } + } + decl.type_annotation.gen(p, ctx); + } + Self::TSTypePredicate(decl) => { + if decl.asserts { + p.print_str(b"asserts "); + } + match &decl.parameter_name { + TSTypePredicateName::Identifier(ident) => { + ident.gen(p, ctx); + } + TSTypePredicateName::This(_ident) => { + p.print_str(b"this"); + } + } + if let Some(type_annotation) = &decl.type_annotation { + p.print_str(b" is "); + type_annotation.gen(p, ctx); + } + } + Self::TSTypeQuery(decl) => decl.gen(p, ctx), + Self::TSTypeReference(decl) => { + decl.type_name.gen(p, ctx); + if let Some(type_parameters) = &decl.type_parameters { + type_parameters.gen(p, ctx); + } + } + Self::JSDocNullableType(decl) => { + if decl.postfix { + decl.type_annotation.gen(p, ctx); + p.print_str(b"?"); + } else { + p.print_str(b"?"); + decl.type_annotation.gen(p, ctx); + } + } + Self::JSDocUnknownType(_decl) => p.print_str(b"unknown"), + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSTemplateLiteralType<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"`"); + for (index, item) in self.quasis.iter().enumerate() { + if index != 0 { + if let Some(types) = self.types.get(index - 1) { + p.print_str(b"${"); + types.gen(p, ctx); + p.print_str(b"}"); + } + } + p.print_str(item.value.raw.as_bytes()); + } + p.print_str(b"`"); + } +} +impl<'a, const MINIFY: bool> Gen for TSTypeName<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + match self { + Self::IdentifierReference(decl) => { + p.print_str(decl.name.as_bytes()); + } + Self::QualifiedName(decl) => { + decl.left.gen(p, ctx); + p.print_str(b"."); + decl.right.gen(p, ctx); + } + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSLiteral<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + match self { + Self::BooleanLiteral(decl) => decl.gen(p, ctx), + Self::NullLiteral(decl) => decl.gen(p, ctx), + Self::NumericLiteral(decl) => decl.gen(p, ctx), + Self::BigintLiteral(decl) => decl.gen(p, ctx), + Self::RegExpLiteral(decl) => decl.gen(p, ctx), + Self::StringLiteral(decl) => decl.gen(p, ctx), + Self::TemplateLiteral(decl) => decl.gen(p, ctx), + Self::UnaryExpression(decl) => decl.gen_expr(p, Precedence::Assign, ctx), + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSTypeParameter<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + self.name.gen(p, ctx); + if let Some(constraint) = &self.constraint { + p.print_str(b" extends "); + constraint.gen(p, ctx); + } + if let Some(default) = &self.default { + p.print_str(b" = "); + default.gen(p, ctx); + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSFunctionType<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + if let Some(type_parameters) = &self.type_parameters { + type_parameters.gen(p, ctx); + } + p.print_str(b"("); + if let Some(this_param) = &self.this_param { + this_param.this.gen(p, ctx); + p.print_str(b":"); + if let Some(type_annotation) = &this_param.type_annotation { + type_annotation.gen(p, ctx); + } else { + p.print_str(b"unknown"); + } + if !self.params.is_empty() || self.params.rest.is_some() { + p.print_str(b","); + } + p.print_soft_space(); + } + self.params.gen(p, ctx); + p.print_str(b")"); + p.print_soft_space(); + p.print_str(b"=>"); + p.print_soft_space(); + self.return_type.gen(p, ctx); + } +} + +impl<'a, const MINIFY: bool> Gen for TSSignature<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_soft_space(); + match self { + Self::TSIndexSignature(signature) => signature.gen(p, ctx), + Self::TSPropertySignature(signature) => { + if signature.readonly { + p.print_str(b"readonly"); + p.print_hard_space(); + } + if signature.computed { + p.print(b'['); + signature.key.gen(p, ctx); + p.print(b']'); + } else { + match &signature.key { + PropertyKey::StaticIdentifier(key) => { + key.gen(p, ctx); + } + PropertyKey::PrivateIdentifier(key) => { + p.print_str(key.name.as_bytes()); + } + key @ match_expression!(PropertyKey) => { + key.to_expression().gen_expr(p, Precedence::Assign, ctx); + } + } + } + if signature.optional { + p.print_str(b"?"); + } + if let Some(type_annotation) = &signature.type_annotation { + p.print_colon(); + p.print_soft_space(); + type_annotation.gen(p, ctx); + } + } + Self::TSCallSignatureDeclaration(signature) => { + p.print_str(b"("); + signature.params.gen(p, ctx); + p.print_str(b")"); + if let Some(return_type) = &signature.return_type { + p.print_colon(); + p.print_soft_space(); + return_type.gen(p, ctx); + } + } + Self::TSConstructSignatureDeclaration(signature) => { + p.print_str(b"new "); + p.print_str(b"("); + signature.params.gen(p, ctx); + p.print_str(b")"); + if let Some(return_type) = &signature.return_type { + p.print_colon(); + p.print_soft_space(); + return_type.gen(p, ctx); + } + } + Self::TSMethodSignature(signature) => { + match signature.kind { + TSMethodSignatureKind::Method => {} + TSMethodSignatureKind::Get => p.print_str(b"get "), + TSMethodSignatureKind::Set => p.print_str(b"set "), + } + if signature.computed { + p.print(b'['); + signature.key.gen(p, ctx); + p.print(b']'); + } else { + match &signature.key { + PropertyKey::StaticIdentifier(key) => { + key.gen(p, ctx); + } + PropertyKey::PrivateIdentifier(key) => { + p.print_str(key.name.as_bytes()); + } + key @ match_expression!(PropertyKey) => { + key.to_expression().gen_expr(p, Precedence::Assign, ctx); + } + } + } + if signature.optional { + p.print_str(b"?"); + } + if let Some(type_parameters) = &signature.type_parameters { + type_parameters.gen(p, ctx); + } + p.print_str(b"("); + signature.params.gen(p, ctx); + p.print_str(b")"); + if let Some(return_type) = &signature.return_type { + p.print_colon(); + p.print_soft_space(); + return_type.gen(p, ctx); + } + } + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSTypeQuery<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"typeof "); + self.expr_name.gen(p, ctx); + if let Some(type_params) = &self.type_parameters { + type_params.gen(p, ctx); + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSTypeQueryExprName<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + match self { + match_ts_type_name!(Self) => self.to_ts_type_name().gen(p, ctx), + Self::TSImportType(decl) => decl.gen(p, ctx), + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSImportType<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"import("); + self.argument.gen(p, ctx); + p.print_str(b")"); + } +} + +impl<'a, const MINIFY: bool> Gen for TSTypeParameterInstantiation<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"<"); + p.print_list(&self.params, ctx); + p.print_str(b">"); + } +} + +impl<'a, const MINIFY: bool> Gen for TSIndexSignature<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"["); + for (index, parameter) in self.parameters.iter().enumerate() { + if index != 0 { + p.print_str(b" | "); + } + p.print_str(parameter.name.as_bytes()); + p.print_colon(); + p.print_soft_space(); + parameter.type_annotation.gen(p, ctx); + } + p.print_str(b"]"); + p.print_colon(); + p.print_soft_space(); + self.type_annotation.gen(p, ctx); + } +} + +impl<'a, const MINIFY: bool> Gen for TSTupleElement<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + match self { + match_ts_type!(TSTupleElement) => self.to_ts_type().gen(p, ctx), + TSTupleElement::TSOptionalType(ts_type) => { + ts_type.type_annotation.gen(p, ctx); + p.print_str(b"?"); + } + TSTupleElement::TSRestType(ts_type) => { + p.print_str(b"..."); + ts_type.type_annotation.gen(p, ctx); + } + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSNamedTupleMember<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + self.label.gen(p, ctx); + p.print_str(b":"); + p.print_soft_space(); + self.element_type.gen(p, ctx); + } +} + +impl<'a, const MINIFY: bool> Gen for TSModuleDeclaration<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + if self.modifiers.contains(ModifierKind::Export) { + p.print_str(b"export "); + } + if self.modifiers.contains(ModifierKind::Declare) { + p.print_str(b"declare "); + } + p.print_str(b"module"); + p.print_space_before_identifier(); + let name = self.id.name(); + p.wrap_quote(name, |p, _| p.print_str(name.as_bytes())); + p.print_hard_space(); + match &self.body { + Some(TSModuleDeclarationBody::TSModuleDeclaration(body)) => { + p.print_block_start(body.span.start); + body.gen(p, ctx); + p.print_block_end(body.span.end); + } + Some(TSModuleDeclarationBody::TSModuleBlock(body)) => { + p.print_block_start(body.span.start); + for item in &body.body { + p.print_semicolon_if_needed(); + item.gen(p, ctx); + } + p.print_semicolon_if_needed(); + p.print_block_end(body.span.end); + } + None => {} + } + if MINIFY { + p.print_semicolon(); + } + p.print_hard_space(); + p.print_soft_newline(); + } +} + +impl<'a, const MINIFY: bool> Gen for TSTypeAliasDeclaration<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"type "); + self.id.gen(p, ctx); + if let Some(type_parameters) = &self.type_parameters { + type_parameters.gen(p, ctx); + } + p.print_str(b" = "); + self.type_annotation.gen(p, ctx); + p.print_semicolon_after_statement(); + } +} + +impl<'a, const MINIFY: bool> Gen for TSInterfaceDeclaration<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"interface"); + p.print_hard_space(); + self.id.gen(p, ctx); + if let Some(type_parameters) = &self.type_parameters { + type_parameters.gen(p, ctx); + } + if let Some(extends) = &self.extends { + if !extends.is_empty() { + p.print_str(b" extends "); + p.print_list(extends, ctx); + } + } + p.print_soft_space(); + p.print_block_start(self.body.span.start); + for item in &self.body.body { + p.print_indent(); + p.print_semicolon_if_needed(); + item.gen(p, ctx); + p.print_semicolon_after_statement(); + } + p.print_block_end(self.body.span.end); + if MINIFY { + p.print_hard_space(); + } + p.print_soft_newline(); + p.needs_semicolon = false; + } +} + +impl<'a, const MINIFY: bool> Gen for TSInterfaceHeritage<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + self.expression.gen_expr(p, Precedence::Call, ctx); + if let Some(type_parameters) = &self.type_parameters { + type_parameters.gen(p, ctx); + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSEnumDeclaration<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_indent(); + if self.modifiers.contains(ModifierKind::Export) { + p.print_str(b"export "); + } + if self.modifiers.contains(ModifierKind::Declare) { + p.print_str(b"declare "); + } + if self.modifiers.contains(ModifierKind::Const) { + p.print_str(b"const "); + } + p.print_space_before_identifier(); + p.print_str(b"enum "); + self.id.gen(p, ctx); + p.print_space_before_identifier(); + p.print_block_start(self.span.start); + p.print_list(&self.members, ctx); + p.print_block_end(self.span.end); + p.print_hard_space(); + } +} + +impl<'a, const MINIFY: bool> Gen for TSEnumMember<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + match &self.id { + TSEnumMemberName::StaticIdentifier(decl) => decl.gen(p, ctx), + TSEnumMemberName::StaticStringLiteral(decl) => decl.gen(p, ctx), + TSEnumMemberName::StaticNumericLiteral(decl) => decl.gen(p, ctx), + decl @ match_expression!(TSEnumMemberName) => { + p.print_str(b"["); + decl.to_expression().gen_expr(p, Precedence::lowest(), ctx); + p.print_str(b"]"); + } + } + } +} + +impl<'a, const MINIFY: bool> Gen for TSConstructorType<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + if self.r#abstract { + p.print_str(b"abstract "); + } + p.print_str(b"new "); + if let Some(type_parameters) = &self.type_parameters { + type_parameters.gen(p, ctx); + } + p.print_str(b"("); + self.params.gen(p, ctx); + p.print_str(b")"); + p.print_soft_space(); + p.print_str(b"=>"); + p.print_soft_space(); + self.return_type.gen(p, ctx); + } +} + +impl<'a, const MINIFY: bool> Gen for TSImportEqualsDeclaration<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + p.print_str(b"import "); + self.id.gen(p, ctx); + p.print_str(b" = "); + self.module_reference.gen(p, ctx); + p.print_semicolon_after_statement(); + } +} +impl<'a, const MINIFY: bool> Gen for TSModuleReference<'a> { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { + match self { + Self::ExternalModuleReference(decl) => { + p.print_str(b"require("); + decl.expression.gen(p, ctx); + p.print_str(b")"); + } + match_ts_type_name!(Self) => self.to_ts_type_name().gen(p, ctx), + } + } +} + +impl<'a, const MINIFY: bool> GenExpr for TSTypeAssertion<'a> { + fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) { + p.print_str(b"<"); + self.type_annotation.gen(p, ctx); + p.print_str(b">"); + self.expression.gen_expr(p, precedence, ctx); + } +} + +impl Gen for TSAccessibility { + fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) { + match self { + Self::Public => p.print_str(b"public "), + Self::Private => p.print_str(b"private "), + Self::Protected => p.print_str(b"protected "), + } + } +} diff --git a/crates/oxc_codegen/src/gen_ts.rs b/crates/oxc_codegen/src/gen_ts.rs deleted file mode 100644 index 3f0f304782590..0000000000000 --- a/crates/oxc_codegen/src/gen_ts.rs +++ /dev/null @@ -1,709 +0,0 @@ -#[allow(clippy::wildcard_imports)] -use oxc_ast::ast::*; -use oxc_syntax::precedence::Precedence; - -use crate::{context::Context, Codegen, Gen, GenExpr}; - -impl<'a, const MINIFY: bool> Gen for TSTypeParameterDeclaration<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"<"); - p.print_list(&self.params, ctx); - p.print_str(b">"); - } -} - -impl<'a, const MINIFY: bool> Gen for TSTypeAnnotation<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - self.type_annotation.gen(p, ctx); - } -} - -impl<'a, const MINIFY: bool> Gen for TSType<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - match self { - Self::TSFunctionType(decl) => decl.gen(p, ctx), - Self::TSConstructorType(decl) => { - decl.gen(p, ctx); - } - Self::TSArrayType(decl) => { - p.print_str(b"("); - decl.element_type.gen(p, ctx); - p.print_str(b")[]"); - } - Self::TSTupleType(decl) => { - p.print_str(b"["); - p.print_list(&decl.element_types, ctx); - p.print_str(b"]"); - } - Self::TSUnionType(decl) => { - if decl.types.len() == 1 { - decl.types[0].gen(p, ctx); - return; - } - - p.print_str(b"("); - for (index, item) in decl.types.iter().enumerate() { - if index != 0 { - p.print_soft_space(); - p.print_str(b"|"); - p.print_soft_space(); - } - p.print_str(b"("); - item.gen(p, ctx); - p.print_str(b")"); - } - p.print_str(b")"); - } - Self::TSIntersectionType(decl) => { - if decl.types.len() == 1 { - decl.types[0].gen(p, ctx); - return; - } - - p.print_str(b"("); - for (index, item) in decl.types.iter().enumerate() { - if index != 0 { - p.print_soft_space(); - p.print_str(b"&"); - p.print_soft_space(); - } - p.print_str(b"("); - item.gen(p, ctx); - p.print_str(b")"); - } - p.print_str(b")"); - } - Self::TSConditionalType(decl) => { - decl.check_type.gen(p, ctx); - p.print_str(b" extends ("); - decl.extends_type.gen(p, ctx); - p.print_str(b") ? "); - decl.true_type.gen(p, ctx); - p.print_str(b" : "); - decl.false_type.gen(p, ctx); - } - Self::TSInferType(decl) => { - p.print_str(b"infer "); - decl.type_parameter.gen(p, ctx); - } - Self::TSIndexedAccessType(decl) => { - decl.object_type.gen(p, ctx); - p.print_str(b"["); - decl.index_type.gen(p, ctx); - p.print_str(b"]"); - } - Self::TSMappedType(decl) => { - p.print_str(b"{"); - match decl.readonly { - TSMappedTypeModifierOperator::True => { - p.print_str(b"readonly"); - } - TSMappedTypeModifierOperator::Plus => { - p.print_str(b"+readonly"); - } - TSMappedTypeModifierOperator::Minus => { - p.print_str(b"-readonly"); - } - TSMappedTypeModifierOperator::None => {} - } - p.print_hard_space(); - p.print_str(b"["); - decl.type_parameter.name.gen(p, ctx); - if let Some(constraint) = &decl.type_parameter.constraint { - p.print_str(b" in "); - constraint.gen(p, ctx); - } - if let Some(default) = &decl.type_parameter.default { - p.print_str(b" = "); - default.gen(p, ctx); - } - p.print_str(b"]"); - match decl.optional { - TSMappedTypeModifierOperator::True => { - p.print_str(b"?"); - } - TSMappedTypeModifierOperator::Plus => { - p.print_str(b"+?"); - } - TSMappedTypeModifierOperator::Minus => { - p.print_str(b"-?"); - } - TSMappedTypeModifierOperator::None => {} - } - p.print_soft_space(); - if let Some(type_annotation) = &decl.type_annotation { - p.print_str(b":"); - p.print_soft_space(); - type_annotation.gen(p, ctx); - } - p.print_semicolon_if_needed(); - p.print_str(b"}"); - } - Self::TSNamedTupleMember(decl) => { - decl.gen(p, ctx); - } - Self::TSLiteralType(decl) => { - decl.literal.gen(p, ctx); - } - Self::TSImportType(decl) => { - decl.gen(p, ctx); - } - Self::TSQualifiedName(decl) => { - decl.left.gen(p, ctx); - p.print_str(b"."); - decl.right.gen(p, ctx); - } - Self::TSAnyKeyword(_) => { - p.print_str(b"any"); - } - Self::TSBigIntKeyword(_) => { - p.print_str(b"bigint"); - } - Self::TSBooleanKeyword(_) => { - p.print_str(b"boolean"); - } - Self::TSNeverKeyword(_) => { - p.print_str(b"never"); - } - Self::TSNullKeyword(_) => { - p.print_str(b"null"); - } - Self::TSNumberKeyword(_) => { - p.print_str(b"number"); - } - Self::TSObjectKeyword(_) => { - p.print_str(b"object"); - } - Self::TSStringKeyword(_) => { - p.print_str(b"string"); - } - Self::TSSymbolKeyword(_) => { - p.print_str(b"symbol"); - } - Self::TSThisType(_) => { - p.print_str(b"this"); - } - Self::TSUndefinedKeyword(_) => { - p.print_str(b"undefined"); - } - Self::TSUnknownKeyword(_) => { - p.print_str(b"unknown"); - } - Self::TSVoidKeyword(_) => { - p.print_str(b"void"); - } - Self::TSTemplateLiteralType(decl) => decl.gen(p, ctx), - Self::TSTypeLiteral(decl) => { - p.print_block_start(decl.span.start); - for item in &decl.members { - item.gen(p, ctx); - p.print_semicolon(); - } - p.print_block_end(decl.span.end); - } - Self::TSTypeOperatorType(decl) => { - match decl.operator { - TSTypeOperatorOperator::Keyof => { - p.print_str(b"keyof "); - } - TSTypeOperatorOperator::Unique => { - p.print_str(b"unique "); - } - TSTypeOperatorOperator::Readonly => { - p.print_str(b"readonly "); - } - } - decl.type_annotation.gen(p, ctx); - } - Self::TSTypePredicate(decl) => { - if decl.asserts { - p.print_str(b"asserts "); - } - match &decl.parameter_name { - TSTypePredicateName::Identifier(ident) => { - ident.gen(p, ctx); - } - TSTypePredicateName::This(_ident) => { - p.print_str(b"this"); - } - } - if let Some(type_annotation) = &decl.type_annotation { - p.print_str(b" is "); - type_annotation.gen(p, ctx); - } - } - Self::TSTypeQuery(decl) => decl.gen(p, ctx), - Self::TSTypeReference(decl) => { - decl.type_name.gen(p, ctx); - if let Some(type_parameters) = &decl.type_parameters { - type_parameters.gen(p, ctx); - } - } - Self::JSDocNullableType(decl) => { - if decl.postfix { - decl.type_annotation.gen(p, ctx); - p.print_str(b"?"); - } else { - p.print_str(b"?"); - decl.type_annotation.gen(p, ctx); - } - } - Self::JSDocUnknownType(_decl) => p.print_str(b"unknown"), - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSTemplateLiteralType<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"`"); - for (index, item) in self.quasis.iter().enumerate() { - if index != 0 { - if let Some(types) = self.types.get(index - 1) { - p.print_str(b"${"); - types.gen(p, ctx); - p.print_str(b"}"); - } - } - p.print_str(item.value.raw.as_bytes()); - } - p.print_str(b"`"); - } -} -impl<'a, const MINIFY: bool> Gen for TSTypeName<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - match self { - Self::IdentifierReference(decl) => { - p.print_str(decl.name.as_bytes()); - } - Self::QualifiedName(decl) => { - decl.left.gen(p, ctx); - p.print_str(b"."); - decl.right.gen(p, ctx); - } - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSLiteral<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - match self { - Self::BooleanLiteral(decl) => decl.gen(p, ctx), - Self::NullLiteral(decl) => decl.gen(p, ctx), - Self::NumericLiteral(decl) => decl.gen(p, ctx), - Self::BigintLiteral(decl) => decl.gen(p, ctx), - Self::RegExpLiteral(decl) => decl.gen(p, ctx), - Self::StringLiteral(decl) => decl.gen(p, ctx), - Self::TemplateLiteral(decl) => decl.gen(p, ctx), - Self::UnaryExpression(decl) => decl.gen_expr(p, Precedence::Assign, ctx), - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSTypeParameter<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - self.name.gen(p, ctx); - if let Some(constraint) = &self.constraint { - p.print_str(b" extends "); - constraint.gen(p, ctx); - } - if let Some(default) = &self.default { - p.print_str(b" = "); - default.gen(p, ctx); - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSFunctionType<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if let Some(type_parameters) = &self.type_parameters { - type_parameters.gen(p, ctx); - } - p.print_str(b"("); - if let Some(this_param) = &self.this_param { - this_param.this.gen(p, ctx); - p.print_str(b":"); - if let Some(type_annotation) = &this_param.type_annotation { - type_annotation.gen(p, ctx); - } else { - p.print_str(b"unknown"); - } - if !self.params.is_empty() || self.params.rest.is_some() { - p.print_str(b","); - } - p.print_soft_space(); - } - self.params.gen(p, ctx); - p.print_str(b")"); - p.print_soft_space(); - p.print_str(b"=>"); - p.print_soft_space(); - self.return_type.gen(p, ctx); - } -} - -impl<'a, const MINIFY: bool> Gen for TSSignature<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_soft_space(); - match self { - Self::TSIndexSignature(signature) => signature.gen(p, ctx), - Self::TSPropertySignature(signature) => { - if signature.readonly { - p.print_str(b"readonly"); - p.print_hard_space(); - } - if signature.computed { - p.print(b'['); - signature.key.gen(p, ctx); - p.print(b']'); - } else { - match &signature.key { - PropertyKey::StaticIdentifier(key) => { - key.gen(p, ctx); - } - PropertyKey::PrivateIdentifier(key) => { - p.print_str(key.name.as_bytes()); - } - key @ match_expression!(PropertyKey) => { - key.to_expression().gen_expr(p, Precedence::Assign, ctx); - } - } - } - if signature.optional { - p.print_str(b"?"); - } - if let Some(type_annotation) = &signature.type_annotation { - p.print_colon(); - p.print_soft_space(); - type_annotation.gen(p, ctx); - } - } - Self::TSCallSignatureDeclaration(signature) => { - p.print_str(b"("); - signature.params.gen(p, ctx); - p.print_str(b")"); - if let Some(return_type) = &signature.return_type { - p.print_colon(); - p.print_soft_space(); - return_type.gen(p, ctx); - } - } - Self::TSConstructSignatureDeclaration(signature) => { - p.print_str(b"new "); - p.print_str(b"("); - signature.params.gen(p, ctx); - p.print_str(b")"); - if let Some(return_type) = &signature.return_type { - p.print_colon(); - p.print_soft_space(); - return_type.gen(p, ctx); - } - } - Self::TSMethodSignature(signature) => { - match signature.kind { - TSMethodSignatureKind::Method => {} - TSMethodSignatureKind::Get => p.print_str(b"get "), - TSMethodSignatureKind::Set => p.print_str(b"set "), - } - if signature.computed { - p.print(b'['); - signature.key.gen(p, ctx); - p.print(b']'); - } else { - match &signature.key { - PropertyKey::StaticIdentifier(key) => { - key.gen(p, ctx); - } - PropertyKey::PrivateIdentifier(key) => { - p.print_str(key.name.as_bytes()); - } - key @ match_expression!(PropertyKey) => { - key.to_expression().gen_expr(p, Precedence::Assign, ctx); - } - } - } - if signature.optional { - p.print_str(b"?"); - } - if let Some(type_parameters) = &signature.type_parameters { - type_parameters.gen(p, ctx); - } - p.print_str(b"("); - signature.params.gen(p, ctx); - p.print_str(b")"); - if let Some(return_type) = &signature.return_type { - p.print_colon(); - p.print_soft_space(); - return_type.gen(p, ctx); - } - } - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSTypeQuery<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"typeof "); - self.expr_name.gen(p, ctx); - if let Some(type_params) = &self.type_parameters { - type_params.gen(p, ctx); - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSTypeQueryExprName<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - match self { - match_ts_type_name!(Self) => self.to_ts_type_name().gen(p, ctx), - Self::TSImportType(decl) => decl.gen(p, ctx), - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSImportType<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"import("); - self.argument.gen(p, ctx); - p.print_str(b")"); - } -} - -impl<'a, const MINIFY: bool> Gen for TSTypeParameterInstantiation<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"<"); - p.print_list(&self.params, ctx); - p.print_str(b">"); - } -} - -impl<'a, const MINIFY: bool> Gen for TSIndexSignature<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"["); - for (index, parameter) in self.parameters.iter().enumerate() { - if index != 0 { - p.print_str(b" | "); - } - p.print_str(parameter.name.as_bytes()); - p.print_colon(); - p.print_soft_space(); - parameter.type_annotation.gen(p, ctx); - } - p.print_str(b"]"); - p.print_colon(); - p.print_soft_space(); - self.type_annotation.gen(p, ctx); - } -} - -impl<'a, const MINIFY: bool> Gen for TSTupleElement<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - match self { - match_ts_type!(TSTupleElement) => self.to_ts_type().gen(p, ctx), - TSTupleElement::TSOptionalType(ts_type) => { - ts_type.type_annotation.gen(p, ctx); - p.print_str(b"?"); - } - TSTupleElement::TSRestType(ts_type) => { - p.print_str(b"..."); - ts_type.type_annotation.gen(p, ctx); - } - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSNamedTupleMember<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - self.label.gen(p, ctx); - p.print_str(b":"); - p.print_soft_space(); - self.element_type.gen(p, ctx); - } -} - -impl<'a, const MINIFY: bool> Gen for TSModuleDeclaration<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if self.modifiers.contains(ModifierKind::Export) { - p.print_str(b"export "); - } - if self.modifiers.contains(ModifierKind::Declare) { - p.print_str(b"declare "); - } - p.print_str(b"module"); - p.print_space_before_identifier(); - let name = self.id.name(); - p.wrap_quote(name, |p, _| p.print_str(name.as_bytes())); - p.print_hard_space(); - match &self.body { - Some(TSModuleDeclarationBody::TSModuleDeclaration(body)) => { - p.print_block_start(body.span.start); - body.gen(p, ctx); - p.print_block_end(body.span.end); - } - Some(TSModuleDeclarationBody::TSModuleBlock(body)) => { - p.print_block_start(body.span.start); - for item in &body.body { - p.print_semicolon_if_needed(); - item.gen(p, ctx); - } - p.print_semicolon_if_needed(); - p.print_block_end(body.span.end); - } - None => {} - } - if MINIFY { - p.print_semicolon(); - } - p.print_hard_space(); - p.print_soft_newline(); - } -} - -impl<'a, const MINIFY: bool> Gen for TSTypeAliasDeclaration<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"type "); - self.id.gen(p, ctx); - if let Some(type_parameters) = &self.type_parameters { - type_parameters.gen(p, ctx); - } - p.print_str(b" = "); - self.type_annotation.gen(p, ctx); - p.print_semicolon_after_statement(); - } -} - -impl<'a, const MINIFY: bool> Gen for TSInterfaceDeclaration<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"interface"); - p.print_hard_space(); - self.id.gen(p, ctx); - if let Some(type_parameters) = &self.type_parameters { - type_parameters.gen(p, ctx); - } - if let Some(extends) = &self.extends { - if !extends.is_empty() { - p.print_str(b" extends "); - p.print_list(extends, ctx); - } - } - p.print_soft_space(); - p.print_block_start(self.body.span.start); - for item in &self.body.body { - p.print_indent(); - p.print_semicolon_if_needed(); - item.gen(p, ctx); - p.print_semicolon_after_statement(); - } - p.print_block_end(self.body.span.end); - if MINIFY { - p.print_hard_space(); - } - p.print_soft_newline(); - p.needs_semicolon = false; - } -} - -impl<'a, const MINIFY: bool> Gen for TSInterfaceHeritage<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - self.expression.gen_expr(p, Precedence::Call, ctx); - if let Some(type_parameters) = &self.type_parameters { - type_parameters.gen(p, ctx); - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSEnumDeclaration<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_indent(); - if self.modifiers.contains(ModifierKind::Export) { - p.print_str(b"export "); - } - if self.modifiers.contains(ModifierKind::Declare) { - p.print_str(b"declare "); - } - if self.modifiers.contains(ModifierKind::Const) { - p.print_str(b"const "); - } - p.print_space_before_identifier(); - p.print_str(b"enum "); - self.id.gen(p, ctx); - p.print_space_before_identifier(); - p.print_block_start(self.span.start); - p.print_list(&self.members, ctx); - p.print_block_end(self.span.end); - p.print_hard_space(); - } -} - -impl<'a, const MINIFY: bool> Gen for TSEnumMember<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - match &self.id { - TSEnumMemberName::StaticIdentifier(decl) => decl.gen(p, ctx), - TSEnumMemberName::StaticStringLiteral(decl) => decl.gen(p, ctx), - TSEnumMemberName::StaticNumericLiteral(decl) => decl.gen(p, ctx), - decl @ match_expression!(TSEnumMemberName) => { - p.print_str(b"["); - decl.to_expression().gen_expr(p, Precedence::lowest(), ctx); - p.print_str(b"]"); - } - } - } -} - -impl<'a, const MINIFY: bool> Gen for TSConstructorType<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - if self.r#abstract { - p.print_str(b"abstract "); - } - p.print_str(b"new "); - if let Some(type_parameters) = &self.type_parameters { - type_parameters.gen(p, ctx); - } - p.print_str(b"("); - self.params.gen(p, ctx); - p.print_str(b")"); - p.print_soft_space(); - p.print_str(b"=>"); - p.print_soft_space(); - self.return_type.gen(p, ctx); - } -} - -impl<'a, const MINIFY: bool> Gen for TSImportEqualsDeclaration<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - p.print_str(b"import "); - self.id.gen(p, ctx); - p.print_str(b" = "); - self.module_reference.gen(p, ctx); - p.print_semicolon_after_statement(); - } -} -impl<'a, const MINIFY: bool> Gen for TSModuleReference<'a> { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { - match self { - Self::ExternalModuleReference(decl) => { - p.print_str(b"require("); - decl.expression.gen(p, ctx); - p.print_str(b")"); - } - match_ts_type_name!(Self) => self.to_ts_type_name().gen(p, ctx), - } - } -} - -impl<'a, const MINIFY: bool> GenExpr for TSTypeAssertion<'a> { - fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) { - p.print_str(b"<"); - self.type_annotation.gen(p, ctx); - p.print_str(b">"); - self.expression.gen_expr(p, precedence, ctx); - } -} - -impl Gen for TSAccessibility { - fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) { - match self { - Self::Public => p.print_str(b"public "), - Self::Private => p.print_str(b"private "), - Self::Protected => p.print_str(b"protected "), - } - } -} diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index 031735f3f54f2..bf756a954678a 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -11,7 +11,6 @@ mod annotation_comment; mod context; mod gen; -mod gen_ts; mod operator; mod sourcemap_builder;