swc_estree_compat/swcify/
expr.rs

1use swc_common::Spanned;
2use swc_ecma_ast::{
3    op, ArrayLit, ArrowExpr, AssignExpr, AwaitExpr, BinExpr, BinaryOp, BindingIdent,
4    BlockStmtOrExpr, CallExpr, Callee, ClassExpr, ComputedPropName, CondExpr, Expr, ExprOrSpread,
5    FnExpr, Function, Ident, Import, JSXAttr, JSXAttrOrSpread, JSXAttrValue, JSXEmptyExpr, JSXExpr,
6    JSXExprContainer, JSXMemberExpr, JSXObject, KeyValueProp, Lit, MemberExpr, MemberProp,
7    MetaPropExpr, MetaPropKind, MethodProp, NewExpr, ObjectLit, OptCall, OptChainBase,
8    OptChainExpr, ParenExpr, Prop, PropName, PropOrSpread, SeqExpr, SpreadElement, SuperProp,
9    SuperPropExpr, TaggedTpl, ThisExpr, TsAsExpr, TsNonNullExpr, TsTypeAssertion,
10    TsTypeParamInstantiation, UnaryExpr, UnaryOp, UpdateExpr, YieldExpr,
11};
12use swc_estree_ast::{
13    Arg, ArrayExprEl, ArrayExpression, ArrowFuncExprBody, ArrowFunctionExpression,
14    AssignmentExpression, AwaitExpression, BinaryExprLeft, BinaryExprOp, BinaryExpression,
15    BindExpression, CallExpression, Callee as BabelCallee, ClassExpression, ConditionalExpression,
16    DoExpression, Expression, FunctionExpression, Identifier, Import as BabelImport, JSXAttrVal,
17    JSXAttribute, JSXEmptyExpression, JSXExprContainerExpr, JSXExpressionContainer,
18    JSXMemberExprObject, JSXMemberExpression, JSXSpreadAttribute, Literal, LogicalExprOp,
19    LogicalExpression, MemberExprProp, MemberExpression, MetaProperty, ModuleExpression,
20    NewExpression, ObjectExprProp, ObjectExpression, ObjectKey, ObjectMethod, ObjectPropVal,
21    ObjectProperty, OptionalCallExpression, OptionalMemberExprProp, OptionalMemberExpression,
22    ParenthesizedExpression, PatternLike, PipelinePrimaryTopicReference, RecordExpression,
23    SequenceExpression, TSAsExpression, TSNonNullExpression, TSTypeAssertion,
24    TaggedTemplateExprTypeParams, TaggedTemplateExpression, ThisExpression, TupleExpression,
25    TypeCastExpression, UnaryExprOp, UnaryExpression, UpdateExprOp, UpdateExpression,
26    YieldExpression,
27};
28
29use super::Context;
30use crate::{swcify::Swcify, Never};
31
32impl Swcify for Expression {
33    type Output = Box<Expr>;
34
35    fn swcify(self, ctx: &Context) -> Self::Output {
36        Box::new(match self {
37            Expression::Array(e) => e.swcify(ctx).into(),
38            Expression::Assignment(e) => e.swcify(ctx).into(),
39            Expression::Binary(e) => e.swcify(ctx).into(),
40            Expression::Call(e) => e.swcify(ctx).into(),
41            Expression::Conditional(e) => e.swcify(ctx).into(),
42            Expression::Func(e) => e.swcify(ctx).into(),
43            Expression::Id(e) => e.swcify(ctx).id.into(),
44            Expression::Literal(Literal::String(e)) => e.swcify(ctx).into(),
45            Expression::Literal(Literal::Numeric(e)) => e.swcify(ctx).into(),
46            Expression::Literal(Literal::Null(e)) => Lit::from(e.swcify(ctx)).into(),
47            Expression::Literal(Literal::Boolean(e)) => Lit::from(e.swcify(ctx)).into(),
48            Expression::Literal(Literal::RegExp(e)) => Lit::from(e.swcify(ctx)).into(),
49            Expression::Logical(e) => e.swcify(ctx).into(),
50            Expression::Member(e) => e.swcify(ctx),
51            Expression::New(e) => e.swcify(ctx).into(),
52            Expression::Object(e) => e.swcify(ctx).into(),
53            Expression::Sequence(e) => e.swcify(ctx).into(),
54            Expression::Parenthesized(e) => e.swcify(ctx).into(),
55            Expression::This(e) => e.swcify(ctx).into(),
56            Expression::Unary(e) => e.swcify(ctx).into(),
57            Expression::Update(e) => e.swcify(ctx).into(),
58            Expression::ArrowFunc(e) => e.swcify(ctx).into(),
59            Expression::Class(e) => e.swcify(ctx).into(),
60            Expression::MetaProp(e) => e.swcify(ctx).into(),
61            Expression::Super(..) => unreachable!(),
62            Expression::TaggedTemplate(e) => e.swcify(ctx).into(),
63            Expression::TemplateLiteral(e) => e.swcify(ctx).into(),
64            Expression::Yield(e) => e.swcify(ctx).into(),
65            Expression::Await(e) => e.swcify(ctx).into(),
66            Expression::Literal(Literal::BigInt(e)) => e.swcify(ctx).into(),
67            Expression::OptionalMember(e) => e.swcify(ctx).into(),
68            Expression::OptionalCall(e) => e.swcify(ctx).into(),
69            Expression::JSXElement(e) => return e.swcify(ctx).into(),
70            Expression::JSXFragment(e) => e.swcify(ctx).into(),
71            Expression::Literal(Literal::Decimal(e)) => e.swcify(ctx).into(),
72            Expression::TSAs(e) => e.swcify(ctx).into(),
73            Expression::TSTypeAssertion(e) => e.swcify(ctx).into(),
74            Expression::TSNonNull(e) => e.swcify(ctx).into(),
75            _ => {
76                unimplemented!("swcify: {:?}", self)
77            }
78        })
79    }
80}
81
82impl Swcify for ArrayExpression {
83    type Output = ArrayLit;
84
85    fn swcify(self, ctx: &Context) -> Self::Output {
86        ArrayLit {
87            span: ctx.span(&self.base),
88            elems: self.elements.swcify(ctx),
89        }
90    }
91}
92
93impl Swcify for AssignmentExpression {
94    type Output = AssignExpr;
95
96    fn swcify(self, ctx: &Context) -> Self::Output {
97        AssignExpr {
98            span: ctx.span(&self.base),
99            op: self.operator.parse().unwrap_or_else(|_| {
100                panic!(
101                    "failed to convert `AssignmentExpression` of babel: Unknown assignment \
102                     operator {}",
103                    self.operator,
104                )
105            }),
106            left: self.left.swcify(ctx).try_into().unwrap(),
107            right: self.right.swcify(ctx),
108        }
109    }
110}
111
112impl Swcify for BinaryExpression {
113    type Output = BinExpr;
114
115    fn swcify(self, ctx: &Context) -> Self::Output {
116        BinExpr {
117            span: ctx.span(&self.base),
118            op: self.operator.swcify(ctx),
119            left: self.left.swcify(ctx),
120            right: self.right.swcify(ctx),
121        }
122    }
123}
124
125impl Swcify for swc_estree_ast::PrivateName {
126    type Output = swc_ecma_ast::PrivateName;
127
128    fn swcify(self, ctx: &Context) -> Self::Output {
129        swc_ecma_ast::PrivateName {
130            span: ctx.span(&self.base),
131            name: self.id.swcify(ctx).sym.clone(),
132        }
133    }
134}
135
136impl Swcify for BinaryExprLeft {
137    type Output = Box<Expr>;
138
139    fn swcify(self, ctx: &Context) -> Self::Output {
140        match self {
141            BinaryExprLeft::Private(e) => e.swcify(ctx).into(),
142            BinaryExprLeft::Expr(e) => e.swcify(ctx),
143        }
144    }
145}
146
147impl Swcify for BinaryExprOp {
148    type Output = BinaryOp;
149
150    fn swcify(self, _: &Context) -> Self::Output {
151        match self {
152            BinaryExprOp::Addition => {
153                op!(bin, "+")
154            }
155            BinaryExprOp::Subtraction => {
156                op!(bin, "-")
157            }
158            BinaryExprOp::Division => {
159                op!("/")
160            }
161            BinaryExprOp::Remainder => {
162                op!("%")
163            }
164            BinaryExprOp::Multiplication => {
165                op!("*")
166            }
167            BinaryExprOp::Exponentiation => {
168                op!("**")
169            }
170            BinaryExprOp::And => {
171                op!("&")
172            }
173            BinaryExprOp::Or => {
174                op!("|")
175            }
176            BinaryExprOp::RightShift => {
177                op!(">>")
178            }
179            BinaryExprOp::UnsignedRightShift => {
180                op!(">>>")
181            }
182            BinaryExprOp::LeftShift => {
183                op!("<<")
184            }
185            BinaryExprOp::Xor => {
186                op!("^")
187            }
188            BinaryExprOp::Equal => {
189                op!("==")
190            }
191            BinaryExprOp::StrictEqual => {
192                op!("===")
193            }
194            BinaryExprOp::NotEqual => {
195                op!("!=")
196            }
197            BinaryExprOp::StrictNotEqual => {
198                op!("!==")
199            }
200            BinaryExprOp::In => {
201                op!("in")
202            }
203            BinaryExprOp::Instanceof => {
204                op!("instanceof")
205            }
206            BinaryExprOp::GreaterThan => {
207                op!(">")
208            }
209            BinaryExprOp::LessThan => {
210                op!("<")
211            }
212            BinaryExprOp::GreaterThanOrEqual => {
213                op!(">=")
214            }
215            BinaryExprOp::LessThanOrEqual => {
216                op!("<=")
217            }
218        }
219    }
220}
221
222impl Swcify for BabelCallee {
223    type Output = Callee;
224
225    fn swcify(self, ctx: &Context) -> Self::Output {
226        match self {
227            BabelCallee::V8Id(_) => {
228                unreachable!("what is v8 id?")
229            }
230            BabelCallee::Expr(e) => match *e {
231                Expression::Super(s) => Callee::Super(s.swcify(ctx)),
232                Expression::Import(s) => Callee::Import(s.swcify(ctx)),
233                _ => Callee::Expr(e.swcify(ctx)),
234            },
235        }
236    }
237}
238
239impl Swcify for CallExpression {
240    type Output = CallExpr;
241
242    fn swcify(self, ctx: &Context) -> Self::Output {
243        CallExpr {
244            span: ctx.span(&self.base),
245            callee: self.callee.swcify(ctx),
246            args: self
247                .arguments
248                .swcify(ctx)
249                .into_iter()
250                .map(|v| v.expect("failed to swcify arguments"))
251                .collect(),
252            type_args: self.type_parameters.swcify(ctx).map(Box::new),
253            ..Default::default()
254        }
255    }
256}
257
258impl Swcify for Arg {
259    type Output = Option<ExprOrSpread>;
260
261    fn swcify(self, ctx: &Context) -> Self::Output {
262        Some(match self {
263            Arg::Spread(s) => ExprOrSpread {
264                spread: Some(ctx.span(&s.base)),
265                expr: s.argument.swcify(ctx),
266            },
267            Arg::JSXName(e) => ExprOrSpread {
268                spread: None,
269                expr: e.swcify(ctx).into(),
270            },
271            Arg::Placeholder(_) => return None,
272            Arg::Expr(e) => ExprOrSpread {
273                spread: None,
274                expr: e.swcify(ctx),
275            },
276        })
277    }
278}
279
280impl Swcify for ConditionalExpression {
281    type Output = CondExpr;
282
283    fn swcify(self, ctx: &Context) -> Self::Output {
284        CondExpr {
285            span: ctx.span(&self.base),
286            test: self.test.swcify(ctx),
287            cons: self.consequent.swcify(ctx),
288            alt: self.alternate.swcify(ctx),
289        }
290    }
291}
292
293impl Swcify for FunctionExpression {
294    type Output = FnExpr;
295
296    fn swcify(self, ctx: &Context) -> Self::Output {
297        FnExpr {
298            ident: self.id.swcify(ctx).map(|v| v.into()),
299            function: Box::new(Function {
300                params: self.params.swcify(ctx),
301                decorators: Default::default(),
302                span: ctx.span(&self.base),
303                body: Some(self.body.swcify(ctx)),
304                is_generator: self.generator.unwrap_or(false),
305                is_async: self.is_async.unwrap_or(false),
306                type_params: self.type_parameters.swcify(ctx).flatten().map(Box::new),
307                return_type: self.return_type.swcify(ctx).flatten().map(Box::new),
308                ..Default::default()
309            }),
310        }
311    }
312}
313
314impl Swcify for Identifier {
315    type Output = BindingIdent;
316
317    fn swcify(self, ctx: &Context) -> Self::Output {
318        BindingIdent {
319            id: Ident {
320                span: ctx.span(&self.base),
321                sym: self.name,
322                optional: self.optional.unwrap_or(false),
323                ctxt: Default::default(),
324            },
325            type_ann: self.type_annotation.swcify(ctx).flatten().map(Box::new),
326        }
327    }
328}
329
330impl Swcify for LogicalExprOp {
331    type Output = BinaryOp;
332
333    fn swcify(self, _: &Context) -> Self::Output {
334        match self {
335            LogicalExprOp::Or => {
336                op!("||")
337            }
338            LogicalExprOp::And => {
339                op!("&&")
340            }
341            LogicalExprOp::Nullish => {
342                op!("??")
343            }
344        }
345    }
346}
347
348impl Swcify for LogicalExpression {
349    type Output = BinExpr;
350
351    fn swcify(self, ctx: &Context) -> Self::Output {
352        BinExpr {
353            span: ctx.span(&self.base),
354            op: self.operator.swcify(ctx),
355            left: self.left.swcify(ctx),
356            right: self.right.swcify(ctx),
357        }
358    }
359}
360
361impl Swcify for MemberExpression {
362    type Output = Expr;
363
364    fn swcify(self, ctx: &Context) -> Self::Output {
365        match *self.object {
366            Expression::Super(s) => SuperPropExpr {
367                span: ctx.span(&self.base),
368                obj: s.swcify(ctx),
369                prop: match (*self.property, self.computed) {
370                    (MemberExprProp::Id(i), false) => SuperProp::Ident(i.swcify(ctx).into()),
371                    (MemberExprProp::Expr(e), true) => {
372                        let expr = e.swcify(ctx);
373                        SuperProp::Computed(ComputedPropName {
374                            span: expr.span(),
375                            expr,
376                        })
377                    }
378                    _ => unreachable!(),
379                },
380            }
381            .into(),
382            _ => MemberExpr {
383                span: ctx.span(&self.base),
384                obj: self.object.swcify(ctx),
385                prop: match (*self.property, self.computed) {
386                    (MemberExprProp::Id(i), false) => MemberProp::Ident(i.swcify(ctx).into()),
387                    (MemberExprProp::PrivateName(e), false) => {
388                        MemberProp::PrivateName(e.swcify(ctx))
389                    }
390                    (MemberExprProp::Expr(e), true) => {
391                        let expr = e.swcify(ctx);
392                        MemberProp::Computed(ComputedPropName {
393                            span: expr.span(),
394                            expr,
395                        })
396                    }
397                    _ => unreachable!(),
398                },
399            }
400            .into(),
401        }
402    }
403}
404
405impl Swcify for NewExpression {
406    type Output = NewExpr;
407
408    fn swcify(self, ctx: &Context) -> Self::Output {
409        NewExpr {
410            span: ctx.span(&self.base),
411            callee: match self.callee {
412                BabelCallee::V8Id(..) => {
413                    unreachable!()
414                }
415                BabelCallee::Expr(e) => e.swcify(ctx),
416            },
417            args: Some(
418                self.arguments
419                    .swcify(ctx)
420                    .into_iter()
421                    .map(|v| v.expect("failed to swcify arguments"))
422                    .collect(),
423            ),
424            type_args: self.type_parameters.swcify(ctx).map(From::from),
425            ..Default::default()
426        }
427    }
428}
429
430impl Swcify for ObjectExpression {
431    type Output = ObjectLit;
432
433    fn swcify(self, ctx: &Context) -> Self::Output {
434        ObjectLit {
435            span: ctx.span(&self.base),
436            props: self.properties.swcify(ctx),
437        }
438    }
439}
440
441impl Swcify for ObjectExprProp {
442    type Output = PropOrSpread;
443
444    fn swcify(self, ctx: &Context) -> Self::Output {
445        match self {
446            ObjectExprProp::Method(m) => PropOrSpread::Prop(Box::new(Prop::Method(m.swcify(ctx)))),
447            ObjectExprProp::Prop(p) => PropOrSpread::Prop(Box::new(Prop::KeyValue(p.swcify(ctx)))),
448            ObjectExprProp::Spread(p) => PropOrSpread::Spread(SpreadElement {
449                // TODO: Use exact span
450                dot3_token: ctx.span(&p.base),
451                expr: p.argument.swcify(ctx),
452            }),
453        }
454    }
455}
456
457impl Swcify for ObjectMethod {
458    type Output = MethodProp;
459
460    fn swcify(self, ctx: &Context) -> Self::Output {
461        MethodProp {
462            key: self.key.swcify(ctx),
463            function: Box::new(Function {
464                params: self.params.swcify(ctx),
465                decorators: self.decorator.swcify(ctx).unwrap_or_default(),
466                span: ctx.span(&self.base),
467                body: Some(self.body.swcify(ctx)),
468                is_generator: self.generator.unwrap_or(false),
469                is_async: self.is_async.unwrap_or(false),
470                type_params: self.type_parameters.swcify(ctx).flatten().map(Box::new),
471                return_type: self.return_type.swcify(ctx).flatten().map(Box::new),
472                ..Default::default()
473            }),
474        }
475    }
476}
477
478impl Swcify for swc_estree_ast::Decorator {
479    type Output = swc_ecma_ast::Decorator;
480
481    fn swcify(self, ctx: &Context) -> Self::Output {
482        swc_ecma_ast::Decorator {
483            span: ctx.span(&self.base),
484            expr: self.expression.swcify(ctx),
485        }
486    }
487}
488
489impl Swcify for ObjectKey {
490    type Output = PropName;
491
492    fn swcify(self, ctx: &Context) -> Self::Output {
493        match self {
494            ObjectKey::Id(v) => PropName::Ident(v.swcify(ctx).into()),
495            ObjectKey::String(v) => PropName::Str(v.swcify(ctx)),
496            ObjectKey::Numeric(v) => PropName::Num(v.swcify(ctx)),
497            ObjectKey::Expr(v) => {
498                let expr = v.swcify(ctx);
499                PropName::Computed(ComputedPropName {
500                    span: expr.span(),
501                    expr,
502                })
503            }
504        }
505    }
506}
507
508impl Swcify for ObjectProperty {
509    type Output = KeyValueProp;
510
511    fn swcify(self, ctx: &Context) -> Self::Output {
512        KeyValueProp {
513            key: self.key.swcify(ctx),
514            value: match self.value {
515                ObjectPropVal::Pattern(pat) => match pat {
516                    PatternLike::Id(i) => i.swcify(ctx).into(),
517                    _ => {
518                        panic!("swc does not support ObjectPropVal::Pattern({pat:?})")
519                    }
520                },
521                ObjectPropVal::Expr(e) => e.swcify(ctx),
522            },
523        }
524    }
525}
526
527impl Swcify for SequenceExpression {
528    type Output = SeqExpr;
529
530    fn swcify(self, ctx: &Context) -> Self::Output {
531        SeqExpr {
532            span: ctx.span(&self.base),
533            exprs: self.expressions.swcify(ctx),
534        }
535    }
536}
537
538impl Swcify for ParenthesizedExpression {
539    type Output = ParenExpr;
540
541    fn swcify(self, ctx: &Context) -> Self::Output {
542        ParenExpr {
543            span: ctx.span(&self.base),
544            expr: self.expression.swcify(ctx),
545        }
546    }
547}
548
549impl Swcify for ThisExpression {
550    type Output = ThisExpr;
551
552    fn swcify(self, ctx: &Context) -> Self::Output {
553        ThisExpr {
554            span: ctx.span(&self.base),
555        }
556    }
557}
558
559impl Swcify for UnaryExpression {
560    type Output = UnaryExpr;
561
562    fn swcify(self, ctx: &Context) -> Self::Output {
563        UnaryExpr {
564            span: ctx.span(&self.base),
565            op: self.operator.swcify(ctx),
566            arg: self.argument.swcify(ctx),
567        }
568    }
569}
570
571impl Swcify for UnaryExprOp {
572    type Output = UnaryOp;
573
574    fn swcify(self, _: &Context) -> Self::Output {
575        match self {
576            UnaryExprOp::Void => {
577                op!("void")
578            }
579            UnaryExprOp::Throw => {
580                panic!("swc does not support throw expressions")
581            }
582            UnaryExprOp::Delete => {
583                op!("delete")
584            }
585            UnaryExprOp::LogicalNot => {
586                op!("!")
587            }
588            UnaryExprOp::Plus => {
589                op!(unary, "+")
590            }
591            UnaryExprOp::Negation => {
592                op!(unary, "-")
593            }
594            UnaryExprOp::BitwiseNot => {
595                op!("~")
596            }
597            UnaryExprOp::Typeof => {
598                op!("typeof")
599            }
600        }
601    }
602}
603
604impl Swcify for UpdateExpression {
605    type Output = UpdateExpr;
606
607    fn swcify(self, ctx: &Context) -> Self::Output {
608        UpdateExpr {
609            span: ctx.span(&self.base),
610            op: match self.operator {
611                UpdateExprOp::Increment => {
612                    op!("++")
613                }
614                UpdateExprOp::Decrement => {
615                    op!("--")
616                }
617            },
618            prefix: self.prefix,
619            arg: self.argument.swcify(ctx),
620        }
621    }
622}
623
624impl Swcify for ArrowFunctionExpression {
625    type Output = ArrowExpr;
626
627    fn swcify(self, ctx: &Context) -> Self::Output {
628        ArrowExpr {
629            span: ctx.span(&self.base),
630            params: self.params.into_iter().map(|v| v.swcify(ctx).pat).collect(),
631            body: Box::new(self.body.swcify(ctx)),
632            is_async: self.is_async,
633            is_generator: self.generator,
634            type_params: self.type_parameters.swcify(ctx).flatten().map(Box::new),
635            return_type: self.return_type.swcify(ctx).flatten().map(Box::new),
636            ..Default::default()
637        }
638    }
639}
640
641impl Swcify for ArrowFuncExprBody {
642    type Output = BlockStmtOrExpr;
643
644    fn swcify(self, ctx: &Context) -> Self::Output {
645        match self {
646            ArrowFuncExprBody::Block(v) => BlockStmtOrExpr::BlockStmt(v.swcify(ctx)),
647            ArrowFuncExprBody::Expr(v) => BlockStmtOrExpr::Expr(v.swcify(ctx)),
648        }
649    }
650}
651
652impl Swcify for ClassExpression {
653    type Output = ClassExpr;
654
655    fn swcify(self, ctx: &Context) -> Self::Output {
656        ClassExpr {
657            ident: self.id.swcify(ctx).map(|v| v.into()),
658            class: Box::new(swc_ecma_ast::Class {
659                span: ctx.span(&self.base),
660                decorators: self.decorators.swcify(ctx).unwrap_or_default(),
661                body: self.body.swcify(ctx),
662                super_class: self.super_class.swcify(ctx),
663                is_abstract: false,
664                type_params: self.type_parameters.swcify(ctx).flatten().map(Box::new),
665                super_type_params: self.super_type_parameters.swcify(ctx).map(Box::new),
666                implements: self.implements.swcify(ctx).unwrap_or_default(),
667                ..Default::default()
668            }),
669        }
670    }
671}
672
673impl Swcify for MetaProperty {
674    type Output = MetaPropExpr;
675
676    fn swcify(self, ctx: &Context) -> Self::Output {
677        let meta: Ident = self.meta.swcify(ctx).into();
678        let prop: Ident = self.property.swcify(ctx).into();
679        match (&*meta.sym, &*prop.sym) {
680            ("new", "target") => MetaPropExpr {
681                kind: MetaPropKind::NewTarget,
682                span: ctx.span(&self.base),
683            },
684            ("import", "meta") => MetaPropExpr {
685                kind: MetaPropKind::NewTarget,
686                span: ctx.span(&self.base),
687            },
688            _ => unreachable!("there are only two kind of meta prop"),
689        }
690    }
691}
692
693impl Swcify for swc_estree_ast::Super {
694    type Output = swc_ecma_ast::Super;
695
696    fn swcify(self, ctx: &Context) -> Self::Output {
697        swc_ecma_ast::Super {
698            span: ctx.span(&self.base),
699        }
700    }
701}
702
703impl Swcify for TaggedTemplateExpression {
704    type Output = TaggedTpl;
705
706    fn swcify(self, ctx: &Context) -> Self::Output {
707        TaggedTpl {
708            span: ctx.span(&self.base),
709            tag: self.tag.swcify(ctx),
710            type_params: self.type_parameters.swcify(ctx).map(From::from),
711            tpl: Box::new(self.quasi.swcify(ctx)),
712            ..Default::default()
713        }
714    }
715}
716
717impl Swcify for TaggedTemplateExprTypeParams {
718    type Output = TsTypeParamInstantiation;
719
720    fn swcify(self, ctx: &Context) -> Self::Output {
721        match self {
722            TaggedTemplateExprTypeParams::Flow(_) => unimplemented!("flow types"),
723            TaggedTemplateExprTypeParams::TS(v) => v.swcify(ctx),
724        }
725    }
726}
727
728impl Swcify for YieldExpression {
729    type Output = YieldExpr;
730
731    fn swcify(self, ctx: &Context) -> Self::Output {
732        YieldExpr {
733            span: ctx.span(&self.base),
734            arg: self.argument.swcify(ctx),
735            delegate: self.delegate,
736        }
737    }
738}
739
740impl Swcify for AwaitExpression {
741    type Output = AwaitExpr;
742
743    fn swcify(self, ctx: &Context) -> Self::Output {
744        AwaitExpr {
745            span: ctx.span(&self.base),
746            arg: self.argument.swcify(ctx),
747        }
748    }
749}
750
751impl Swcify for BabelImport {
752    type Output = Import;
753
754    fn swcify(self, ctx: &Context) -> Self::Output {
755        Import {
756            span: ctx.span(&self.base),
757            // TODO
758            phase: Default::default(),
759        }
760    }
761}
762
763impl Swcify for OptionalMemberExpression {
764    type Output = OptChainExpr;
765
766    fn swcify(self, ctx: &Context) -> Self::Output {
767        OptChainExpr {
768            span: ctx.span(&self.base),
769            // TODO: Use correct span.
770            optional: self.optional,
771            base: Box::new(OptChainBase::Member(MemberExpr {
772                span: ctx.span(&self.base),
773                obj: self.object.swcify(ctx),
774                prop: match (self.property, self.computed) {
775                    (OptionalMemberExprProp::Id(i), false) => {
776                        MemberProp::Ident(i.swcify(ctx).into())
777                    }
778                    (OptionalMemberExprProp::Expr(e), true) => {
779                        let expr = e.swcify(ctx);
780                        MemberProp::Computed(ComputedPropName {
781                            span: expr.span(),
782                            expr,
783                        })
784                    }
785                    _ => unreachable!(),
786                },
787            })),
788        }
789    }
790}
791
792impl Swcify for OptionalMemberExprProp {
793    type Output = Box<Expr>;
794
795    fn swcify(self, ctx: &Context) -> Self::Output {
796        match self {
797            OptionalMemberExprProp::Id(v) => v.swcify(ctx).into(),
798            OptionalMemberExprProp::Expr(v) => v.swcify(ctx),
799        }
800    }
801}
802
803impl Swcify for OptionalCallExpression {
804    type Output = OptChainExpr;
805
806    fn swcify(self, ctx: &Context) -> Self::Output {
807        OptChainExpr {
808            span: ctx.span(&self.base),
809            optional: self.optional,
810            base: Box::new(OptChainBase::Call(OptCall {
811                span: ctx.span(&self.base),
812                callee: self.callee.swcify(ctx),
813                args: self.arguments.swcify(ctx).into_iter().flatten().collect(),
814                type_args: self.type_parameters.swcify(ctx).map(From::from),
815                ..Default::default()
816            })),
817        }
818    }
819}
820
821impl Swcify for TypeCastExpression {
822    type Output = Never;
823
824    fn swcify(self, _: &Context) -> Self::Output {
825        unimplemented!("flow type cast")
826    }
827}
828
829impl Swcify for swc_estree_ast::JSXElement {
830    type Output = swc_ecma_ast::JSXElement;
831
832    fn swcify(self, ctx: &Context) -> Self::Output {
833        swc_ecma_ast::JSXElement {
834            span: ctx.span(&self.base),
835            opening: self.opening_element.swcify(ctx),
836            children: self.children.swcify(ctx),
837            closing: self.closing_element.swcify(ctx),
838        }
839    }
840}
841
842impl Swcify for swc_estree_ast::JSXOpeningElement {
843    type Output = swc_ecma_ast::JSXOpeningElement;
844
845    fn swcify(self, ctx: &Context) -> Self::Output {
846        swc_ecma_ast::JSXOpeningElement {
847            span: ctx.span(&self.base),
848            name: self.name.swcify(ctx),
849            attrs: self.attributes.swcify(ctx),
850            self_closing: self.self_closing,
851            type_args: None,
852        }
853    }
854}
855
856impl Swcify for swc_estree_ast::JSXElementName {
857    type Output = swc_ecma_ast::JSXElementName;
858
859    fn swcify(self, ctx: &Context) -> Self::Output {
860        match self {
861            swc_estree_ast::JSXElementName::Id(v) => {
862                swc_ecma_ast::JSXElementName::Ident(v.swcify(ctx))
863            }
864            swc_estree_ast::JSXElementName::Expr(v) => {
865                swc_ecma_ast::JSXElementName::JSXMemberExpr(v.swcify(ctx))
866            }
867            swc_estree_ast::JSXElementName::Name(v) => {
868                swc_ecma_ast::JSXElementName::JSXNamespacedName(v.swcify(ctx))
869            }
870        }
871    }
872}
873
874impl Swcify for JSXMemberExpression {
875    type Output = JSXMemberExpr;
876
877    fn swcify(self, ctx: &Context) -> Self::Output {
878        JSXMemberExpr {
879            span: ctx.span(&self.base),
880            obj: self.object.swcify(ctx),
881            prop: self.property.swcify(ctx).into(),
882        }
883    }
884}
885
886impl Swcify for JSXMemberExprObject {
887    type Output = JSXObject;
888
889    fn swcify(self, ctx: &Context) -> Self::Output {
890        match self {
891            JSXMemberExprObject::Expr(e) => JSXObject::JSXMemberExpr(Box::new(e.swcify(ctx))),
892            JSXMemberExprObject::Id(e) => JSXObject::Ident(e.swcify(ctx)),
893        }
894    }
895}
896
897impl Swcify for swc_estree_ast::JSXOpeningElAttr {
898    type Output = JSXAttrOrSpread;
899
900    fn swcify(self, ctx: &Context) -> Self::Output {
901        match self {
902            swc_estree_ast::JSXOpeningElAttr::Attr(v) => JSXAttrOrSpread::JSXAttr(v.swcify(ctx)),
903            swc_estree_ast::JSXOpeningElAttr::Spread(v) => {
904                JSXAttrOrSpread::SpreadElement(v.swcify(ctx))
905            }
906        }
907    }
908}
909
910impl Swcify for JSXAttribute {
911    type Output = JSXAttr;
912
913    fn swcify(self, ctx: &Context) -> Self::Output {
914        JSXAttr {
915            span: ctx.span(&self.base),
916            name: self.name.swcify(ctx),
917            value: self.value.swcify(ctx),
918        }
919    }
920}
921
922impl Swcify for swc_estree_ast::JSXAttrName {
923    type Output = swc_ecma_ast::JSXAttrName;
924
925    fn swcify(self, ctx: &Context) -> Self::Output {
926        match self {
927            swc_estree_ast::JSXAttrName::Id(v) => {
928                swc_ecma_ast::JSXAttrName::Ident(v.swcify(ctx).into())
929            }
930            swc_estree_ast::JSXAttrName::Name(v) => {
931                swc_ecma_ast::JSXAttrName::JSXNamespacedName(v.swcify(ctx))
932            }
933        }
934    }
935}
936
937impl Swcify for JSXAttrVal {
938    type Output = JSXAttrValue;
939
940    fn swcify(self, ctx: &Context) -> Self::Output {
941        match self {
942            JSXAttrVal::Element(v) => JSXAttrValue::JSXElement(Box::new(v.swcify(ctx))),
943            JSXAttrVal::Fragment(v) => JSXAttrValue::JSXFragment(v.swcify(ctx)),
944            JSXAttrVal::String(v) => JSXAttrValue::Lit(Lit::Str(v.swcify(ctx))),
945            JSXAttrVal::Expr(v) => JSXAttrValue::JSXExprContainer(v.swcify(ctx)),
946        }
947    }
948}
949
950impl Swcify for JSXExpressionContainer {
951    type Output = JSXExprContainer;
952
953    fn swcify(self, ctx: &Context) -> Self::Output {
954        JSXExprContainer {
955            span: ctx.span(&self.base),
956            expr: self.expression.swcify(ctx),
957        }
958    }
959}
960
961impl Swcify for JSXExprContainerExpr {
962    type Output = JSXExpr;
963
964    fn swcify(self, ctx: &Context) -> Self::Output {
965        match self {
966            JSXExprContainerExpr::Empty(v) => JSXExpr::JSXEmptyExpr(v.swcify(ctx)),
967            JSXExprContainerExpr::Expr(v) => JSXExpr::Expr(v.swcify(ctx)),
968        }
969    }
970}
971
972impl Swcify for JSXEmptyExpression {
973    type Output = JSXEmptyExpr;
974
975    fn swcify(self, ctx: &Context) -> Self::Output {
976        JSXEmptyExpr {
977            span: ctx.span(&self.base),
978        }
979    }
980}
981
982impl Swcify for JSXSpreadAttribute {
983    type Output = SpreadElement;
984
985    fn swcify(self, ctx: &Context) -> Self::Output {
986        SpreadElement {
987            dot3_token: ctx.span(&self.base),
988            expr: self.argument.swcify(ctx),
989        }
990    }
991}
992
993impl Swcify for swc_estree_ast::JSXElementChild {
994    type Output = swc_ecma_ast::JSXElementChild;
995
996    fn swcify(self, ctx: &Context) -> Self::Output {
997        match self {
998            swc_estree_ast::JSXElementChild::Text(v) => {
999                swc_ecma_ast::JSXElementChild::JSXText(v.swcify(ctx))
1000            }
1001            swc_estree_ast::JSXElementChild::Expr(v) => {
1002                swc_ecma_ast::JSXElementChild::from(v.swcify(ctx))
1003            }
1004            swc_estree_ast::JSXElementChild::Spread(v) => {
1005                swc_ecma_ast::JSXElementChild::from(v.swcify(ctx))
1006            }
1007            swc_estree_ast::JSXElementChild::Element(v) => {
1008                swc_ecma_ast::JSXElementChild::from(Box::new(v.swcify(ctx)))
1009            }
1010            swc_estree_ast::JSXElementChild::Fragment(v) => {
1011                swc_ecma_ast::JSXElementChild::from(v.swcify(ctx))
1012            }
1013        }
1014    }
1015}
1016
1017impl Swcify for swc_estree_ast::JSXText {
1018    type Output = swc_ecma_ast::JSXText;
1019
1020    fn swcify(self, ctx: &Context) -> Self::Output {
1021        swc_ecma_ast::JSXText {
1022            span: ctx.span(&self.base),
1023            value: self.value,
1024            // TODO fix me
1025            raw: Default::default(),
1026        }
1027    }
1028}
1029
1030impl Swcify for swc_estree_ast::JSXSpreadChild {
1031    type Output = swc_ecma_ast::JSXSpreadChild;
1032
1033    fn swcify(self, ctx: &Context) -> Self::Output {
1034        swc_ecma_ast::JSXSpreadChild {
1035            span: ctx.span(&self.base),
1036            expr: self.expression.swcify(ctx),
1037        }
1038    }
1039}
1040
1041impl Swcify for swc_estree_ast::JSXClosingElement {
1042    type Output = swc_ecma_ast::JSXClosingElement;
1043
1044    fn swcify(self, ctx: &Context) -> Self::Output {
1045        swc_ecma_ast::JSXClosingElement {
1046            span: ctx.span(&self.base),
1047            name: self.name.swcify(ctx),
1048        }
1049    }
1050}
1051
1052impl Swcify for swc_estree_ast::JSXFragment {
1053    type Output = swc_ecma_ast::JSXFragment;
1054
1055    fn swcify(self, ctx: &Context) -> Self::Output {
1056        swc_ecma_ast::JSXFragment {
1057            span: ctx.span(&self.base),
1058            opening: self.opening_fragment.swcify(ctx),
1059            children: self.children.swcify(ctx),
1060            closing: self.closing_fragment.swcify(ctx),
1061        }
1062    }
1063}
1064
1065impl Swcify for swc_estree_ast::JSXOpeningFragment {
1066    type Output = swc_ecma_ast::JSXOpeningFragment;
1067
1068    fn swcify(self, ctx: &Context) -> Self::Output {
1069        swc_ecma_ast::JSXOpeningFragment {
1070            span: ctx.span(&self.base),
1071        }
1072    }
1073}
1074
1075impl Swcify for swc_estree_ast::JSXClosingFragment {
1076    type Output = swc_ecma_ast::JSXClosingFragment;
1077
1078    fn swcify(self, ctx: &Context) -> Self::Output {
1079        swc_ecma_ast::JSXClosingFragment {
1080            span: ctx.span(&self.base),
1081        }
1082    }
1083}
1084
1085impl Swcify for BindExpression {
1086    type Output = Never;
1087
1088    fn swcify(self, _: &Context) -> Self::Output {
1089        panic!("swc does not support bind expressions")
1090    }
1091}
1092
1093impl Swcify for DoExpression {
1094    type Output = Never;
1095
1096    fn swcify(self, _: &Context) -> Self::Output {
1097        panic!("swc does not support do expressions")
1098    }
1099}
1100
1101impl Swcify for PipelinePrimaryTopicReference {
1102    type Output = Never;
1103
1104    fn swcify(self, _: &Context) -> Self::Output {
1105        panic!("swc does not support `PipelinePrimaryTopicReference`")
1106    }
1107}
1108
1109impl Swcify for RecordExpression {
1110    type Output = Never;
1111
1112    fn swcify(self, _: &Context) -> Self::Output {
1113        panic!("swc does not support record expressions")
1114    }
1115}
1116
1117impl Swcify for TupleExpression {
1118    type Output = Never;
1119
1120    fn swcify(self, _: &Context) -> Self::Output {
1121        panic!("swc does not support tuple expressions")
1122    }
1123}
1124
1125impl Swcify for ModuleExpression {
1126    type Output = Never;
1127
1128    fn swcify(self, _: &Context) -> Self::Output {
1129        panic!("swc does not support module expressions")
1130    }
1131}
1132
1133impl Swcify for TSAsExpression {
1134    type Output = TsAsExpr;
1135
1136    fn swcify(self, ctx: &Context) -> Self::Output {
1137        TsAsExpr {
1138            span: ctx.span(&self.base),
1139            expr: self.expression.swcify(ctx),
1140            type_ann: self.type_annotation.swcify(ctx),
1141        }
1142    }
1143}
1144
1145impl Swcify for TSTypeAssertion {
1146    type Output = TsTypeAssertion;
1147
1148    fn swcify(self, ctx: &Context) -> Self::Output {
1149        TsTypeAssertion {
1150            span: ctx.span(&self.base),
1151            expr: self.expression.swcify(ctx),
1152            type_ann: self.type_annotation.swcify(ctx),
1153        }
1154    }
1155}
1156
1157impl Swcify for TSNonNullExpression {
1158    type Output = TsNonNullExpr;
1159
1160    fn swcify(self, ctx: &Context) -> Self::Output {
1161        TsNonNullExpr {
1162            span: ctx.span(&self.base),
1163            expr: self.expression.swcify(ctx),
1164        }
1165    }
1166}
1167
1168impl Swcify for ArrayExprEl {
1169    type Output = ExprOrSpread;
1170
1171    fn swcify(self, ctx: &Context) -> Self::Output {
1172        match self {
1173            ArrayExprEl::Spread(s) => ExprOrSpread {
1174                // TODO: Use correct span
1175                spread: Some(ctx.span(&s.base)),
1176                expr: s.argument.swcify(ctx),
1177            },
1178            ArrayExprEl::Expr(e) => ExprOrSpread {
1179                spread: None,
1180                expr: e.swcify(ctx),
1181            },
1182        }
1183    }
1184}