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 }
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}