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