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            },
65            Stmt::Expr(s) => Statement::Expr(s.babelify(ctx)),
66        }
67    }
68}
69
70impl Babelify for ExprStmt {
71    type Output = ExpressionStatement;
72
73    fn babelify(self, ctx: &Context) -> Self::Output {
74        ExpressionStatement {
75            base: ctx.base(self.span),
76            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
77        }
78    }
79}
80
81impl Babelify for EmptyStmt {
82    type Output = EmptyStatement;
83
84    fn babelify(self, ctx: &Context) -> Self::Output {
85        EmptyStatement {
86            base: ctx.base(self.span),
87        }
88    }
89}
90
91impl Babelify for DebuggerStmt {
92    type Output = DebuggerStatement;
93
94    fn babelify(self, ctx: &Context) -> Self::Output {
95        DebuggerStatement {
96            base: ctx.base(self.span),
97        }
98    }
99}
100
101impl Babelify for WithStmt {
102    type Output = WithStatement;
103
104    fn babelify(self, ctx: &Context) -> Self::Output {
105        WithStatement {
106            base: ctx.base(self.span),
107            object: Box::alloc().init(self.obj.babelify(ctx).into()),
108            body: Box::alloc().init(self.body.babelify(ctx)),
109        }
110    }
111}
112
113impl Babelify for ReturnStmt {
114    type Output = ReturnStatement;
115
116    fn babelify(self, ctx: &Context) -> Self::Output {
117        ReturnStatement {
118            base: ctx.base(self.span),
119            argument: self
120                .arg
121                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
122        }
123    }
124}
125
126impl Babelify for LabeledStmt {
127    type Output = LabeledStatement;
128
129    fn babelify(self, ctx: &Context) -> Self::Output {
130        LabeledStatement {
131            base: ctx.base(self.span),
132            label: self.label.babelify(ctx),
133            body: Box::alloc().init(self.body.babelify(ctx)),
134        }
135    }
136}
137
138impl Babelify for BreakStmt {
139    type Output = BreakStatement;
140
141    fn babelify(self, ctx: &Context) -> Self::Output {
142        BreakStatement {
143            base: ctx.base(self.span),
144            label: self.label.map(|id| id.babelify(ctx)),
145        }
146    }
147}
148
149impl Babelify for ContinueStmt {
150    type Output = ContinueStatement;
151
152    fn babelify(self, ctx: &Context) -> Self::Output {
153        ContinueStatement {
154            base: ctx.base(self.span),
155            label: self.label.map(|id| id.babelify(ctx)),
156        }
157    }
158}
159
160impl Babelify for IfStmt {
161    type Output = IfStatement;
162
163    fn babelify(self, ctx: &Context) -> Self::Output {
164        IfStatement {
165            base: ctx.base(self.span),
166            test: Box::alloc().init(self.test.babelify(ctx).into()),
167            consequent: Box::alloc().init(self.cons.babelify(ctx)),
168            alternate: self.alt.map(|a| Box::alloc().init(a.babelify(ctx))),
169        }
170    }
171}
172
173impl Babelify for SwitchStmt {
174    type Output = SwitchStatement;
175
176    fn babelify(self, ctx: &Context) -> Self::Output {
177        SwitchStatement {
178            base: ctx.base(self.span),
179            discriminant: Box::alloc().init(self.discriminant.babelify(ctx).into()),
180            cases: self.cases.babelify(ctx),
181        }
182    }
183}
184
185impl Babelify for ThrowStmt {
186    type Output = ThrowStatement;
187
188    fn babelify(self, ctx: &Context) -> Self::Output {
189        ThrowStatement {
190            base: ctx.base(self.span),
191            argument: Box::alloc().init(self.arg.babelify(ctx).into()),
192        }
193    }
194}
195
196impl Babelify for TryStmt {
197    type Output = TryStatement;
198
199    fn babelify(self, ctx: &Context) -> Self::Output {
200        TryStatement {
201            base: ctx.base(self.span),
202            block: self.block.babelify(ctx),
203            handler: self.handler.map(|clause| clause.babelify(ctx)),
204            finalizer: self.finalizer.map(|stmt| stmt.babelify(ctx)),
205        }
206    }
207}
208
209impl Babelify for WhileStmt {
210    type Output = WhileStatement;
211
212    fn babelify(self, ctx: &Context) -> Self::Output {
213        WhileStatement {
214            base: ctx.base(self.span),
215            test: Box::alloc().init(self.test.babelify(ctx).into()),
216            body: Box::alloc().init(self.body.babelify(ctx)),
217        }
218    }
219}
220
221impl Babelify for DoWhileStmt {
222    type Output = DoWhileStatement;
223
224    fn babelify(self, ctx: &Context) -> Self::Output {
225        DoWhileStatement {
226            base: ctx.base(self.span),
227            test: Box::alloc().init(self.test.babelify(ctx).into()),
228            body: Box::alloc().init(self.body.babelify(ctx)),
229        }
230    }
231}
232
233impl Babelify for ForStmt {
234    type Output = ForStatement;
235
236    fn babelify(self, ctx: &Context) -> Self::Output {
237        ForStatement {
238            base: ctx.base(self.span),
239            init: self.init.map(|i| i.babelify(ctx)),
240            test: self
241                .test
242                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
243            update: self
244                .update
245                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
246            body: Box::alloc().init(self.body.babelify(ctx)),
247        }
248    }
249}
250
251impl Babelify for ForInStmt {
252    type Output = ForInStatement;
253
254    fn babelify(self, ctx: &Context) -> Self::Output {
255        ForInStatement {
256            base: ctx.base(self.span),
257            left: self.left.babelify(ctx),
258            right: Box::alloc().init(self.right.babelify(ctx).into()),
259            body: Box::alloc().init(self.body.babelify(ctx)),
260        }
261    }
262}
263
264impl Babelify for ForOfStmt {
265    type Output = ForOfStatement;
266
267    fn babelify(self, ctx: &Context) -> Self::Output {
268        ForOfStatement {
269            base: ctx.base(self.span),
270            left: self.left.babelify(ctx),
271            right: Box::alloc().init(self.right.babelify(ctx).into()),
272            body: Box::alloc().init(self.body.babelify(ctx)),
273            // await_token not yet implemented
274        }
275    }
276}
277
278impl Babelify for SwitchCase {
279    type Output = BabelSwitchCase;
280
281    fn babelify(self, ctx: &Context) -> Self::Output {
282        BabelSwitchCase {
283            base: ctx.base(self.span),
284            test: self
285                .test
286                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
287            consequent: self.cons.babelify(ctx),
288        }
289    }
290}
291
292impl Babelify for CatchClause {
293    type Output = BabelCatchClause;
294
295    fn babelify(self, ctx: &Context) -> Self::Output {
296        BabelCatchClause {
297            base: ctx.base(self.span),
298            param: self.param.map(|p| p.babelify(ctx).into()),
299            body: self.body.babelify(ctx),
300        }
301    }
302}
303
304impl Babelify for ForHead {
305    type Output = ForStmtLeft;
306
307    fn babelify(self, ctx: &Context) -> Self::Output {
308        match self {
309            ForHead::VarDecl(v) => ForStmtLeft::VarDecl(v.babelify(ctx)),
310            ForHead::Pat(p) => ForStmtLeft::LVal(p.babelify(ctx).into()),
311            _ => {
312                todo!("ForHead::UsingDecl({self:?})")
313            }
314        }
315    }
316}
317
318impl Babelify for VarDeclOrExpr {
319    type Output = ForStmtInit;
320
321    fn babelify(self, ctx: &Context) -> Self::Output {
322        match self {
323            VarDeclOrExpr::VarDecl(v) => ForStmtInit::VarDecl(v.babelify(ctx)),
324            VarDeclOrExpr::Expr(e) => ForStmtInit::Expr(Box::alloc().init(e.babelify(ctx).into())),
325        }
326    }
327}