swc_ecma_compat_es2019/
optional_catch_binding.rs

1use swc_ecma_ast::*;
2use swc_ecma_utils::private_ident;
3use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith};
4use swc_trace_macro::swc_trace;
5
6struct OptionalCatchBinding;
7
8pub fn optional_catch_binding() -> impl Pass {
9    visit_mut_pass(OptionalCatchBinding)
10}
11
12#[swc_trace]
13impl VisitMut for OptionalCatchBinding {
14    noop_visit_mut_type!(fail);
15
16    fn visit_mut_catch_clause(&mut self, cc: &mut CatchClause) {
17        cc.visit_mut_children_with(self);
18
19        if cc.param.is_some() {
20            return;
21        }
22        cc.param = Some(private_ident!("e").into());
23    }
24}
25
26#[cfg(test)]
27mod tests {
28    use swc_common::Mark;
29    use swc_ecma_ast::Pass;
30    use swc_ecma_transforms_base::resolver;
31    use swc_ecma_transforms_testing::test;
32    use swc_ecma_visit::visit_mut_pass;
33
34    use crate::optional_catch_binding::OptionalCatchBinding;
35
36    pub fn tr() -> impl Pass {
37        (
38            resolver(Mark::new(), Mark::new(), false),
39            visit_mut_pass(OptionalCatchBinding),
40        )
41    }
42
43    test!(
44        ::swc_ecma_parser::Syntax::default(),
45        |_| tr(),
46        issue_411,
47        "try {} catch {}"
48    );
49
50    test!(
51        ::swc_ecma_parser::Syntax::default(),
52        |_| tr(),
53        catch_binding_name_collision_1,
54        "try { throw new Error(); } catch { log(e); }"
55    );
56
57    test!(
58        ::swc_ecma_parser::Syntax::default(),
59        |_| tr(),
60        catch_binding_name_collision_2,
61        "var e; try {} catch { log(e); }"
62    );
63}