swc_ecma_ast/
operators.rs

1use string_enum::StringEnum;
2use swc_common::EqIgnoreSpan;
3
4#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan, Default)]
5#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
6#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
7#[cfg_attr(
8    any(feature = "rkyv-impl"),
9    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
10)]
11#[cfg_attr(feature = "rkyv-impl", derive(bytecheck::CheckBytes))]
12#[cfg_attr(feature = "rkyv-impl", repr(u32))]
13#[cfg_attr(swc_ast_unknown, non_exhaustive)]
14pub enum BinaryOp {
15    /// `==`
16    #[default]
17    EqEq,
18    /// `!=`
19    NotEq,
20    /// `===`
21    EqEqEq,
22    /// `!==`
23    NotEqEq,
24    /// `<`
25    Lt,
26    /// `<=`
27    LtEq,
28    /// `>`
29    Gt,
30    /// `>=`
31    GtEq,
32    /// `<<`
33    LShift,
34    /// `>>`
35    RShift,
36    /// `>>>`
37    ZeroFillRShift,
38
39    /// `+`
40    Add,
41    /// `-`
42    Sub,
43    /// `*`
44    Mul,
45    /// `/`
46    Div,
47    /// `%`
48    Mod,
49
50    /// `|`
51    BitOr,
52    /// `^`
53    BitXor,
54    /// `&`
55    BitAnd,
56
57    /// `||`
58    LogicalOr,
59
60    /// `&&`
61    LogicalAnd,
62
63    /// `in`
64    In,
65    /// `instanceof`
66    InstanceOf,
67
68    /// `**`
69    Exp,
70
71    /// `??`
72    NullishCoalescing,
73}
74
75impl BinaryOp {
76    pub fn precedence(self) -> u8 {
77        match self {
78            BinaryOp::EqEq => 6,
79            BinaryOp::NotEq => 6,
80            BinaryOp::EqEqEq => 6,
81            BinaryOp::NotEqEq => 6,
82            BinaryOp::Lt => 7,
83            BinaryOp::LtEq => 7,
84            BinaryOp::Gt => 7,
85            BinaryOp::GtEq => 7,
86            BinaryOp::LShift => 8,
87            BinaryOp::RShift => 8,
88            BinaryOp::ZeroFillRShift => 8,
89
90            BinaryOp::Add => 9,
91            BinaryOp::Sub => 9,
92            BinaryOp::Mul => 10,
93            BinaryOp::Div => 10,
94            BinaryOp::Mod => 10,
95
96            BinaryOp::BitOr => 3,
97            BinaryOp::BitXor => 4,
98
99            BinaryOp::BitAnd => 5,
100
101            BinaryOp::LogicalOr => 1,
102
103            BinaryOp::LogicalAnd => 2,
104            BinaryOp::In => 7,
105            BinaryOp::InstanceOf => 7,
106
107            BinaryOp::Exp => 11,
108
109            BinaryOp::NullishCoalescing => 1,
110        }
111    }
112
113    pub fn may_short_circuit(&self) -> bool {
114        matches!(self, op!("??") | op!("||") | op!("&&"))
115    }
116}
117
118#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan, Default)]
119#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
120#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
121#[cfg_attr(
122    any(feature = "rkyv-impl"),
123    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
124)]
125#[cfg_attr(feature = "rkyv-impl", derive(bytecheck::CheckBytes))]
126#[cfg_attr(feature = "rkyv-impl", repr(u32))]
127#[cfg_attr(swc_ast_unknown, non_exhaustive)]
128pub enum AssignOp {
129    /// `=`
130    #[default]
131    Assign,
132    /// `+=`
133    AddAssign,
134    /// `-=`
135    SubAssign,
136    /// `*=`
137    MulAssign,
138    /// `/=`
139    DivAssign,
140    /// `%=`
141    ModAssign,
142    /// `<<=`
143    LShiftAssign,
144    /// `>>=`
145    RShiftAssign,
146    /// `>>>=`
147    ZeroFillRShiftAssign,
148    /// `|=`
149    BitOrAssign,
150    /// `^=`
151    BitXorAssign,
152    /// `&=`
153    BitAndAssign,
154
155    /// `**=`
156    ExpAssign,
157
158    /// `&&=`
159    AndAssign,
160
161    /// `||=`
162    OrAssign,
163
164    /// `??=`
165    NullishAssign,
166}
167
168impl AssignOp {
169    pub fn to_update(self) -> Option<BinaryOp> {
170        match self {
171            op!("=") => None,
172
173            op!("+=") => Some(op!(bin, "+")),
174            op!("-=") => Some(op!(bin, "-")),
175            op!("*=") => Some(op!("*")),
176            op!("/=") => Some(op!("/")),
177            op!("%=") => Some(op!("%")),
178            op!("<<=") => Some(op!("<<")),
179            op!(">>=") => Some(op!(">>")),
180            op!(">>>=") => Some(op!(">>>")),
181            op!("|=") => Some(op!("|")),
182            op!("&=") => Some(op!("&")),
183            op!("^=") => Some(op!("^")),
184            op!("**=") => Some(op!("**")),
185            op!("&&=") => Some(op!("&&")),
186            op!("||=") => Some(op!("||")),
187            op!("??=") => Some(op!("??")),
188        }
189    }
190
191    pub fn may_short_circuit(&self) -> bool {
192        matches!(self, op!("??=") | op!("||=") | op!("&&="))
193    }
194}
195
196#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan, Default)]
197#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
198#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
199#[cfg_attr(
200    any(feature = "rkyv-impl"),
201    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
202)]
203#[cfg_attr(feature = "rkyv-impl", derive(bytecheck::CheckBytes))]
204#[cfg_attr(feature = "rkyv-impl", repr(u32))]
205#[cfg_attr(swc_ast_unknown, non_exhaustive)]
206pub enum UpdateOp {
207    /// `++`
208    #[default]
209    PlusPlus,
210    /// `--`
211    MinusMinus,
212}
213
214#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan, Default)]
215#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
216#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
217#[cfg_attr(
218    any(feature = "rkyv-impl"),
219    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
220)]
221#[cfg_attr(feature = "rkyv-impl", derive(bytecheck::CheckBytes))]
222#[cfg_attr(feature = "rkyv-impl", repr(u32))]
223#[cfg_attr(swc_ast_unknown, non_exhaustive)]
224pub enum UnaryOp {
225    /// `-`
226    Minus,
227    /// `+`
228    Plus,
229    /// `!`
230    Bang,
231    /// `~`
232    Tilde,
233    /// `typeof`
234    TypeOf,
235    /// `void`
236    #[default]
237    Void,
238    /// `delete`
239    Delete,
240}