swc_estree_compat/babelify/
operators.rs

1use serde::{Deserialize, Serialize};
2use swc_ecma_ast::{AssignOp, BinaryOp, UnaryOp, UpdateOp};
3use swc_estree_ast::{BinaryExprOp, LogicalExprOp, UnaryExprOp, UpdateExprOp};
4
5use crate::babelify::{Babelify, Context};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub enum BinaryOpOutput {
9    BinOp(BinaryExprOp),
10    LogicOp(LogicalExprOp),
11}
12
13impl From<BinaryOpOutput> for BinaryExprOp {
14    fn from(o: BinaryOpOutput) -> Self {
15        match o {
16            BinaryOpOutput::BinOp(op) => op,
17            BinaryOpOutput::LogicOp(_) => panic!(
18                "illegal conversion: Cannot convert {:?} to BinaryExprOp",
19                &o
20            ),
21        }
22    }
23}
24
25impl From<BinaryOpOutput> for LogicalExprOp {
26    fn from(o: BinaryOpOutput) -> Self {
27        match o {
28            BinaryOpOutput::LogicOp(op) => op,
29            BinaryOpOutput::BinOp(_) => panic!(
30                "illegal conversion: Cannot convert {:?} to LogicalExprOp",
31                &o
32            ),
33        }
34    }
35}
36
37impl Babelify for BinaryOp {
38    type Output = BinaryOpOutput;
39
40    fn babelify(self, _ctx: &Context) -> Self::Output {
41        match self {
42            BinaryOp::EqEq => BinaryOpOutput::BinOp(BinaryExprOp::Equal),
43            BinaryOp::NotEq => BinaryOpOutput::BinOp(BinaryExprOp::NotEqual),
44            BinaryOp::EqEqEq => BinaryOpOutput::BinOp(BinaryExprOp::StrictEqual),
45            BinaryOp::NotEqEq => BinaryOpOutput::BinOp(BinaryExprOp::StrictNotEqual),
46            BinaryOp::Lt => BinaryOpOutput::BinOp(BinaryExprOp::LessThan),
47            BinaryOp::LtEq => BinaryOpOutput::BinOp(BinaryExprOp::LessThanOrEqual),
48            BinaryOp::Gt => BinaryOpOutput::BinOp(BinaryExprOp::GreaterThan),
49            BinaryOp::GtEq => BinaryOpOutput::BinOp(BinaryExprOp::GreaterThanOrEqual),
50            BinaryOp::LShift => BinaryOpOutput::BinOp(BinaryExprOp::LeftShift),
51            BinaryOp::RShift => BinaryOpOutput::BinOp(BinaryExprOp::RightShift),
52            BinaryOp::ZeroFillRShift => BinaryOpOutput::BinOp(BinaryExprOp::UnsignedRightShift),
53            BinaryOp::Add => BinaryOpOutput::BinOp(BinaryExprOp::Addition),
54            BinaryOp::Sub => BinaryOpOutput::BinOp(BinaryExprOp::Subtraction),
55            BinaryOp::Mul => BinaryOpOutput::BinOp(BinaryExprOp::Multiplication),
56            BinaryOp::Div => BinaryOpOutput::BinOp(BinaryExprOp::Division),
57            BinaryOp::Mod => BinaryOpOutput::BinOp(BinaryExprOp::Remainder),
58            BinaryOp::BitOr => BinaryOpOutput::BinOp(BinaryExprOp::Or),
59            BinaryOp::BitXor => BinaryOpOutput::BinOp(BinaryExprOp::Xor),
60            BinaryOp::BitAnd => BinaryOpOutput::BinOp(BinaryExprOp::And),
61            BinaryOp::LogicalOr => BinaryOpOutput::LogicOp(LogicalExprOp::Or),
62            BinaryOp::LogicalAnd => BinaryOpOutput::LogicOp(LogicalExprOp::And),
63            BinaryOp::In => BinaryOpOutput::BinOp(BinaryExprOp::In),
64            BinaryOp::InstanceOf => BinaryOpOutput::BinOp(BinaryExprOp::Instanceof),
65            BinaryOp::Exp => BinaryOpOutput::BinOp(BinaryExprOp::Exponentiation),
66            BinaryOp::NullishCoalescing => BinaryOpOutput::LogicOp(LogicalExprOp::Nullish),
67        }
68    }
69}
70
71// Babel appears to just store all of these as a string. See
72// AssignmentExpression.operator field. NOTE(dwoznick): I'm unsure if this is
73// the correct way to handle this case.
74impl Babelify for AssignOp {
75    type Output = String;
76
77    fn babelify(self, _ctx: &Context) -> Self::Output {
78        match self {
79            AssignOp::Assign => "=".into(),
80            AssignOp::AddAssign => "+=".into(),
81            AssignOp::SubAssign => "-=".into(),
82            AssignOp::MulAssign => "*=".into(),
83            AssignOp::DivAssign => "/=".into(),
84            AssignOp::ModAssign => "%=".into(),
85            AssignOp::LShiftAssign => "<<=".into(),
86            AssignOp::RShiftAssign => ">>=".into(),
87            AssignOp::ZeroFillRShiftAssign => ">>>=".into(),
88            AssignOp::BitOrAssign => "|=".into(),
89            AssignOp::BitXorAssign => "^=".into(),
90            AssignOp::BitAndAssign => "&=".into(),
91            AssignOp::ExpAssign => "**=".into(),
92            AssignOp::AndAssign => "&&=".into(),
93            AssignOp::OrAssign => "||=".into(),
94            AssignOp::NullishAssign => "??=".into(),
95        }
96    }
97}
98
99impl Babelify for UpdateOp {
100    type Output = UpdateExprOp;
101
102    fn babelify(self, _ctx: &Context) -> Self::Output {
103        match self {
104            UpdateOp::PlusPlus => UpdateExprOp::Increment,
105            UpdateOp::MinusMinus => UpdateExprOp::Decrement,
106        }
107    }
108}
109
110impl Babelify for UnaryOp {
111    type Output = UnaryExprOp;
112
113    fn babelify(self, _ctx: &Context) -> Self::Output {
114        match self {
115            // TODO(dwoznicki): missing `throw` op
116            UnaryOp::Minus => UnaryExprOp::Negation,
117            UnaryOp::Plus => UnaryExprOp::Plus,
118            UnaryOp::Bang => UnaryExprOp::LogicalNot,
119            UnaryOp::Tilde => UnaryExprOp::BitwiseNot,
120            UnaryOp::TypeOf => UnaryExprOp::Typeof,
121            UnaryOp::Void => UnaryExprOp::Void,
122            UnaryOp::Delete => UnaryExprOp::Delete,
123        }
124    }
125}