Skip to content

Commit

Permalink
feat(transformer-dts): support for
Browse files Browse the repository at this point in the history
transform dts
  • Loading branch information
Dunqing committed Jun 14, 2024
1 parent cf71c23 commit 8781794
Show file tree
Hide file tree
Showing 21 changed files with 1,801 additions and 105 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2211,7 +2211,11 @@ impl<'a> BindingPatternKind<'a> {
}

pub fn is_destructuring_pattern(&self) -> bool {
matches!(self, Self::ObjectPattern(_) | Self::ArrayPattern(_))
match self {
Self::ObjectPattern(_) | Self::ArrayPattern(_) => true,
Self::AssignmentPattern(pattern) => pattern.left.kind.is_destructuring_pattern(),
Self::BindingIdentifier(_) => false,
}
}

pub fn is_binding_identifier(&self) -> bool {
Expand Down
31 changes: 28 additions & 3 deletions crates/oxc_ast/src/ast/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,33 @@ impl<'a> TSType<'a> {
pub fn is_maybe_undefined(&self) -> bool {
match self {
TSType::TSUndefinedKeyword(_) => true,
TSType::TSUnionType(un) => {
un.types.iter().any(|t| matches!(t, TSType::TSUndefinedKeyword(_)))
}
TSType::TSUnionType(un) => un.types.iter().any(Self::is_maybe_undefined),
_ => false,
}
}

pub fn is_keyword(&self) -> bool {
matches!(
self,
TSType::TSAnyKeyword(_)
| TSType::TSBigIntKeyword(_)
| TSType::TSBooleanKeyword(_)
| TSType::TSNeverKeyword(_)
| TSType::TSNullKeyword(_)
| TSType::TSNumberKeyword(_)
| TSType::TSObjectKeyword(_)
| TSType::TSStringKeyword(_)
| TSType::TSSymbolKeyword(_)
| TSType::TSThisType(_)
| TSType::TSUndefinedKeyword(_)
| TSType::TSUnknownKeyword(_)
| TSType::TSVoidKeyword(_)
)
}

pub fn is_keyword_or_literal(&self) -> bool {
self.is_keyword() || matches!(self, TSType::TSLiteralType(_))
}
}

/// `SomeType extends OtherType ? TrueType : FalseType;`
Expand Down Expand Up @@ -1305,6 +1326,10 @@ impl<'a> Modifiers<'a> {
self.contains(ModifierKind::Declare)
}

pub fn is_contains_abstract(&self) -> bool {
self.contains(ModifierKind::Abstract)
}

pub fn remove_type_modifiers(&mut self) {
if let Some(list) = &mut self.0 {
list.retain(|m| !m.kind.is_typescript_syntax());
Expand Down
55 changes: 48 additions & 7 deletions crates/oxc_ast/src/ast_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,13 @@ impl<'a> AstBuilder<'a> {
value: Option<Expression<'a>>,
computed: bool,
r#static: bool,
declare: bool,
r#override: bool,
optional: bool,
definite: bool,
readonly: bool,
type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
accessibility: Option<TSAccessibility>,
decorators: Vec<'a, Decorator<'a>>,
) -> ClassElement<'a> {
ClassElement::PropertyDefinition(self.alloc(PropertyDefinition {
Expand All @@ -1071,17 +1078,46 @@ impl<'a> AstBuilder<'a> {
value,
computed,
r#static,
declare: false,
r#override: false,
optional: false,
definite: false,
readonly: false,
type_annotation: None,
accessibility: None,
declare,
r#override,
optional,
definite,
readonly,
type_annotation,
accessibility,
decorators,
}))
}

pub fn class_method(
self,
r#type: MethodDefinitionType,
span: Span,
key: PropertyKey<'a>,
kind: MethodDefinitionKind,
value: Box<'a, Function<'a>>,
computed: bool,
r#static: bool,
r#override: bool,
optional: bool,
accessibility: Option<TSAccessibility>,
decorators: Vec<'a, Decorator<'a>>,
) -> ClassElement<'a> {
ClassElement::MethodDefinition(self.alloc(MethodDefinition {
r#type,
span,
decorators,
key,
value,
kind,
computed,
r#static,
r#override,
optional,
accessibility,
}))
}

#[inline]
pub fn class_constructor(self, span: Span, value: Box<'a, Function<'a>>) -> ClassElement<'a> {
ClassElement::MethodDefinition(self.alloc(MethodDefinition {
Expand Down Expand Up @@ -1248,6 +1284,11 @@ impl<'a> AstBuilder<'a> {
PropertyKey::StaticIdentifier(self.alloc(ident))
}

#[inline]
pub fn property_key_private_identifier(self, ident: PrivateIdentifier<'a>) -> PropertyKey<'a> {
PropertyKey::PrivateIdentifier(self.alloc(ident))
}

#[inline]
pub fn property_key_expression(self, expr: Expression<'a>) -> PropertyKey<'a> {
PropertyKey::from(expr)
Expand Down
18 changes: 14 additions & 4 deletions crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,13 @@ 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 && self.readonly {
p.print_str(b"readonly ");
if p.options.enable_typescript {
if self.readonly {
p.print_str(b"readonly ");
}
if let Some(accessibility) = self.accessibility {
accessibility.gen(p, ctx);
}
}
self.pattern.gen(p, ctx);
}
Expand Down Expand Up @@ -2080,8 +2085,13 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Class<'a> {
if !p.options.enable_typescript && self.is_declare() {
return;
}
if p.options.enable_typescript && self.is_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 ");
}
}
let n = p.code_len();
let wrap = self.is_expression() && (p.start_of_stmt == n || p.start_of_default_export == n);
Expand Down
29 changes: 29 additions & 0 deletions crates/oxc_codegen/src/gen_ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSSignature<'a> {
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")");
Expand Down Expand Up @@ -558,6 +561,22 @@ 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 {
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<MINIFY> for TSInterfaceDeclaration<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
if !p.options.enable_typescript {
Expand Down Expand Up @@ -698,3 +717,13 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSTypeAssertion<'a> {
self.expression.gen_expr(p, precedence, ctx);
}
}

impl<const MINIFY: bool> Gen<MINIFY> 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 "),
}
}
}
1 change: 1 addition & 0 deletions crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
}

fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, _ctx: &mut TraverseCtx<'a>) {
self.x0_typescript.transform_statements(stmts);
self.x3_es2015.enter_statements(stmts);
}

Expand Down
Loading

0 comments on commit 8781794

Please sign in to comment.