swc_estree_compat/babelify/
expr.rs

1use copyless::BoxHelper;
2use serde::{Deserialize, Serialize};
3use swc_atoms::atom;
4use swc_common::{BytePos, Span, Spanned};
5use swc_ecma_ast::{
6    ArrayLit, ArrowExpr, AssignExpr, AssignTarget, AssignTargetPat, AwaitExpr, BinExpr, BinaryOp,
7    BlockStmtOrExpr, CallExpr, Callee, ClassExpr, CondExpr, Expr, ExprOrSpread, FnExpr, Ident,
8    Import, Lit, MemberExpr, MemberProp, MetaPropExpr, MetaPropKind, NewExpr, ObjectLit, ParenExpr,
9    PropOrSpread, SeqExpr, SimpleAssignTarget, SpreadElement, Super, SuperProp, SuperPropExpr,
10    TaggedTpl, ThisExpr, Tpl, TplElement, UnaryExpr, UpdateExpr, YieldExpr,
11};
12use swc_estree_ast::{
13    flavor::Flavor, ArrayExprEl, ArrayExpression, ArrowFuncExprBody, ArrowFunctionExpression,
14    AssignmentExpression, AwaitExpression, BinaryExprLeft, BinaryExpression, CallExpression,
15    Callee as BabelCallee, ClassExpression, ConditionalExpression, Expression, FunctionExpression,
16    Import as BabelImport, LVal, Literal, LogicalExpression, MemberExprProp, MemberExpression,
17    MetaProperty, NewExpression, ObjectExprProp, ObjectExpression, ObjectKey, ObjectMember,
18    ParenthesizedExpression, PrivateName, SequenceExpression, SpreadElement as BabelSpreadElement,
19    Super as BabelSuper, TaggedTemplateExprTypeParams, TaggedTemplateExpression, TemplateElVal,
20    TemplateElement, TemplateLiteral, TemplateLiteralExpr, ThisExpression, UnaryExpression,
21    UpdateExpression, YieldExpression,
22};
23
24use crate::babelify::{Babelify, Context};
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub enum ExprOutput {
28    Expr(Box<Expression>),
29    Private(PrivateName),
30}
31
32impl Babelify for Expr {
33    type Output = ExprOutput;
34
35    fn babelify(self, ctx: &Context) -> Self::Output {
36        match self {
37            Expr::This(t) => ExprOutput::Expr(Box::alloc().init(Expression::This(t.babelify(ctx)))),
38            Expr::Array(a) => {
39                ExprOutput::Expr(Box::alloc().init(Expression::Array(a.babelify(ctx))))
40            }
41            Expr::Object(o) => {
42                ExprOutput::Expr(Box::alloc().init(Expression::Object(o.babelify(ctx))))
43            }
44            Expr::Fn(f) => ExprOutput::Expr(Box::alloc().init(Expression::Func(f.babelify(ctx)))),
45            Expr::Unary(u) => {
46                ExprOutput::Expr(Box::alloc().init(Expression::Unary(u.babelify(ctx))))
47            }
48            Expr::Update(u) => {
49                ExprOutput::Expr(Box::alloc().init(Expression::Update(u.babelify(ctx))))
50            }
51            Expr::Bin(b) => match b.babelify(ctx) {
52                BinaryOrLogicalExpr::Binary(bin) => {
53                    ExprOutput::Expr(Box::alloc().init(Expression::Binary(bin)))
54                }
55                BinaryOrLogicalExpr::Logical(log) => {
56                    ExprOutput::Expr(Box::alloc().init(Expression::Logical(log)))
57                }
58            },
59            Expr::Assign(a) => {
60                ExprOutput::Expr(Box::alloc().init(Expression::Assignment(a.babelify(ctx))))
61            }
62            Expr::Member(m) => {
63                ExprOutput::Expr(Box::alloc().init(Expression::Member(m.babelify(ctx))))
64            }
65            Expr::SuperProp(m) => {
66                ExprOutput::Expr(Box::alloc().init(Expression::Member(m.babelify(ctx))))
67            }
68            Expr::Cond(c) => {
69                ExprOutput::Expr(Box::alloc().init(Expression::Conditional(c.babelify(ctx))))
70            }
71            Expr::Call(c) => ExprOutput::Expr(Box::alloc().init(Expression::Call(c.babelify(ctx)))),
72            Expr::New(n) => ExprOutput::Expr(Box::alloc().init(Expression::New(n.babelify(ctx)))),
73            Expr::Seq(s) => {
74                ExprOutput::Expr(Box::alloc().init(Expression::Sequence(s.babelify(ctx))))
75            }
76            Expr::Ident(i) => ExprOutput::Expr(Box::alloc().init(Expression::Id(i.babelify(ctx)))),
77            Expr::Lit(lit) => {
78                match lit {
79                    Lit::Str(s) => ExprOutput::Expr(
80                        Box::alloc().init(Expression::Literal(Literal::String(s.babelify(ctx)))),
81                    ),
82                    Lit::Bool(b) => ExprOutput::Expr(
83                        Box::alloc().init(Expression::Literal(Literal::Boolean(b.babelify(ctx)))),
84                    ),
85                    Lit::Null(n) => ExprOutput::Expr(
86                        Box::alloc().init(Expression::Literal(Literal::Null(n.babelify(ctx)))),
87                    ),
88                    Lit::Num(n) => ExprOutput::Expr(
89                        Box::alloc().init(Expression::Literal(Literal::Numeric(n.babelify(ctx)))),
90                    ),
91                    Lit::BigInt(i) => ExprOutput::Expr(
92                        Box::alloc().init(Expression::Literal(Literal::BigInt(i.babelify(ctx)))),
93                    ),
94                    Lit::Regex(r) => ExprOutput::Expr(
95                        Box::alloc().init(Expression::Literal(Literal::RegExp(r.babelify(ctx)))),
96                    ),
97                    Lit::JSXText(_) => panic!(
98                        "illegal conversion: Cannot convert {:?} to ExprOutput",
99                        &lit
100                    ), // TODO(dwoznicki): is this really illegal?
101                    #[cfg(swc_ast_unknown)]
102                    _ => panic!("unable to access unknown nodes"),
103                }
104            }
105            Expr::Tpl(t) => {
106                ExprOutput::Expr(Box::alloc().init(Expression::TemplateLiteral(t.babelify(ctx))))
107            }
108            Expr::TaggedTpl(t) => {
109                ExprOutput::Expr(Box::alloc().init(Expression::TaggedTemplate(t.babelify(ctx))))
110            }
111            Expr::Arrow(a) => {
112                ExprOutput::Expr(Box::alloc().init(Expression::ArrowFunc(a.babelify(ctx))))
113            }
114            Expr::Class(c) => {
115                ExprOutput::Expr(Box::alloc().init(Expression::Class(c.babelify(ctx))))
116            }
117            Expr::Yield(y) => {
118                ExprOutput::Expr(Box::alloc().init(Expression::Yield(y.babelify(ctx))))
119            }
120            Expr::MetaProp(m) => {
121                ExprOutput::Expr(Box::alloc().init(Expression::MetaProp(m.babelify(ctx))))
122            }
123            Expr::Await(a) => {
124                ExprOutput::Expr(Box::alloc().init(Expression::Await(a.babelify(ctx))))
125            }
126            Expr::Paren(p) => {
127                ExprOutput::Expr(Box::alloc().init(Expression::Parenthesized(p.babelify(ctx))))
128            }
129            Expr::JSXElement(e) => {
130                ExprOutput::Expr(Box::alloc().init(Expression::JSXElement(e.babelify(ctx))))
131            }
132            Expr::JSXFragment(f) => {
133                ExprOutput::Expr(Box::alloc().init(Expression::JSXFragment(f.babelify(ctx))))
134            }
135            Expr::TsTypeAssertion(a) => {
136                ExprOutput::Expr(Box::alloc().init(Expression::TSTypeAssertion(a.babelify(ctx))))
137            }
138            Expr::TsNonNull(n) => {
139                ExprOutput::Expr(Box::alloc().init(Expression::TSNonNull(n.babelify(ctx))))
140            }
141            Expr::TsAs(a) => ExprOutput::Expr(Box::alloc().init(Expression::TSAs(a.babelify(ctx)))),
142            Expr::TsInstantiation(..) => unimplemented!("Babel doesn't support this right now."),
143            Expr::PrivateName(p) => ExprOutput::Private(p.babelify(ctx)),
144
145            // TODO(dwoznicki): how does babel handle these?
146            Expr::JSXMember(_) => panic!(
147                "illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
148                &self
149            ),
150            Expr::JSXNamespacedName(_) => panic!(
151                "illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
152                &self
153            ),
154            Expr::JSXEmpty(_) => panic!(
155                "illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
156                &self
157            ),
158            Expr::TsConstAssertion(_) => panic!(
159                "illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
160                &self
161            ),
162            Expr::TsSatisfies(_) => panic!(
163                "illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
164                &self
165            ),
166            Expr::OptChain(_) => panic!(
167                "illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
168                &self
169            ),
170            Expr::Invalid(_) => panic!(
171                "illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
172                &self
173            ),
174            #[cfg(swc_ast_unknown)]
175            _ => panic!("unable to access unknown nodes"),
176        }
177    }
178}
179
180impl From<ExprOutput> for Expression {
181    fn from(o: ExprOutput) -> Self {
182        match o {
183            ExprOutput::Expr(expr) => *expr,
184            ExprOutput::Private(_) => panic!(
185                "illegal conversion: Cannot convert {:?} to Expression - babel has no equivalent",
186                &o
187            ),
188        }
189    }
190}
191
192impl From<ExprOutput> for BinaryExprLeft {
193    fn from(o: ExprOutput) -> Self {
194        match o {
195            ExprOutput::Expr(e) => BinaryExprLeft::Expr(e),
196            ExprOutput::Private(p) => BinaryExprLeft::Private(p),
197        }
198    }
199}
200
201impl From<ExprOutput> for ObjectKey {
202    fn from(o: ExprOutput) -> Self {
203        match o {
204            ExprOutput::Expr(e) => match *e {
205                Expression::Id(i) => ObjectKey::Id(i),
206                Expression::Literal(Literal::String(s)) => ObjectKey::String(s),
207                Expression::Literal(Literal::Numeric(n)) => ObjectKey::Numeric(n),
208                _ => ObjectKey::Expr(e),
209            },
210            ExprOutput::Private(_) => panic!(
211                "illegal conversion: Cannot convert {:?} to ObjectKey - babel has no equivalent",
212                &o
213            ),
214        }
215    }
216}
217
218impl From<ExprOutput> for MemberExprProp {
219    fn from(o: ExprOutput) -> Self {
220        match o {
221            ExprOutput::Private(p) => MemberExprProp::PrivateName(p),
222            ExprOutput::Expr(e) => match *e {
223                Expression::Id(i) => MemberExprProp::Id(i),
224                _ => MemberExprProp::Expr(e),
225            },
226        }
227    }
228}
229
230impl Babelify for ThisExpr {
231    type Output = ThisExpression;
232
233    fn babelify(self, ctx: &Context) -> Self::Output {
234        ThisExpression {
235            base: ctx.base(self.span),
236        }
237    }
238}
239
240impl Babelify for ArrayLit {
241    type Output = ArrayExpression;
242
243    fn babelify(self, ctx: &Context) -> Self::Output {
244        ArrayExpression {
245            base: ctx.base(self.span),
246            elements: self.elems.babelify(ctx),
247        }
248    }
249}
250
251impl Babelify for ObjectLit {
252    type Output = ObjectExpression;
253
254    fn babelify(self, ctx: &Context) -> Self::Output {
255        ObjectExpression {
256            base: ctx.base(self.span),
257            properties: self.props.babelify(ctx),
258        }
259    }
260}
261
262impl Babelify for PropOrSpread {
263    type Output = ObjectExprProp;
264
265    fn babelify(self, ctx: &Context) -> Self::Output {
266        match self {
267            PropOrSpread::Spread(s) => ObjectExprProp::Spread(s.babelify(ctx)),
268            PropOrSpread::Prop(prop) => {
269                let member = prop.babelify(ctx);
270                match member {
271                    ObjectMember::Method(m) => ObjectExprProp::Method(m),
272                    ObjectMember::Prop(p) => ObjectExprProp::Prop(p),
273                }
274            }
275            #[cfg(swc_ast_unknown)]
276            _ => panic!("unable to access unknown nodes"),
277        }
278    }
279}
280
281impl Babelify for SpreadElement {
282    type Output = BabelSpreadElement;
283
284    fn babelify(self, ctx: &Context) -> Self::Output {
285        BabelSpreadElement {
286            base: ctx.base(self.span()),
287            argument: Box::alloc().init(self.expr.babelify(ctx).into()),
288        }
289    }
290}
291
292impl Babelify for UnaryExpr {
293    type Output = UnaryExpression;
294
295    fn babelify(self, ctx: &Context) -> Self::Output {
296        UnaryExpression {
297            base: ctx.base(self.span),
298            operator: self.op.babelify(ctx),
299            argument: Box::alloc().init(self.arg.babelify(ctx).into()),
300            prefix: true,
301        }
302    }
303}
304
305impl Babelify for UpdateExpr {
306    type Output = UpdateExpression;
307
308    fn babelify(self, ctx: &Context) -> Self::Output {
309        UpdateExpression {
310            base: ctx.base(self.span),
311            operator: self.op.babelify(ctx),
312            prefix: self.prefix,
313            argument: Box::alloc().init(self.arg.babelify(ctx).into()),
314        }
315    }
316}
317
318#[derive(Debug, Clone, Serialize, Deserialize)]
319pub enum BinaryOrLogicalExpr {
320    Binary(BinaryExpression),
321    Logical(LogicalExpression),
322}
323
324impl Babelify for BinExpr {
325    type Output = BinaryOrLogicalExpr;
326
327    fn babelify(self, ctx: &Context) -> Self::Output {
328        match self.op {
329            BinaryOp::LogicalOr | BinaryOp::LogicalAnd | BinaryOp::NullishCoalescing => {
330                BinaryOrLogicalExpr::Logical(LogicalExpression {
331                    base: ctx.base(self.span),
332                    operator: self.op.babelify(ctx).into(),
333                    left: Box::alloc().init(self.left.babelify(ctx).into()),
334                    right: Box::alloc().init(self.right.babelify(ctx).into()),
335                })
336            }
337            _ => BinaryOrLogicalExpr::Binary(BinaryExpression {
338                base: ctx.base(self.span),
339                operator: self.op.babelify(ctx).into(),
340                left: Box::alloc().init(self.left.babelify(ctx).into()),
341                right: Box::alloc().init(self.right.babelify(ctx).into()),
342            }),
343        }
344
345        // BinaryExpression {
346        //     base: ctx.base(self.span),
347        //     operator: self.op.babelify(ctx).into(),
348        //     left: Box::alloc().init(self.left.babelify(ctx).into()),
349        //     right: Box::alloc().init(self.right.babelify(ctx).into()),
350        // }
351    }
352}
353
354impl Babelify for FnExpr {
355    type Output = FunctionExpression;
356
357    fn babelify(self, ctx: &Context) -> Self::Output {
358        FunctionExpression {
359            id: self.ident.map(|id| id.babelify(ctx)),
360            ..self.function.babelify(ctx)
361        }
362    }
363}
364
365impl Babelify for ClassExpr {
366    type Output = ClassExpression;
367
368    fn babelify(self, ctx: &Context) -> Self::Output {
369        ClassExpression {
370            id: self.ident.map(|id| id.babelify(ctx)),
371            ..self.class.babelify(ctx)
372        }
373    }
374}
375
376impl Babelify for AssignExpr {
377    type Output = AssignmentExpression;
378
379    fn babelify(self, ctx: &Context) -> Self::Output {
380        AssignmentExpression {
381            base: ctx.base(self.span),
382            operator: self.op.as_str().into(),
383            left: Box::alloc().init(self.left.babelify(ctx)),
384            right: Box::alloc().init(self.right.babelify(ctx).into()),
385        }
386    }
387}
388
389impl Babelify for MemberExpr {
390    type Output = MemberExpression;
391
392    fn babelify(self, ctx: &Context) -> Self::Output {
393        let computed = self.prop.is_computed();
394
395        MemberExpression {
396            base: ctx.base(self.span),
397            object: Box::alloc().init(self.obj.babelify(ctx).into()),
398            property: Box::alloc().init(self.prop.babelify(ctx)),
399            computed,
400            optional: Default::default(),
401        }
402    }
403}
404
405impl Babelify for MemberProp {
406    type Output = MemberExprProp;
407
408    fn babelify(self, ctx: &Context) -> Self::Output {
409        match self {
410            Self::Computed(c) => MemberExprProp::Expr(c.babelify(ctx).into()),
411            Self::Ident(i) => MemberExprProp::Id(i.babelify(ctx)),
412            Self::PrivateName(p) => MemberExprProp::PrivateName(p.babelify(ctx)),
413            #[cfg(swc_ast_unknown)]
414            _ => panic!("unable to access unknown nodes"),
415        }
416    }
417}
418
419impl Babelify for SuperPropExpr {
420    type Output = MemberExpression;
421
422    fn babelify(self, ctx: &Context) -> Self::Output {
423        let computed = self.prop.is_computed();
424
425        MemberExpression {
426            base: ctx.base(self.span),
427            object: Box::alloc().init(Expression::Super(self.obj.babelify(ctx))),
428            property: Box::alloc().init(self.prop.babelify(ctx)),
429            computed,
430            optional: Default::default(),
431        }
432    }
433}
434
435impl Babelify for SuperProp {
436    type Output = MemberExprProp;
437
438    fn babelify(self, ctx: &Context) -> Self::Output {
439        match self {
440            Self::Computed(c) => MemberExprProp::Expr(c.babelify(ctx).into()),
441            Self::Ident(i) => MemberExprProp::Id(i.babelify(ctx)),
442            #[cfg(swc_ast_unknown)]
443            _ => panic!("unable to access unknown nodes"),
444        }
445    }
446}
447
448impl Babelify for CondExpr {
449    type Output = ConditionalExpression;
450
451    fn babelify(self, ctx: &Context) -> Self::Output {
452        ConditionalExpression {
453            base: ctx.base(self.span),
454            test: Box::alloc().init(self.test.babelify(ctx).into()),
455            consequent: Box::alloc().init(self.cons.babelify(ctx).into()),
456            alternate: Box::alloc().init(self.alt.babelify(ctx).into()),
457        }
458    }
459}
460
461impl Babelify for CallExpr {
462    type Output = CallExpression;
463
464    fn babelify(self, ctx: &Context) -> Self::Output {
465        CallExpression {
466            base: ctx.base(self.span),
467            callee: Box::alloc().init(self.callee.babelify(ctx).into()),
468            arguments: self
469                .args
470                .into_iter()
471                .map(|arg| arg.babelify(ctx).into())
472                .collect(),
473            type_parameters: self.type_args.map(|t| t.babelify(ctx)),
474            type_arguments: Default::default(),
475            optional: Default::default(),
476        }
477    }
478}
479
480impl Babelify for NewExpr {
481    type Output = NewExpression;
482
483    fn babelify(self, ctx: &Context) -> Self::Output {
484        NewExpression {
485            base: ctx.base(self.span),
486            callee: BabelCallee::Expr(Box::alloc().init(self.callee.babelify(ctx).into())),
487            arguments: match self.args {
488                Some(args) => args
489                    .into_iter()
490                    .map(|arg| arg.babelify(ctx).into())
491                    .collect(),
492                None => Vec::new(),
493            },
494            type_parameters: self.type_args.map(|t| t.babelify(ctx)),
495            type_arguments: Default::default(),
496            optional: Default::default(),
497        }
498    }
499}
500
501impl Babelify for SeqExpr {
502    type Output = SequenceExpression;
503
504    fn babelify(self, ctx: &Context) -> Self::Output {
505        SequenceExpression {
506            base: ctx.base(self.span),
507            expressions: self
508                .exprs
509                .into_iter()
510                .map(|expr| Box::alloc().init(expr.babelify(ctx).into()))
511                .collect(),
512        }
513    }
514}
515
516impl Babelify for ArrowExpr {
517    type Output = ArrowFunctionExpression;
518
519    fn babelify(self, ctx: &Context) -> Self::Output {
520        ArrowFunctionExpression {
521            base: ctx.base(self.span),
522            params: self
523                .params
524                .into_iter()
525                .map(|p| p.babelify(ctx).into())
526                .collect(),
527            body: Box::alloc().init(self.body.babelify(ctx)),
528            is_async: self.is_async,
529            expression: match Flavor::current() {
530                Flavor::Babel => Default::default(),
531                Flavor::Acorn { .. } => true,
532            },
533            generator: self.is_generator,
534            return_type: self
535                .return_type
536                .map(|t| Box::alloc().init(t.babelify(ctx).into())),
537            type_parameters: self.type_params.map(|t| t.babelify(ctx).into()),
538        }
539    }
540}
541
542impl Babelify for YieldExpr {
543    type Output = YieldExpression;
544
545    fn babelify(self, ctx: &Context) -> Self::Output {
546        YieldExpression {
547            base: ctx.base(self.span),
548            argument: self.arg.map(|a| Box::alloc().init(a.babelify(ctx).into())),
549            delegate: self.delegate,
550        }
551    }
552}
553
554impl Babelify for MetaPropExpr {
555    type Output = MetaProperty;
556
557    fn babelify(self, ctx: &Context) -> Self::Output {
558        let (meta, property) = match self.kind {
559            MetaPropKind::ImportMeta => (
560                Ident {
561                    span: Span {
562                        hi: self.span.hi - BytePos(5),
563                        ..self.span
564                    },
565                    sym: atom!("import"),
566                    ..Default::default()
567                }
568                .babelify(ctx),
569                Ident {
570                    span: Span {
571                        lo: self.span.lo + BytePos(7),
572                        ..self.span
573                    },
574                    sym: atom!("meta"),
575                    ..Default::default()
576                }
577                .babelify(ctx),
578            ),
579            MetaPropKind::NewTarget => (
580                Ident {
581                    span: Span {
582                        hi: self.span.hi - BytePos(7),
583                        ..self.span
584                    },
585                    sym: atom!("new"),
586                    ..Default::default()
587                }
588                .babelify(ctx),
589                Ident {
590                    span: Span {
591                        hi: self.span.hi + BytePos(4),
592                        ..self.span
593                    },
594                    sym: atom!("target"),
595                    ..Default::default()
596                }
597                .babelify(ctx),
598            ),
599            #[cfg(swc_ast_unknown)]
600            _ => panic!("unable to access unknown nodes"),
601        };
602        MetaProperty {
603            base: ctx.base(self.span()),
604            meta,
605            property,
606        }
607    }
608}
609
610impl Babelify for AwaitExpr {
611    type Output = AwaitExpression;
612
613    fn babelify(self, ctx: &Context) -> Self::Output {
614        AwaitExpression {
615            base: ctx.base(self.span),
616            argument: Box::alloc().init(self.arg.babelify(ctx).into()),
617        }
618    }
619}
620
621impl Babelify for Tpl {
622    type Output = TemplateLiteral;
623
624    fn babelify(self, ctx: &Context) -> Self::Output {
625        TemplateLiteral {
626            base: ctx.base(self.span),
627            expressions: self
628                .exprs
629                .into_iter()
630                .map(|e| TemplateLiteralExpr::Expr(Box::alloc().init(e.babelify(ctx).into())))
631                .collect(),
632            quasis: self.quasis.babelify(ctx),
633        }
634    }
635}
636
637impl Babelify for TaggedTpl {
638    type Output = TaggedTemplateExpression;
639
640    fn babelify(self, ctx: &Context) -> Self::Output {
641        TaggedTemplateExpression {
642            base: ctx.base(self.span),
643            tag: Box::alloc().init(self.tag.babelify(ctx).into()),
644            quasi: self.tpl.babelify(ctx),
645            type_parameters: self
646                .type_params
647                .map(|t| TaggedTemplateExprTypeParams::TS(t.babelify(ctx))),
648        }
649    }
650}
651
652impl Babelify for TplElement {
653    type Output = TemplateElement;
654
655    fn babelify(self, ctx: &Context) -> Self::Output {
656        TemplateElement {
657            base: ctx.base(self.span),
658            tail: self.tail,
659            value: TemplateElVal {
660                raw: self.raw,
661                cooked: self.cooked,
662            },
663        }
664    }
665}
666
667impl Babelify for ParenExpr {
668    type Output = ParenthesizedExpression;
669
670    fn babelify(self, ctx: &Context) -> Self::Output {
671        ParenthesizedExpression {
672            base: ctx.base(self.span),
673            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
674        }
675    }
676}
677
678impl Babelify for Callee {
679    type Output = Expression;
680
681    fn babelify(self, ctx: &Context) -> Self::Output {
682        match self {
683            Callee::Expr(e) => e.babelify(ctx).into(),
684            Callee::Super(s) => Expression::Super(s.babelify(ctx)),
685            Callee::Import(i) => Expression::Import(i.babelify(ctx)),
686            #[cfg(swc_ast_unknown)]
687            _ => panic!("unable to access unknown nodes"),
688        }
689    }
690}
691
692impl Babelify for Super {
693    type Output = BabelSuper;
694
695    fn babelify(self, ctx: &Context) -> Self::Output {
696        BabelSuper {
697            base: ctx.base(self.span),
698        }
699    }
700}
701
702impl Babelify for Import {
703    type Output = BabelImport;
704
705    fn babelify(self, ctx: &Context) -> Self::Output {
706        BabelImport {
707            base: ctx.base(self.span),
708        }
709    }
710}
711
712impl Babelify for ExprOrSpread {
713    type Output = ArrayExprEl;
714
715    fn babelify(self, ctx: &Context) -> Self::Output {
716        match self.spread {
717            Some(_) => ArrayExprEl::Spread(BabelSpreadElement {
718                base: ctx.base(self.span()),
719                argument: Box::alloc().init(self.expr.babelify(ctx).into()),
720            }),
721            None => ArrayExprEl::Expr(Box::alloc().init(self.expr.babelify(ctx).into())),
722        }
723    }
724}
725
726impl Babelify for BlockStmtOrExpr {
727    type Output = ArrowFuncExprBody;
728
729    fn babelify(self, ctx: &Context) -> Self::Output {
730        match self {
731            BlockStmtOrExpr::BlockStmt(b) => ArrowFuncExprBody::Block(b.babelify(ctx)),
732            BlockStmtOrExpr::Expr(e) => {
733                ArrowFuncExprBody::Expr(Box::alloc().init(e.babelify(ctx).into()))
734            }
735            #[cfg(swc_ast_unknown)]
736            _ => panic!("unable to access unknown nodes"),
737        }
738    }
739}
740
741impl Babelify for AssignTarget {
742    type Output = LVal;
743
744    fn babelify(self, ctx: &Context) -> Self::Output {
745        match self {
746            AssignTarget::Simple(s) => s.babelify(ctx),
747            AssignTarget::Pat(p) => p.babelify(ctx),
748            #[cfg(swc_ast_unknown)]
749            _ => panic!("unable to access unknown nodes"),
750        }
751    }
752}
753
754impl Babelify for SimpleAssignTarget {
755    type Output = LVal;
756
757    fn babelify(self, ctx: &Context) -> Self::Output {
758        match self {
759            SimpleAssignTarget::Ident(i) => LVal::Id(i.babelify(ctx)),
760            SimpleAssignTarget::Member(m) => LVal::MemberExpr(m.babelify(ctx)),
761            SimpleAssignTarget::SuperProp(s) => LVal::MemberExpr(s.babelify(ctx)),
762            _ => unreachable!(),
763        }
764    }
765}
766
767impl Babelify for AssignTargetPat {
768    type Output = LVal;
769
770    fn babelify(self, ctx: &Context) -> Self::Output {
771        match self {
772            AssignTargetPat::Array(a) => LVal::ArrayPat(a.babelify(ctx)),
773            AssignTargetPat::Object(o) => LVal::ObjectPat(o.babelify(ctx)),
774            AssignTargetPat::Invalid(_) => todo!(),
775            #[cfg(swc_ast_unknown)]
776            _ => panic!("unable to access unknown nodes"),
777        }
778    }
779}
780
781// NOTE: OptChainExpr does not appear to have an official Babel AST node yet.
782
783// #[ast_node("OptionalChainingExpression")]
784// #[derive(Eq, Hash, EqIgnoreSpan)]
785// #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
786// pub struct OptChainExpr {
787//     pub span: Span,
788//     pub question_dot_token: Span,
789//     pub expr: Box<Expr>,
790// }
791//