swc_estree_compat/babelify/
stmt.rs

1use copyless::BoxHelper;
2use swc_ecma_ast::{
3    BlockStmt, BreakStmt, CatchClause, ContinueStmt, DebuggerStmt, Decl, DoWhileStmt, EmptyStmt,
4    ExprStmt, ForHead, ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt,
5    SwitchCase, SwitchStmt, ThrowStmt, TryStmt, VarDeclOrExpr, WhileStmt, WithStmt,
6};
7use swc_estree_ast::{
8    BlockStatement, BreakStatement, CatchClause as BabelCatchClause, ContinueStatement,
9    DebuggerStatement, DoWhileStatement, EmptyStatement, ExpressionStatement, ForInStatement,
10    ForOfStatement, ForStatement, ForStmtInit, ForStmtLeft, IfStatement, LabeledStatement,
11    ReturnStatement, Statement, SwitchCase as BabelSwitchCase, SwitchStatement, ThrowStatement,
12    TryStatement, WhileStatement, WithStatement,
13};
14
15use crate::babelify::{Babelify, Context};
16
17impl Babelify for BlockStmt {
18    type Output = BlockStatement;
19
20    fn babelify(self, ctx: &Context) -> Self::Output {
21        BlockStatement {
22            base: ctx.base(self.span),
23            body: self.stmts.babelify(ctx),
24            directives: Default::default(),
25        }
26    }
27}
28
29impl Babelify for Stmt {
30    type Output = Statement;
31
32    fn parallel(cnt: usize) -> bool {
33        cnt >= 16
34    }
35
36    fn babelify(self, ctx: &Context) -> Self::Output {
37        match self {
38            Stmt::Block(s) => Statement::Block(s.babelify(ctx)),
39            Stmt::Empty(s) => Statement::Empty(s.babelify(ctx)),
40            Stmt::Debugger(s) => Statement::Debugger(s.babelify(ctx)),
41            Stmt::With(s) => Statement::With(s.babelify(ctx)),
42            Stmt::Return(s) => Statement::Return(s.babelify(ctx)),
43            Stmt::Labeled(s) => Statement::Labeled(s.babelify(ctx)),
44            Stmt::Break(s) => Statement::Break(s.babelify(ctx)),
45            Stmt::Continue(s) => Statement::Continue(s.babelify(ctx)),
46            Stmt::If(s) => Statement::If(s.babelify(ctx)),
47            Stmt::Switch(s) => Statement::Switch(s.babelify(ctx)),
48            Stmt::Throw(s) => Statement::Throw(s.babelify(ctx)),
49            Stmt::Try(s) => Statement::Try(s.babelify(ctx)),
50            Stmt::While(s) => Statement::While(s.babelify(ctx)),
51            Stmt::DoWhile(s) => Statement::DoWhile(s.babelify(ctx)),
52            Stmt::For(s) => Statement::For(s.babelify(ctx)),
53            Stmt::ForIn(s) => Statement::ForIn(s.babelify(ctx)),
54            Stmt::ForOf(s) => Statement::ForOf(s.babelify(ctx)),
55            Stmt::Decl(decl) => match decl {
56                Decl::Class(d) => Statement::ClassDecl(d.babelify(ctx)),
57                Decl::Fn(d) => Statement::FuncDecl(d.babelify(ctx)),
58                Decl::Var(d) => Statement::VarDecl(d.babelify(ctx)),
59                Decl::Using(d) => Statement::UsingDecl(d.babelify(ctx)),
60                Decl::TsInterface(d) => Statement::TSInterfaceDecl(d.babelify(ctx)),
61                Decl::TsTypeAlias(d) => Statement::TSTypeAliasDecl(d.babelify(ctx)),
62                Decl::TsEnum(d) => Statement::TSEnumDecl(d.babelify(ctx)),
63                Decl::TsModule(d) => Statement::TSModuleDecl(d.babelify(ctx)),
64                #[cfg(swc_ast_unknown)]
65                _ => panic!("unable to access unknown nodes"),
66            },
67            Stmt::Expr(s) => Statement::Expr(s.babelify(ctx)),
68            #[cfg(swc_ast_unknown)]
69            _ => panic!("unable to access unknown nodes"),
70        }
71    }
72}
73
74impl Babelify for ExprStmt {
75    type Output = ExpressionStatement;
76
77    fn babelify(self, ctx: &Context) -> Self::Output {
78        ExpressionStatement {
79            base: ctx.base(self.span),
80            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
81        }
82    }
83}
84
85impl Babelify for EmptyStmt {
86    type Output = EmptyStatement;
87
88    fn babelify(self, ctx: &Context) -> Self::Output {
89        EmptyStatement {
90            base: ctx.base(self.span),
91        }
92    }
93}
94
95impl Babelify for DebuggerStmt {
96    type Output = DebuggerStatement;
97
98    fn babelify(self, ctx: &Context) -> Self::Output {
99        DebuggerStatement {
100            base: ctx.base(self.span),
101        }
102    }
103}
104
105impl Babelify for WithStmt {
106    type Output = WithStatement;
107
108    fn babelify(self, ctx: &Context) -> Self::Output {
109        WithStatement {
110            base: ctx.base(self.span),
111            object: Box::alloc().init(self.obj.babelify(ctx).into()),
112            body: Box::alloc().init(self.body.babelify(ctx)),
113        }
114    }
115}
116
117impl Babelify for ReturnStmt {
118    type Output = ReturnStatement;
119
120    fn babelify(self, ctx: &Context) -> Self::Output {
121        ReturnStatement {
122            base: ctx.base(self.span),
123            argument: self
124                .arg
125                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
126        }
127    }
128}
129
130impl Babelify for LabeledStmt {
131    type Output = LabeledStatement;
132
133    fn babelify(self, ctx: &Context) -> Self::Output {
134        LabeledStatement {
135            base: ctx.base(self.span),
136            label: self.label.babelify(ctx),
137            body: Box::alloc().init(self.body.babelify(ctx)),
138        }
139    }
140}
141
142impl Babelify for BreakStmt {
143    type Output = BreakStatement;
144
145    fn babelify(self, ctx: &Context) -> Self::Output {
146        BreakStatement {
147            base: ctx.base(self.span),
148            label: self.label.map(|id| id.babelify(ctx)),
149        }
150    }
151}
152
153impl Babelify for ContinueStmt {
154    type Output = ContinueStatement;
155
156    fn babelify(self, ctx: &Context) -> Self::Output {
157        ContinueStatement {
158            base: ctx.base(self.span),
159            label: self.label.map(|id| id.babelify(ctx)),
160        }
161    }
162}
163
164impl Babelify for IfStmt {
165    type Output = IfStatement;
166
167    fn babelify(self, ctx: &Context) -> Self::Output {
168        IfStatement {
169            base: ctx.base(self.span),
170            test: Box::alloc().init(self.test.babelify(ctx).into()),
171            consequent: Box::alloc().init(self.cons.babelify(ctx)),
172            alternate: self.alt.map(|a| Box::alloc().init(a.babelify(ctx))),
173        }
174    }
175}
176
177impl Babelify for SwitchStmt {
178    type Output = SwitchStatement;
179
180    fn babelify(self, ctx: &Context) -> Self::Output {
181        SwitchStatement {
182            base: ctx.base(self.span),
183            discriminant: Box::alloc().init(self.discriminant.babelify(ctx).into()),
184            cases: self.cases.babelify(ctx),
185        }
186    }
187}
188
189impl Babelify for ThrowStmt {
190    type Output = ThrowStatement;
191
192    fn babelify(self, ctx: &Context) -> Self::Output {
193        ThrowStatement {
194            base: ctx.base(self.span),
195            argument: Box::alloc().init(self.arg.babelify(ctx).into()),
196        }
197    }
198}
199
200impl Babelify for TryStmt {
201    type Output = TryStatement;
202
203    fn babelify(self, ctx: &Context) -> Self::Output {
204        TryStatement {
205            base: ctx.base(self.span),
206            block: self.block.babelify(ctx),
207            handler: self.handler.map(|clause| clause.babelify(ctx)),
208            finalizer: self.finalizer.map(|stmt| stmt.babelify(ctx)),
209        }
210    }
211}
212
213impl Babelify for WhileStmt {
214    type Output = WhileStatement;
215
216    fn babelify(self, ctx: &Context) -> Self::Output {
217        WhileStatement {
218            base: ctx.base(self.span),
219            test: Box::alloc().init(self.test.babelify(ctx).into()),
220            body: Box::alloc().init(self.body.babelify(ctx)),
221        }
222    }
223}
224
225impl Babelify for DoWhileStmt {
226    type Output = DoWhileStatement;
227
228    fn babelify(self, ctx: &Context) -> Self::Output {
229        DoWhileStatement {
230            base: ctx.base(self.span),
231            test: Box::alloc().init(self.test.babelify(ctx).into()),
232            body: Box::alloc().init(self.body.babelify(ctx)),
233        }
234    }
235}
236
237impl Babelify for ForStmt {
238    type Output = ForStatement;
239
240    fn babelify(self, ctx: &Context) -> Self::Output {
241        ForStatement {
242            base: ctx.base(self.span),
243            init: self.init.map(|i| i.babelify(ctx)),
244            test: self
245                .test
246                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
247            update: self
248                .update
249                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
250            body: Box::alloc().init(self.body.babelify(ctx)),
251        }
252    }
253}
254
255impl Babelify for ForInStmt {
256    type Output = ForInStatement;
257
258    fn babelify(self, ctx: &Context) -> Self::Output {
259        ForInStatement {
260            base: ctx.base(self.span),
261            left: self.left.babelify(ctx),
262            right: Box::alloc().init(self.right.babelify(ctx).into()),
263            body: Box::alloc().init(self.body.babelify(ctx)),
264        }
265    }
266}
267
268impl Babelify for ForOfStmt {
269    type Output = ForOfStatement;
270
271    fn babelify(self, ctx: &Context) -> Self::Output {
272        ForOfStatement {
273            base: ctx.base(self.span),
274            left: self.left.babelify(ctx),
275            right: Box::alloc().init(self.right.babelify(ctx).into()),
276            body: Box::alloc().init(self.body.babelify(ctx)),
277            // await_token not yet implemented
278        }
279    }
280}
281
282impl Babelify for SwitchCase {
283    type Output = BabelSwitchCase;
284
285    fn babelify(self, ctx: &Context) -> Self::Output {
286        BabelSwitchCase {
287            base: ctx.base(self.span),
288            test: self
289                .test
290                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
291            consequent: self.cons.babelify(ctx),
292        }
293    }
294}
295
296impl Babelify for CatchClause {
297    type Output = BabelCatchClause;
298
299    fn babelify(self, ctx: &Context) -> Self::Output {
300        BabelCatchClause {
301            base: ctx.base(self.span),
302            param: self.param.map(|p| p.babelify(ctx).into()),
303            body: self.body.babelify(ctx),
304        }
305    }
306}
307
308impl Babelify for ForHead {
309    type Output = ForStmtLeft;
310
311    fn babelify(self, ctx: &Context) -> Self::Output {
312        match self {
313            ForHead::VarDecl(v) => ForStmtLeft::VarDecl(v.babelify(ctx)),
314            ForHead::Pat(p) => ForStmtLeft::LVal(p.babelify(ctx).into()),
315            _ => {
316                todo!("ForHead::UsingDecl({self:?})")
317            }
318        }
319    }
320}
321
322impl Babelify for VarDeclOrExpr {
323    type Output = ForStmtInit;
324
325    fn babelify(self, ctx: &Context) -> Self::Output {
326        match self {
327            VarDeclOrExpr::VarDecl(v) => ForStmtInit::VarDecl(v.babelify(ctx)),
328            VarDeclOrExpr::Expr(e) => ForStmtInit::Expr(Box::alloc().init(e.babelify(ctx).into())),
329            #[cfg(swc_ast_unknown)]
330            _ => panic!("unable to access unknown nodes"),
331        }
332    }
333}