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