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