swc_ecma_compat_es2019/
optional_catch_binding.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use swc_ecma_ast::*;
use swc_ecma_utils::private_ident;
use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith};
use swc_trace_macro::swc_trace;

struct OptionalCatchBinding;

pub fn optional_catch_binding() -> impl Pass {
    visit_mut_pass(OptionalCatchBinding)
}

#[swc_trace]
impl VisitMut for OptionalCatchBinding {
    noop_visit_mut_type!(fail);

    fn visit_mut_catch_clause(&mut self, cc: &mut CatchClause) {
        cc.visit_mut_children_with(self);

        if cc.param.is_some() {
            return;
        }
        cc.param = Some(private_ident!("e").into());
    }
}

#[cfg(test)]
mod tests {
    use swc_common::Mark;
    use swc_ecma_ast::Pass;
    use swc_ecma_transforms_base::resolver;
    use swc_ecma_transforms_testing::test;
    use swc_ecma_visit::visit_mut_pass;

    use crate::optional_catch_binding::OptionalCatchBinding;

    pub fn tr() -> impl Pass {
        (
            resolver(Mark::new(), Mark::new(), false),
            visit_mut_pass(OptionalCatchBinding),
        )
    }

    test!(
        ::swc_ecma_parser::Syntax::default(),
        |_| tr(),
        issue_411,
        "try {} catch {}"
    );

    test!(
        ::swc_ecma_parser::Syntax::default(),
        |_| tr(),
        catch_binding_name_collision_1,
        "try { throw new Error(); } catch { log(e); }"
    );

    test!(
        ::swc_ecma_parser::Syntax::default(),
        |_| tr(),
        catch_binding_name_collision_2,
        "var e; try {} catch { log(e); }"
    );
}