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(
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    /// `==`
20    #[default]
21    EqEq,
22    /// `!=`
23    NotEq,
24    /// `===`
25    EqEqEq,
26    /// `!==`
27    NotEqEq,
28    /// `<`
29    Lt,
30    /// `<=`
31    LtEq,
32    /// `>`
33    Gt,
34    /// `>=`
35    GtEq,
36    /// `<<`
37    LShift,
38    /// `>>`
39    RShift,
40    /// `>>>`
41    ZeroFillRShift,
42
43    /// `+`
44    Add,
45    /// `-`
46    Sub,
47    /// `*`
48    Mul,
49    /// `/`
50    Div,
51    /// `%`
52    Mod,
53
54    /// `|`
55    BitOr,
56    /// `^`
57    BitXor,
58    /// `&`
59    BitAnd,
60
61    /// `||`
62    LogicalOr,
63
64    /// `&&`
65    LogicalAnd,
66
67    /// `in`
68    In,
69    /// `instanceof`
70    InstanceOf,
71
72    /// `**`
73    Exp,
74
75    /// `??`
76    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    /// `=`
138    #[default]
139    Assign,
140    /// `+=`
141    AddAssign,
142    /// `-=`
143    SubAssign,
144    /// `*=`
145    MulAssign,
146    /// `/=`
147    DivAssign,
148    /// `%=`
149    ModAssign,
150    /// `<<=`
151    LShiftAssign,
152    /// `>>=`
153    RShiftAssign,
154    /// `>>>=`
155    ZeroFillRShiftAssign,
156    /// `|=`
157    BitOrAssign,
158    /// `^=`
159    BitXorAssign,
160    /// `&=`
161    BitAndAssign,
162
163    /// `**=`
164    ExpAssign,
165
166    /// `&&=`
167    AndAssign,
168
169    /// `||=`
170    OrAssign,
171
172    /// `??=`
173    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    /// `++`
220    #[default]
221    PlusPlus,
222    /// `--`
223    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    /// `-`
242    Minus,
243    /// `+`
244    Plus,
245    /// `!`
246    Bang,
247    /// `~`
248    Tilde,
249    /// `typeof`
250    TypeOf,
251    /// `void`
252    #[default]
253    Void,
254    /// `delete`
255    Delete,
256}