swc_estree_ast/
flavor.rs

1better_scoped_tls::scoped_tls!(static FLAVOR: Flavor);
2
3#[repr(u8)]
4#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default)]
5pub enum Flavor {
6    #[default]
7    Babel,
8    Acorn {
9        extra_comments: bool,
10    },
11}
12
13impl Flavor {
14    pub fn with<F, Ret>(self, op: F) -> Ret
15    where
16        F: FnOnce() -> Ret,
17    {
18        FLAVOR.set(&self, op)
19    }
20
21    pub fn current() -> Self {
22        if FLAVOR.is_set() {
23            FLAVOR.with(|v| *v)
24        } else {
25            Flavor::default()
26        }
27    }
28
29    pub fn emit_loc(&self) -> bool {
30        true
31    }
32
33    pub(crate) fn skip_range(_: &Option<[u32; 2]>) -> bool {
34        matches!(Self::current(), Flavor::Babel)
35    }
36
37    pub(crate) fn skip_empty<T>(v: &T) -> bool
38    where
39        T: IsEmpty,
40    {
41        matches!(Self::current(), Flavor::Acorn { .. }) && v.is_empty()
42    }
43
44    pub(crate) fn skip_none<T>(v: &Option<T>) -> bool {
45        matches!(Self::current(), Flavor::Acorn { .. }) && v.is_none()
46    }
47
48    pub(crate) fn skip_none_and_false(v: &Option<bool>) -> bool {
49        matches!(Self::current(), Flavor::Acorn { .. }) && matches!(v, None | Some(false))
50    }
51}
52
53pub(crate) trait IsEmpty {
54    fn is_empty(&self) -> bool;
55}
56
57impl IsEmpty for String {
58    fn is_empty(&self) -> bool {
59        self.is_empty()
60    }
61}
62
63impl<T> IsEmpty for Vec<T> {
64    fn is_empty(&self) -> bool {
65        self.is_empty()
66    }
67}
68
69impl<T> IsEmpty for Option<T>
70where
71    T: IsEmpty,
72{
73    fn is_empty(&self) -> bool {
74        match self {
75            Some(v) => v.is_empty(),
76            None => true,
77        }
78    }
79}