swc_estree_compat/babelify/
typescript.rs

1use copyless::BoxHelper;
2use serde::{Deserialize, Serialize};
3use swc_atoms::Atom;
4use swc_common::Spanned;
5use swc_ecma_ast::{
6    Accessibility, Expr, MemberProp, Pat, TruePlusMinus, TsArrayType, TsAsExpr,
7    TsCallSignatureDecl, TsConditionalType, TsConstAssertion, TsConstructSignatureDecl,
8    TsConstructorType, TsEntityName, TsEnumDecl, TsEnumMember, TsEnumMemberId, TsExportAssignment,
9    TsExprWithTypeArgs, TsExternalModuleRef, TsFnOrConstructorType, TsFnParam, TsFnType,
10    TsImportEqualsDecl, TsImportType, TsIndexSignature, TsIndexedAccessType, TsInferType,
11    TsInterfaceBody, TsInterfaceDecl, TsIntersectionType, TsKeywordType, TsKeywordTypeKind, TsLit,
12    TsLitType, TsMappedType, TsMethodSignature, TsModuleBlock, TsModuleDecl, TsModuleName,
13    TsModuleRef, TsNamespaceBody, TsNamespaceDecl, TsNamespaceExportDecl, TsNonNullExpr,
14    TsOptionalType, TsParamProp, TsParamPropParam, TsParenthesizedType, TsPropertySignature,
15    TsQualifiedName, TsRestType, TsThisType, TsThisTypeOrIdent, TsTplLitType, TsTupleElement,
16    TsTupleType, TsType, TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion, TsTypeElement, TsTypeLit,
17    TsTypeOperator, TsTypeOperatorOp, TsTypeParam, TsTypeParamDecl, TsTypeParamInstantiation,
18    TsTypePredicate, TsTypeQuery, TsTypeQueryExpr, TsTypeRef, TsUnionOrIntersectionType,
19    TsUnionType,
20};
21use swc_estree_ast::{
22    Access, ArrayPattern, IdOrRest, IdOrString, Identifier, ObjectPattern, RestElement,
23    TSAnyKeyword, TSArrayType, TSAsExpression, TSBigIntKeyword, TSBooleanKeyword,
24    TSCallSignatureDeclaration, TSConditionalType, TSConstructSignatureDeclaration,
25    TSConstructorType, TSEntityName, TSEnumDeclaration, TSEnumMember, TSExportAssignment,
26    TSExpressionWithTypeArguments, TSExternalModuleReference, TSFunctionType,
27    TSImportEqualsDeclModuleRef, TSImportEqualsDeclaration, TSImportType, TSIndexSignature,
28    TSIndexedAccessType, TSInferType, TSInterfaceBody, TSInterfaceDeclaration, TSIntersectionType,
29    TSIntrinsicKeyword, TSLiteralType, TSLiteralTypeLiteral, TSMappedType, TSMethodSignature,
30    TSModuleBlock, TSModuleDeclBody, TSModuleDeclaration, TSNamedTupleMember,
31    TSNamespaceExportDeclaration, TSNeverKeyword, TSNonNullExpression, TSNullKeyword,
32    TSNumberKeyword, TSObjectKeyword, TSOptionalType, TSParamPropParam, TSParameterProperty,
33    TSParenthesizedType, TSPropertySignature, TSQualifiedName, TSRestType, TSStringKeyword,
34    TSSymbolKeyword, TSThisType, TSTupleType, TSTupleTypeElType, TSType, TSTypeAliasDeclaration,
35    TSTypeAnnotation, TSTypeAssertion, TSTypeElement, TSTypeLiteral, TSTypeOperator,
36    TSTypeParameter, TSTypeParameterDeclaration, TSTypeParameterInstantiation, TSTypePredicate,
37    TSTypePredicateParamName, TSTypeQuery, TSTypeQueryExprName, TSTypeReference,
38    TSUndefinedKeyword, TSUnionType, TSUnknownKeyword, TSVoidKeyword,
39};
40
41use crate::babelify::{Babelify, Context};
42
43impl Babelify for TsTypeAnn {
44    type Output = TSTypeAnnotation;
45
46    fn babelify(self, ctx: &Context) -> Self::Output {
47        TSTypeAnnotation {
48            base: ctx.base(self.span),
49            type_annotation: self.type_ann.babelify(ctx),
50        }
51    }
52}
53
54impl Babelify for TsFnType {
55    type Output = TSFunctionType;
56
57    fn babelify(self, ctx: &Context) -> Self::Output {
58        TSFunctionType {
59            base: ctx.base(self.span),
60            parameters: self
61                .params
62                .into_iter()
63                .map(|p| p.babelify(ctx).into())
64                .collect(),
65            type_parameters: self.type_params.babelify(ctx),
66            type_annotation: Some(Box::alloc().init(self.type_ann.babelify(ctx))),
67        }
68    }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub enum TsFnParamOutput {
73    Id(Identifier),
74    Array(ArrayPattern),
75    Rest(RestElement),
76    Object(ObjectPattern),
77}
78
79impl Babelify for TsFnParam {
80    type Output = TsFnParamOutput;
81
82    fn babelify(self, ctx: &Context) -> Self::Output {
83        match self {
84            TsFnParam::Ident(i) => TsFnParamOutput::Id(i.babelify(ctx)),
85            TsFnParam::Array(a) => TsFnParamOutput::Array(a.babelify(ctx)),
86            TsFnParam::Rest(r) => TsFnParamOutput::Rest(r.babelify(ctx)),
87            TsFnParam::Object(o) => TsFnParamOutput::Object(o.babelify(ctx)),
88            #[cfg(swc_ast_unknown)]
89            _ => panic!("unable to access unknown nodes"),
90        }
91    }
92}
93
94impl From<TsFnParamOutput> for IdOrRest {
95    fn from(o: TsFnParamOutput) -> Self {
96        match o {
97            TsFnParamOutput::Id(i) => IdOrRest::Id(i),
98            TsFnParamOutput::Rest(r) => IdOrRest::Rest(r),
99            _ => panic!("illegal conversion: Cannot convert {:?} to IdOrRest", &o),
100        }
101    }
102}
103
104impl From<TsFnParamOutput> for Identifier {
105    fn from(o: TsFnParamOutput) -> Self {
106        match o {
107            TsFnParamOutput::Id(i) => i,
108            _ => panic!("illegal conversion: Cannot convert {:?} to Identifier", &o),
109        }
110    }
111}
112
113impl Babelify for TsTypeParamDecl {
114    type Output = TSTypeParameterDeclaration;
115
116    fn babelify(self, ctx: &Context) -> Self::Output {
117        TSTypeParameterDeclaration {
118            base: ctx.base(self.span),
119            params: self.params.babelify(ctx),
120        }
121    }
122}
123
124impl Babelify for TsTypeParam {
125    type Output = TSTypeParameter;
126
127    fn babelify(self, ctx: &Context) -> Self::Output {
128        TSTypeParameter {
129            base: ctx.base(self.span),
130            name: self.name.sym,
131            is_in: self.is_in,
132            is_out: self.is_out,
133            is_const: self.is_const,
134            constraint: self.constraint.map(|c| Box::alloc().init(c.babelify(ctx))),
135            default: self.default.map(|d| Box::alloc().init(d.babelify(ctx))),
136        }
137    }
138}
139
140impl Babelify for TsTypeParamInstantiation {
141    type Output = TSTypeParameterInstantiation;
142
143    fn babelify(self, ctx: &Context) -> Self::Output {
144        TSTypeParameterInstantiation {
145            base: ctx.base(self.span),
146            params: self.params.into_iter().map(|v| v.babelify(ctx)).collect(),
147        }
148    }
149}
150
151impl Babelify for TsParamProp {
152    type Output = TSParameterProperty;
153
154    fn babelify(self, ctx: &Context) -> Self::Output {
155        TSParameterProperty {
156            base: ctx.base(self.span),
157            parameter: self.param.babelify(ctx),
158            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
159            readonly: Some(self.readonly),
160        }
161    }
162}
163
164impl Babelify for TsParamPropParam {
165    type Output = TSParamPropParam;
166
167    fn babelify(self, ctx: &Context) -> Self::Output {
168        match self {
169            TsParamPropParam::Ident(i) => TSParamPropParam::Id(i.babelify(ctx)),
170            TsParamPropParam::Assign(a) => TSParamPropParam::Assignment(a.babelify(ctx)),
171            #[cfg(swc_ast_unknown)]
172            _ => panic!("unable to access unknown nodes"),
173        }
174    }
175}
176
177impl Babelify for TsQualifiedName {
178    type Output = TSQualifiedName;
179
180    fn babelify(self, ctx: &Context) -> Self::Output {
181        TSQualifiedName {
182            base: ctx.base(self.span()),
183            left: Box::alloc().init(self.left.babelify(ctx)),
184            right: self.right.babelify(ctx),
185        }
186    }
187}
188
189impl Babelify for TsEntityName {
190    type Output = TSEntityName;
191
192    fn babelify(self, ctx: &Context) -> Self::Output {
193        match self {
194            TsEntityName::TsQualifiedName(n) => TSEntityName::Qualified(n.babelify(ctx)),
195            TsEntityName::Ident(i) => TSEntityName::Id(i.babelify(ctx)),
196            #[cfg(swc_ast_unknown)]
197            _ => panic!("unable to access unknown nodes"),
198        }
199    }
200}
201
202impl Babelify for TsTypeElement {
203    type Output = TSTypeElement;
204
205    fn babelify(self, ctx: &Context) -> Self::Output {
206        match self {
207            TsTypeElement::TsCallSignatureDecl(t) => {
208                TSTypeElement::CallSignatureDecl(t.babelify(ctx))
209            }
210            TsTypeElement::TsConstructSignatureDecl(t) => {
211                TSTypeElement::ConstructSignatureDecl(t.babelify(ctx))
212            }
213            TsTypeElement::TsPropertySignature(t) => TSTypeElement::PropSignature(t.babelify(ctx)),
214            TsTypeElement::TsMethodSignature(t) => TSTypeElement::MethodSignature(t.babelify(ctx)),
215            TsTypeElement::TsIndexSignature(t) => TSTypeElement::IndexSignature(t.babelify(ctx)),
216            TsTypeElement::TsGetterSignature(_) => panic!("unimplemented"),
217            TsTypeElement::TsSetterSignature(_) => panic!("unimplemented"),
218            #[cfg(swc_ast_unknown)]
219            _ => panic!("unable to access unknown nodes"),
220        }
221    }
222}
223
224impl Babelify for TsCallSignatureDecl {
225    type Output = TSCallSignatureDeclaration;
226
227    fn babelify(self, ctx: &Context) -> Self::Output {
228        TSCallSignatureDeclaration {
229            base: ctx.base(self.span),
230            type_parameters: self.type_params.map(|t| t.babelify(ctx)),
231            parameters: self
232                .params
233                .into_iter()
234                .map(|param| param.babelify(ctx).into())
235                .collect(),
236            type_annotation: self
237                .type_ann
238                .map(|ann| Box::alloc().init(ann.babelify(ctx))),
239        }
240    }
241}
242
243impl Babelify for TsConstructSignatureDecl {
244    type Output = TSConstructSignatureDeclaration;
245
246    fn babelify(self, ctx: &Context) -> Self::Output {
247        TSConstructSignatureDeclaration {
248            base: ctx.base(self.span),
249            type_parameters: self.type_params.map(|t| t.babelify(ctx)),
250            parameters: self
251                .params
252                .into_iter()
253                .map(|param| param.babelify(ctx).into())
254                .collect(),
255            type_annotation: self
256                .type_ann
257                .map(|ann| Box::alloc().init(ann.babelify(ctx))),
258        }
259    }
260}
261
262impl Babelify for TsPropertySignature {
263    type Output = TSPropertySignature;
264
265    fn babelify(self, ctx: &Context) -> Self::Output {
266        TSPropertySignature {
267            base: ctx.base(self.span),
268            key: Box::alloc().init(self.key.babelify(ctx).into()),
269            type_annotation: self
270                .type_ann
271                .map(|ann| Box::alloc().init(ann.babelify(ctx))),
272            computed: Some(self.computed),
273            optional: Some(self.optional),
274            readonly: Some(self.readonly),
275        }
276    }
277}
278
279impl Babelify for TsMethodSignature {
280    type Output = TSMethodSignature;
281
282    fn babelify(self, ctx: &Context) -> Self::Output {
283        TSMethodSignature {
284            base: ctx.base(self.span),
285            key: Box::alloc().init(self.key.babelify(ctx).into()),
286            type_parameters: self.type_params.map(|t| t.babelify(ctx)),
287            parameters: self
288                .params
289                .into_iter()
290                .map(|param| param.babelify(ctx).into())
291                .collect(),
292            type_annotation: self
293                .type_ann
294                .map(|ann| Box::alloc().init(ann.babelify(ctx))),
295            computed: Some(self.computed),
296            optional: Some(self.optional),
297        }
298    }
299}
300
301impl Babelify for TsIndexSignature {
302    type Output = TSIndexSignature;
303
304    fn babelify(self, ctx: &Context) -> Self::Output {
305        TSIndexSignature {
306            base: ctx.base(self.span),
307            parameters: self
308                .params
309                .into_iter()
310                .map(|param| param.babelify(ctx).into())
311                .collect(),
312            type_annotation: self
313                .type_ann
314                .map(|ann| Box::alloc().init(ann.babelify(ctx))),
315            readonly: Some(self.readonly),
316        }
317    }
318}
319
320impl Babelify for TsType {
321    type Output = TSType;
322
323    fn babelify(self, ctx: &Context) -> Self::Output {
324        match self {
325            TsType::TsKeywordType(t) => match t.babelify(ctx) {
326                TsKeywordTypeOutput::Any(a) => TSType::AnyKeyword(a),
327                TsKeywordTypeOutput::Unknown(u) => TSType::UnknownKeyword(u),
328                TsKeywordTypeOutput::Number(n) => TSType::NumberKeyword(n),
329                TsKeywordTypeOutput::Object(o) => TSType::ObjectKeyword(o),
330                TsKeywordTypeOutput::Boolean(b) => TSType::BooleanKeyword(b),
331                TsKeywordTypeOutput::BigInt(i) => TSType::BigIntKeyword(i),
332                TsKeywordTypeOutput::String(s) => TSType::StringKeyword(s),
333                TsKeywordTypeOutput::Symbol(s) => TSType::SymbolKeyword(s),
334                TsKeywordTypeOutput::Void(v) => TSType::VoidKeyword(v),
335                TsKeywordTypeOutput::Undefined(u) => TSType::UndefinedKeyword(u),
336                TsKeywordTypeOutput::Null(n) => TSType::NullKeyword(n),
337                TsKeywordTypeOutput::Never(n) => TSType::NeverKeyword(n),
338                TsKeywordTypeOutput::Intrinsic(i) => TSType::IntrinsicKeyword(i),
339            },
340            TsType::TsThisType(t) => TSType::This(t.babelify(ctx)),
341            TsType::TsFnOrConstructorType(t) => match t.babelify(ctx) {
342                TsFnOrConstructorTypeOutput::Func(f) => TSType::Function(f),
343                TsFnOrConstructorTypeOutput::Constructor(c) => TSType::Constructor(c),
344            },
345            TsType::TsTypeRef(r) => TSType::TypeRef(r.babelify(ctx)),
346            TsType::TsTypeQuery(q) => TSType::TypeQuery(q.babelify(ctx)),
347            TsType::TsTypeLit(l) => TSType::TypeLiteral(l.babelify(ctx)),
348            TsType::TsArrayType(a) => TSType::Array(a.babelify(ctx)),
349            TsType::TsTupleType(t) => TSType::Tuple(t.babelify(ctx)),
350            TsType::TsOptionalType(o) => TSType::Optional(o.babelify(ctx)),
351            TsType::TsRestType(r) => TSType::Rest(r.babelify(ctx)),
352            TsType::TsUnionOrIntersectionType(t) => match t.babelify(ctx) {
353                TsUnionOrIntersectionTypeOutput::Union(u) => TSType::Union(u),
354                TsUnionOrIntersectionTypeOutput::Intersection(i) => TSType::Intersection(i),
355            },
356            TsType::TsConditionalType(c) => TSType::Conditional(c.babelify(ctx)),
357            TsType::TsInferType(i) => TSType::Infer(i.babelify(ctx)),
358            TsType::TsParenthesizedType(p) => TSType::Parenthesized(p.babelify(ctx)),
359            TsType::TsTypeOperator(o) => TSType::TypeOp(o.babelify(ctx)),
360            TsType::TsIndexedAccessType(a) => TSType::IndexedAccess(a.babelify(ctx)),
361            TsType::TsMappedType(m) => TSType::Mapped(m.babelify(ctx)),
362            TsType::TsLitType(l) => TSType::Literal(l.babelify(ctx)),
363            TsType::TsTypePredicate(p) => TSType::TypePredicate(p.babelify(ctx)),
364            TsType::TsImportType(i) => TSType::Import(i.babelify(ctx)),
365            #[cfg(swc_ast_unknown)]
366            _ => panic!("unable to access unknown nodes"),
367        }
368    }
369}
370
371#[derive(Debug, Clone, Serialize, Deserialize)]
372pub enum TsFnOrConstructorTypeOutput {
373    Func(TSFunctionType),
374    Constructor(TSConstructorType),
375}
376
377impl Babelify for TsFnOrConstructorType {
378    type Output = TsFnOrConstructorTypeOutput;
379
380    fn babelify(self, ctx: &Context) -> Self::Output {
381        match self {
382            TsFnOrConstructorType::TsFnType(t) => {
383                TsFnOrConstructorTypeOutput::Func(t.babelify(ctx))
384            }
385            TsFnOrConstructorType::TsConstructorType(t) => {
386                TsFnOrConstructorTypeOutput::Constructor(t.babelify(ctx))
387            }
388            #[cfg(swc_ast_unknown)]
389            _ => panic!("unable to access unknown nodes"),
390        }
391    }
392}
393
394#[derive(Debug, Clone, Serialize, Deserialize)]
395pub enum TsKeywordTypeOutput {
396    Any(TSAnyKeyword),
397    Unknown(TSUnknownKeyword),
398    Number(TSNumberKeyword),
399    Object(TSObjectKeyword),
400    Boolean(TSBooleanKeyword),
401    BigInt(TSBigIntKeyword),
402    String(TSStringKeyword),
403    Symbol(TSSymbolKeyword),
404    Void(TSVoidKeyword),
405    Undefined(TSUndefinedKeyword),
406    Null(TSNullKeyword),
407    Never(TSNeverKeyword),
408    Intrinsic(TSIntrinsicKeyword),
409}
410
411impl Babelify for TsKeywordType {
412    type Output = TsKeywordTypeOutput;
413
414    fn babelify(self, ctx: &Context) -> Self::Output {
415        match self.kind {
416            TsKeywordTypeKind::TsAnyKeyword => TsKeywordTypeOutput::Any(TSAnyKeyword {
417                base: ctx.base(self.span),
418            }),
419            TsKeywordTypeKind::TsUnknownKeyword => TsKeywordTypeOutput::Unknown(TSUnknownKeyword {
420                base: ctx.base(self.span),
421            }),
422            TsKeywordTypeKind::TsNumberKeyword => TsKeywordTypeOutput::Number(TSNumberKeyword {
423                base: ctx.base(self.span),
424            }),
425            TsKeywordTypeKind::TsObjectKeyword => TsKeywordTypeOutput::Object(TSObjectKeyword {
426                base: ctx.base(self.span),
427            }),
428            TsKeywordTypeKind::TsBooleanKeyword => TsKeywordTypeOutput::Boolean(TSBooleanKeyword {
429                base: ctx.base(self.span),
430            }),
431            TsKeywordTypeKind::TsBigIntKeyword => TsKeywordTypeOutput::BigInt(TSBigIntKeyword {
432                base: ctx.base(self.span),
433            }),
434            TsKeywordTypeKind::TsStringKeyword => TsKeywordTypeOutput::String(TSStringKeyword {
435                base: ctx.base(self.span),
436            }),
437            TsKeywordTypeKind::TsSymbolKeyword => TsKeywordTypeOutput::Symbol(TSSymbolKeyword {
438                base: ctx.base(self.span),
439            }),
440            TsKeywordTypeKind::TsVoidKeyword => TsKeywordTypeOutput::Void(TSVoidKeyword {
441                base: ctx.base(self.span),
442            }),
443            TsKeywordTypeKind::TsUndefinedKeyword => {
444                TsKeywordTypeOutput::Undefined(TSUndefinedKeyword {
445                    base: ctx.base(self.span),
446                })
447            }
448            TsKeywordTypeKind::TsNullKeyword => TsKeywordTypeOutput::Null(TSNullKeyword {
449                base: ctx.base(self.span),
450            }),
451            TsKeywordTypeKind::TsNeverKeyword => TsKeywordTypeOutput::Never(TSNeverKeyword {
452                base: ctx.base(self.span),
453            }),
454            TsKeywordTypeKind::TsIntrinsicKeyword => {
455                TsKeywordTypeOutput::Intrinsic(TSIntrinsicKeyword {
456                    base: ctx.base(self.span),
457                })
458            }
459            #[cfg(swc_ast_unknown)]
460            _ => panic!("unable to access unknown nodes"),
461        }
462    }
463}
464
465impl Babelify for TsThisType {
466    type Output = TSThisType;
467
468    fn babelify(self, ctx: &Context) -> Self::Output {
469        TSThisType {
470            base: ctx.base(self.span),
471        }
472    }
473}
474
475impl Babelify for TsConstructorType {
476    type Output = TSConstructorType;
477
478    fn babelify(self, ctx: &Context) -> Self::Output {
479        TSConstructorType {
480            base: ctx.base(self.span),
481            parameters: self
482                .params
483                .into_iter()
484                .map(|param| param.babelify(ctx).into())
485                .collect(),
486            type_parameters: self.type_params.map(|decl| decl.babelify(ctx)),
487            type_annotation: Some(Box::alloc().init(self.type_ann.babelify(ctx))),
488            is_abstract: Some(self.is_abstract),
489        }
490    }
491}
492
493impl Babelify for TsTypeRef {
494    type Output = TSTypeReference;
495
496    fn babelify(self, ctx: &Context) -> Self::Output {
497        TSTypeReference {
498            base: ctx.base(self.span),
499            type_name: self.type_name.babelify(ctx),
500            type_parameters: self.type_params.map(|t| t.babelify(ctx)),
501        }
502    }
503}
504
505impl Babelify for TsTypePredicate {
506    type Output = TSTypePredicate;
507
508    fn babelify(self, ctx: &Context) -> Self::Output {
509        TSTypePredicate {
510            base: ctx.base(self.span),
511            parameter_name: self.param_name.babelify(ctx),
512            type_annotation: self
513                .type_ann
514                .map(|ann| Box::alloc().init(ann.babelify(ctx))),
515            asserts: Some(self.asserts),
516        }
517    }
518}
519
520impl Babelify for TsThisTypeOrIdent {
521    type Output = TSTypePredicateParamName;
522
523    fn babelify(self, ctx: &Context) -> Self::Output {
524        match self {
525            TsThisTypeOrIdent::Ident(i) => TSTypePredicateParamName::Id(i.babelify(ctx)),
526            TsThisTypeOrIdent::TsThisType(t) => TSTypePredicateParamName::This(t.babelify(ctx)),
527            #[cfg(swc_ast_unknown)]
528            _ => panic!("unable to access unknown nodes"),
529        }
530    }
531}
532
533impl Babelify for TsTypeQuery {
534    type Output = TSTypeQuery;
535
536    fn babelify(self, ctx: &Context) -> Self::Output {
537        TSTypeQuery {
538            base: ctx.base(self.span),
539            expr_name: self.expr_name.babelify(ctx),
540        }
541    }
542}
543
544impl Babelify for TsTypeQueryExpr {
545    type Output = TSTypeQueryExprName;
546
547    fn babelify(self, ctx: &Context) -> Self::Output {
548        match self {
549            TsTypeQueryExpr::TsEntityName(n) => TSTypeQueryExprName::EntityName(n.babelify(ctx)),
550            TsTypeQueryExpr::Import(i) => TSTypeQueryExprName::ImportType(i.babelify(ctx)),
551            #[cfg(swc_ast_unknown)]
552            _ => panic!("unable to access unknown nodes"),
553        }
554    }
555}
556
557impl Babelify for TsImportType {
558    type Output = TSImportType;
559
560    fn babelify(self, ctx: &Context) -> Self::Output {
561        TSImportType {
562            base: ctx.base(self.span),
563            argument: self.arg.babelify(ctx),
564            qualifier: self.qualifier.map(|qual| qual.babelify(ctx)),
565            type_parameters: self.type_args.map(|param| param.babelify(ctx)),
566        }
567    }
568}
569
570impl Babelify for TsTypeLit {
571    type Output = TSTypeLiteral;
572
573    fn babelify(self, ctx: &Context) -> Self::Output {
574        TSTypeLiteral {
575            base: ctx.base(self.span),
576            members: self.members.babelify(ctx),
577        }
578    }
579}
580
581impl Babelify for TsArrayType {
582    type Output = TSArrayType;
583
584    fn babelify(self, ctx: &Context) -> Self::Output {
585        TSArrayType {
586            base: ctx.base(self.span),
587            element_type: Box::alloc().init(self.elem_type.babelify(ctx)),
588        }
589    }
590}
591
592impl Babelify for TsTupleType {
593    type Output = TSTupleType;
594
595    fn babelify(self, ctx: &Context) -> Self::Output {
596        TSTupleType {
597            base: ctx.base(self.span),
598            element_types: self.elem_types.babelify(ctx),
599        }
600    }
601}
602
603impl Babelify for TsTupleElement {
604    type Output = TSTupleTypeElType;
605
606    fn babelify(self, ctx: &Context) -> Self::Output {
607        match self.label {
608            None => TSTupleTypeElType::TSType(self.ty.babelify(ctx)),
609            Some(pat) => TSTupleTypeElType::Member(TSNamedTupleMember {
610                base: ctx.base(self.span),
611                label: match pat {
612                    Pat::Ident(id) => id.babelify(ctx),
613                    Pat::Rest(rest) => match *rest.arg {
614                        Pat::Ident(id) => id.babelify(ctx),
615                        _ => panic!(
616                            "illegal conversion: Cannot convert {:?} to Identifier",
617                            &rest.arg
618                        ),
619                    },
620                    _ => panic!(
621                        "illegal conversion: Cannot convert {:?} to Identifier",
622                        &pat
623                    ),
624                },
625                element_type: self.ty.babelify(ctx),
626                optional: Default::default(),
627            }),
628        }
629    }
630}
631
632impl Babelify for TsOptionalType {
633    type Output = TSOptionalType;
634
635    fn babelify(self, ctx: &Context) -> Self::Output {
636        TSOptionalType {
637            base: ctx.base(self.span),
638            type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)),
639        }
640    }
641}
642
643impl Babelify for TsRestType {
644    type Output = TSRestType;
645
646    fn babelify(self, ctx: &Context) -> Self::Output {
647        TSRestType {
648            base: ctx.base(self.span),
649            type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)),
650        }
651    }
652}
653
654#[derive(Debug, Clone, Serialize, Deserialize)]
655pub enum TsUnionOrIntersectionTypeOutput {
656    Union(TSUnionType),
657    Intersection(TSIntersectionType),
658}
659
660impl Babelify for TsUnionOrIntersectionType {
661    type Output = TsUnionOrIntersectionTypeOutput;
662
663    fn babelify(self, ctx: &Context) -> Self::Output {
664        match self {
665            TsUnionOrIntersectionType::TsUnionType(u) => {
666                TsUnionOrIntersectionTypeOutput::Union(u.babelify(ctx))
667            }
668            TsUnionOrIntersectionType::TsIntersectionType(i) => {
669                TsUnionOrIntersectionTypeOutput::Intersection(i.babelify(ctx))
670            }
671            #[cfg(swc_ast_unknown)]
672            _ => panic!("unable to access unknown nodes"),
673        }
674    }
675}
676
677impl Babelify for TsUnionType {
678    type Output = TSUnionType;
679
680    fn babelify(self, ctx: &Context) -> Self::Output {
681        TSUnionType {
682            base: ctx.base(self.span),
683            types: self.types.into_iter().map(|t| t.babelify(ctx)).collect(),
684        }
685    }
686}
687
688impl Babelify for TsIntersectionType {
689    type Output = TSIntersectionType;
690
691    fn babelify(self, ctx: &Context) -> Self::Output {
692        TSIntersectionType {
693            base: ctx.base(self.span),
694            types: self.types.into_iter().map(|t| t.babelify(ctx)).collect(),
695        }
696    }
697}
698
699impl Babelify for TsConditionalType {
700    type Output = TSConditionalType;
701
702    fn babelify(self, ctx: &Context) -> Self::Output {
703        TSConditionalType {
704            base: ctx.base(self.span),
705            check_type: Box::alloc().init(self.check_type.babelify(ctx)),
706            extends_type: Box::alloc().init(self.extends_type.babelify(ctx)),
707            true_type: Box::alloc().init(self.true_type.babelify(ctx)),
708            false_type: Box::alloc().init(self.false_type.babelify(ctx)),
709        }
710    }
711}
712
713impl Babelify for TsInferType {
714    type Output = TSInferType;
715
716    fn babelify(self, ctx: &Context) -> Self::Output {
717        TSInferType {
718            base: ctx.base(self.span),
719            type_parameter: Box::alloc().init(self.type_param.babelify(ctx)),
720        }
721    }
722}
723
724impl Babelify for TsParenthesizedType {
725    type Output = TSParenthesizedType;
726
727    fn babelify(self, ctx: &Context) -> Self::Output {
728        TSParenthesizedType {
729            base: ctx.base(self.span),
730            type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)),
731        }
732    }
733}
734
735impl Babelify for TsTypeOperator {
736    type Output = TSTypeOperator;
737
738    fn babelify(self, ctx: &Context) -> Self::Output {
739        TSTypeOperator {
740            base: ctx.base(self.span),
741            type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)),
742            operator: self.op.babelify(ctx),
743        }
744    }
745}
746
747impl Babelify for TsTypeOperatorOp {
748    type Output = Atom;
749
750    fn babelify(self, _ctx: &Context) -> Self::Output {
751        match self {
752            TsTypeOperatorOp::KeyOf => "keyof".into(),
753            TsTypeOperatorOp::Unique => "unique".into(),
754            TsTypeOperatorOp::ReadOnly => "readonly".into(),
755            #[cfg(swc_ast_unknown)]
756            _ => panic!("unable to access unknown nodes"),
757        }
758    }
759}
760
761impl Babelify for TsIndexedAccessType {
762    type Output = TSIndexedAccessType;
763
764    fn babelify(self, ctx: &Context) -> Self::Output {
765        TSIndexedAccessType {
766            base: ctx.base(self.span),
767            object_type: Box::alloc().init(self.obj_type.babelify(ctx)),
768            index_type: Box::alloc().init(self.index_type.babelify(ctx)),
769        }
770    }
771}
772
773// TODO(dwoznicki): I don't understand how Babel handles the +/- symbol, so this
774// conversion will not work properly yet.
775impl Babelify for TsMappedType {
776    type Output = TSMappedType;
777
778    fn babelify(self, ctx: &Context) -> Self::Output {
779        TSMappedType {
780            base: ctx.base(self.span),
781            type_parameter: Box::alloc().init(self.type_param.babelify(ctx)),
782            type_annotation: self
783                .type_ann
784                .map(|ann| Box::alloc().init(ann.babelify(ctx))),
785            name_type: self.name_type.map(|t| Box::alloc().init(t.babelify(ctx))),
786            optional: self.optional.map(|val| val == TruePlusMinus::True),
787            readonly: self.readonly.map(|val| val == TruePlusMinus::True),
788        }
789    }
790}
791
792impl Babelify for TsLitType {
793    type Output = TSLiteralType;
794
795    fn babelify(self, ctx: &Context) -> Self::Output {
796        TSLiteralType {
797            base: ctx.base(self.span),
798            literal: self.lit.babelify(ctx),
799        }
800    }
801}
802
803impl Babelify for TsLit {
804    type Output = TSLiteralTypeLiteral;
805
806    fn babelify(self, ctx: &Context) -> Self::Output {
807        match self {
808            TsLit::Number(n) => TSLiteralTypeLiteral::Numeric(n.babelify(ctx)),
809            TsLit::Str(s) => TSLiteralTypeLiteral::String(s.babelify(ctx)),
810            TsLit::Bool(b) => TSLiteralTypeLiteral::Boolean(b.babelify(ctx)),
811            TsLit::BigInt(i) => TSLiteralTypeLiteral::BigInt(i.babelify(ctx)),
812            _ => panic!(
813                "illegal conversion: Cannot convert {:?} to TSLiteralTypeLiteral",
814                &self
815            ),
816        }
817    }
818}
819
820// TODO(dwoznicki): Babel does not appear to have a corresponding template
821// literal TS node.
822impl Babelify for TsTplLitType {
823    type Output = String;
824
825    fn babelify(self, _ctx: &Context) -> Self::Output {
826        panic!("unimplemented");
827    }
828}
829
830impl Babelify for TsInterfaceDecl {
831    type Output = TSInterfaceDeclaration;
832
833    fn babelify(self, ctx: &Context) -> Self::Output {
834        TSInterfaceDeclaration {
835            base: ctx.base(self.span),
836            id: self.id.babelify(ctx),
837            type_parameters: self.type_params.map(|t| t.babelify(ctx)),
838            extends: self.extends.into_iter().next().babelify(ctx),
839            body: self.body.babelify(ctx),
840            declare: Some(self.declare),
841        }
842    }
843}
844
845impl Babelify for TsInterfaceBody {
846    type Output = TSInterfaceBody;
847
848    fn babelify(self, ctx: &Context) -> Self::Output {
849        TSInterfaceBody {
850            base: ctx.base(self.span),
851            body: self.body.babelify(ctx),
852        }
853    }
854}
855
856impl Babelify for TsExprWithTypeArgs {
857    type Output = TSExpressionWithTypeArguments;
858
859    fn babelify(self, ctx: &Context) -> Self::Output {
860        fn babelify_expr(expr: Expr, ctx: &Context) -> TSEntityName {
861            match expr {
862                Expr::Ident(id) => TSEntityName::Id(id.babelify(ctx)),
863                Expr::Member(e) => TSEntityName::Qualified(TSQualifiedName {
864                    base: ctx.base(e.span),
865                    left: Box::new(babelify_expr(*e.obj, ctx)),
866                    right: match e.prop {
867                        MemberProp::Ident(id) => id.babelify(ctx),
868                        _ => unreachable!(),
869                    },
870                }),
871                _ => unreachable!(),
872            }
873        }
874        TSExpressionWithTypeArguments {
875            base: ctx.base(self.span),
876            expression: babelify_expr(*self.expr, ctx),
877            type_parameters: self.type_args.map(|arg| arg.babelify(ctx)),
878        }
879    }
880}
881
882impl Babelify for TsTypeAliasDecl {
883    type Output = TSTypeAliasDeclaration;
884
885    fn babelify(self, ctx: &Context) -> Self::Output {
886        TSTypeAliasDeclaration {
887            base: ctx.base(self.span),
888            id: self.id.babelify(ctx),
889            type_parameters: self.type_params.map(|t| t.babelify(ctx)),
890            type_annotation: self.type_ann.babelify(ctx),
891            declare: Some(self.declare),
892        }
893    }
894}
895
896impl Babelify for TsEnumDecl {
897    type Output = TSEnumDeclaration;
898
899    fn babelify(self, ctx: &Context) -> Self::Output {
900        TSEnumDeclaration {
901            base: ctx.base(self.span),
902            id: self.id.babelify(ctx),
903            members: self.members.babelify(ctx),
904            is_const: Some(self.is_const),
905            declare: Some(self.declare),
906            initializer: Default::default(),
907        }
908    }
909}
910
911impl Babelify for TsEnumMember {
912    type Output = TSEnumMember;
913
914    fn babelify(self, ctx: &Context) -> Self::Output {
915        TSEnumMember {
916            base: ctx.base(self.span),
917            id: self.id.babelify(ctx),
918            initializer: self.init.map(|i| Box::alloc().init(i.babelify(ctx).into())),
919        }
920    }
921}
922
923impl Babelify for TsEnumMemberId {
924    type Output = IdOrString;
925
926    fn babelify(self, ctx: &Context) -> Self::Output {
927        match self {
928            TsEnumMemberId::Ident(i) => IdOrString::Id(i.babelify(ctx)),
929            TsEnumMemberId::Str(s) => IdOrString::String(s.babelify(ctx)),
930            #[cfg(swc_ast_unknown)]
931            _ => panic!("unable to access unknown nodes"),
932        }
933    }
934}
935
936impl Babelify for TsModuleDecl {
937    type Output = TSModuleDeclaration;
938
939    fn babelify(self, ctx: &Context) -> Self::Output {
940        TSModuleDeclaration {
941            base: ctx.base(self.span),
942            id: self.id.babelify(ctx),
943            body: Box::alloc().init(self.body.unwrap().babelify(ctx)),
944            declare: Some(self.declare),
945            global: Some(self.global),
946        }
947    }
948}
949
950impl Babelify for TsNamespaceBody {
951    type Output = TSModuleDeclBody;
952
953    fn babelify(self, ctx: &Context) -> Self::Output {
954        match self {
955            TsNamespaceBody::TsModuleBlock(b) => TSModuleDeclBody::Block(b.babelify(ctx)),
956            TsNamespaceBody::TsNamespaceDecl(d) => TSModuleDeclBody::Decl(d.babelify(ctx)),
957            #[cfg(swc_ast_unknown)]
958            _ => panic!("unable to access unknown nodes"),
959        }
960    }
961}
962
963impl Babelify for TsModuleBlock {
964    type Output = TSModuleBlock;
965
966    fn babelify(self, ctx: &Context) -> Self::Output {
967        TSModuleBlock {
968            base: ctx.base(self.span),
969            body: self
970                .body
971                .into_iter()
972                .map(|m| m.babelify(ctx).into())
973                .collect(),
974        }
975    }
976}
977
978impl Babelify for TsNamespaceDecl {
979    type Output = TSModuleDeclaration;
980
981    fn babelify(self, ctx: &Context) -> Self::Output {
982        TSModuleDeclaration {
983            base: ctx.base(self.span),
984            id: IdOrString::Id(self.id.babelify(ctx)),
985            body: Box::alloc().init(self.body.babelify(ctx)),
986            declare: Some(self.declare),
987            global: Some(self.global),
988        }
989    }
990}
991
992impl Babelify for TsModuleName {
993    type Output = IdOrString;
994
995    fn babelify(self, ctx: &Context) -> Self::Output {
996        match self {
997            TsModuleName::Ident(i) => IdOrString::Id(i.babelify(ctx)),
998            TsModuleName::Str(s) => IdOrString::String(s.babelify(ctx)),
999            #[cfg(swc_ast_unknown)]
1000            _ => panic!("unable to access unknown nodes"),
1001        }
1002    }
1003}
1004
1005impl Babelify for TsImportEqualsDecl {
1006    type Output = TSImportEqualsDeclaration;
1007
1008    fn babelify(self, ctx: &Context) -> Self::Output {
1009        TSImportEqualsDeclaration {
1010            base: ctx.base(self.span),
1011            id: self.id.babelify(ctx),
1012            module_reference: self.module_ref.babelify(ctx),
1013            is_export: self.is_export,
1014        }
1015    }
1016}
1017
1018impl Babelify for TsModuleRef {
1019    type Output = TSImportEqualsDeclModuleRef;
1020
1021    fn babelify(self, ctx: &Context) -> Self::Output {
1022        match self {
1023            TsModuleRef::TsEntityName(n) => TSImportEqualsDeclModuleRef::Name(n.babelify(ctx)),
1024            TsModuleRef::TsExternalModuleRef(e) => {
1025                TSImportEqualsDeclModuleRef::External(e.babelify(ctx))
1026            }
1027            #[cfg(swc_ast_unknown)]
1028            _ => panic!("unable to access unknown nodes"),
1029        }
1030    }
1031}
1032
1033impl Babelify for TsExternalModuleRef {
1034    type Output = TSExternalModuleReference;
1035
1036    fn babelify(self, ctx: &Context) -> Self::Output {
1037        TSExternalModuleReference {
1038            base: ctx.base(self.span),
1039            expression: self.expr.babelify(ctx),
1040        }
1041    }
1042}
1043
1044impl Babelify for TsExportAssignment {
1045    type Output = TSExportAssignment;
1046
1047    fn babelify(self, ctx: &Context) -> Self::Output {
1048        TSExportAssignment {
1049            base: ctx.base(self.span),
1050            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
1051        }
1052    }
1053}
1054
1055impl Babelify for TsNamespaceExportDecl {
1056    type Output = TSNamespaceExportDeclaration;
1057
1058    fn babelify(self, ctx: &Context) -> Self::Output {
1059        TSNamespaceExportDeclaration {
1060            base: ctx.base(self.span),
1061            id: self.id.babelify(ctx),
1062        }
1063    }
1064}
1065
1066impl Babelify for TsAsExpr {
1067    type Output = TSAsExpression;
1068
1069    fn babelify(self, ctx: &Context) -> Self::Output {
1070        TSAsExpression {
1071            base: ctx.base(self.span),
1072            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
1073            type_annotation: self.type_ann.babelify(ctx),
1074        }
1075    }
1076}
1077
1078impl Babelify for TsTypeAssertion {
1079    type Output = TSTypeAssertion;
1080
1081    fn babelify(self, ctx: &Context) -> Self::Output {
1082        TSTypeAssertion {
1083            base: ctx.base(self.span),
1084            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
1085            type_annotation: self.type_ann.babelify(ctx),
1086        }
1087    }
1088}
1089
1090impl Babelify for TsNonNullExpr {
1091    type Output = TSNonNullExpression;
1092
1093    fn babelify(self, ctx: &Context) -> Self::Output {
1094        TSNonNullExpression {
1095            base: ctx.base(self.span),
1096            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
1097        }
1098    }
1099}
1100
1101impl Babelify for Accessibility {
1102    type Output = Access;
1103
1104    fn babelify(self, _ctx: &Context) -> Self::Output {
1105        match self {
1106            Accessibility::Public => Access::Public,
1107            Accessibility::Protected => Access::Protected,
1108            Accessibility::Private => Access::Private,
1109            #[cfg(swc_ast_unknown)]
1110            _ => panic!("unable to access unknown nodes"),
1111        }
1112    }
1113}
1114
1115// TODO(dwoznicki): There does not appear to be a corresponding Babel node for
1116// this.
1117impl Babelify for TsConstAssertion {
1118    type Output = String;
1119
1120    fn babelify(self, _ctx: &Context) -> Self::Output {
1121        panic!("unimplemented");
1122    }
1123}