swc_estree_compat/babelify/
operators.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use serde::{Deserialize, Serialize};
use swc_ecma_ast::{AssignOp, BinaryOp, UnaryOp, UpdateOp};
use swc_estree_ast::{BinaryExprOp, LogicalExprOp, UnaryExprOp, UpdateExprOp};

use crate::babelify::{Babelify, Context};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BinaryOpOutput {
    BinOp(BinaryExprOp),
    LogicOp(LogicalExprOp),
}

impl From<BinaryOpOutput> for BinaryExprOp {
    fn from(o: BinaryOpOutput) -> Self {
        match o {
            BinaryOpOutput::BinOp(op) => op,
            BinaryOpOutput::LogicOp(_) => panic!(
                "illegal conversion: Cannot convert {:?} to BinaryExprOp",
                &o
            ),
        }
    }
}

impl From<BinaryOpOutput> for LogicalExprOp {
    fn from(o: BinaryOpOutput) -> Self {
        match o {
            BinaryOpOutput::LogicOp(op) => op,
            BinaryOpOutput::BinOp(_) => panic!(
                "illegal conversion: Cannot convert {:?} to LogicalExprOp",
                &o
            ),
        }
    }
}

impl Babelify for BinaryOp {
    type Output = BinaryOpOutput;

    fn babelify(self, _ctx: &Context) -> Self::Output {
        match self {
            BinaryOp::EqEq => BinaryOpOutput::BinOp(BinaryExprOp::Equal),
            BinaryOp::NotEq => BinaryOpOutput::BinOp(BinaryExprOp::NotEqual),
            BinaryOp::EqEqEq => BinaryOpOutput::BinOp(BinaryExprOp::StrictEqual),
            BinaryOp::NotEqEq => BinaryOpOutput::BinOp(BinaryExprOp::StrictNotEqual),
            BinaryOp::Lt => BinaryOpOutput::BinOp(BinaryExprOp::LessThan),
            BinaryOp::LtEq => BinaryOpOutput::BinOp(BinaryExprOp::LessThanOrEqual),
            BinaryOp::Gt => BinaryOpOutput::BinOp(BinaryExprOp::GreaterThan),
            BinaryOp::GtEq => BinaryOpOutput::BinOp(BinaryExprOp::GreaterThanOrEqual),
            BinaryOp::LShift => BinaryOpOutput::BinOp(BinaryExprOp::LeftShift),
            BinaryOp::RShift => BinaryOpOutput::BinOp(BinaryExprOp::RightShift),
            BinaryOp::ZeroFillRShift => BinaryOpOutput::BinOp(BinaryExprOp::UnsignedRightShift),
            BinaryOp::Add => BinaryOpOutput::BinOp(BinaryExprOp::Addition),
            BinaryOp::Sub => BinaryOpOutput::BinOp(BinaryExprOp::Subtraction),
            BinaryOp::Mul => BinaryOpOutput::BinOp(BinaryExprOp::Multiplication),
            BinaryOp::Div => BinaryOpOutput::BinOp(BinaryExprOp::Division),
            BinaryOp::Mod => BinaryOpOutput::BinOp(BinaryExprOp::Remainder),
            BinaryOp::BitOr => BinaryOpOutput::BinOp(BinaryExprOp::Or),
            BinaryOp::BitXor => BinaryOpOutput::BinOp(BinaryExprOp::Xor),
            BinaryOp::BitAnd => BinaryOpOutput::BinOp(BinaryExprOp::And),
            BinaryOp::LogicalOr => BinaryOpOutput::LogicOp(LogicalExprOp::Or),
            BinaryOp::LogicalAnd => BinaryOpOutput::LogicOp(LogicalExprOp::And),
            BinaryOp::In => BinaryOpOutput::BinOp(BinaryExprOp::In),
            BinaryOp::InstanceOf => BinaryOpOutput::BinOp(BinaryExprOp::Instanceof),
            BinaryOp::Exp => BinaryOpOutput::BinOp(BinaryExprOp::Exponentiation),
            BinaryOp::NullishCoalescing => BinaryOpOutput::LogicOp(LogicalExprOp::Nullish),
        }
    }
}

// Babel appears to just store all of these as a string. See
// AssignmentExpression.operator field. NOTE(dwoznick): I'm unsure if this is
// the correct way to handle this case.
impl Babelify for AssignOp {
    type Output = String;

    fn babelify(self, _ctx: &Context) -> Self::Output {
        match self {
            AssignOp::Assign => "=".into(),
            AssignOp::AddAssign => "+=".into(),
            AssignOp::SubAssign => "-=".into(),
            AssignOp::MulAssign => "*=".into(),
            AssignOp::DivAssign => "/=".into(),
            AssignOp::ModAssign => "%=".into(),
            AssignOp::LShiftAssign => "<<=".into(),
            AssignOp::RShiftAssign => ">>=".into(),
            AssignOp::ZeroFillRShiftAssign => ">>>=".into(),
            AssignOp::BitOrAssign => "|=".into(),
            AssignOp::BitXorAssign => "^=".into(),
            AssignOp::BitAndAssign => "&=".into(),
            AssignOp::ExpAssign => "**=".into(),
            AssignOp::AndAssign => "&&=".into(),
            AssignOp::OrAssign => "||=".into(),
            AssignOp::NullishAssign => "??=".into(),
        }
    }
}

impl Babelify for UpdateOp {
    type Output = UpdateExprOp;

    fn babelify(self, _ctx: &Context) -> Self::Output {
        match self {
            UpdateOp::PlusPlus => UpdateExprOp::Increment,
            UpdateOp::MinusMinus => UpdateExprOp::Decrement,
        }
    }
}

impl Babelify for UnaryOp {
    type Output = UnaryExprOp;

    fn babelify(self, _ctx: &Context) -> Self::Output {
        match self {
            // TODO(dwoznicki): missing `throw` op
            UnaryOp::Minus => UnaryExprOp::Negation,
            UnaryOp::Plus => UnaryExprOp::Plus,
            UnaryOp::Bang => UnaryExprOp::LogicalNot,
            UnaryOp::Tilde => UnaryExprOp::BitwiseNot,
            UnaryOp::TypeOf => UnaryExprOp::Typeof,
            UnaryOp::Void => UnaryExprOp::Void,
            UnaryOp::Delete => UnaryExprOp::Delete,
        }
    }
}