237 lines
5.2 KiB
Rust
237 lines
5.2 KiB
Rust
/// Creates a corresponding operator. This macro is used to make code more
|
|
/// readable.
|
|
///
|
|
/// This can used to represent [UnaryOp](crate::UnaryOp),
|
|
/// [BinaryOp](crate::BinaryOp), or [AssignOp](crate::AssignOp).
|
|
///
|
|
/// Actual type is determined by the input.
|
|
///
|
|
/// # Note about `+` and `-`
|
|
///
|
|
/// As this macro is intended to be used in anywhere, including pattern
|
|
/// bindings, this macro cannot use trick to determine type for `+` and `-`.
|
|
///
|
|
/// So we have to use some special syntax for `+` and `-`:
|
|
///
|
|
/// - If you need [UnaryOp](crate::UnaryOp), use `op!(unary, "+")` and
|
|
/// `op!(unary, "-")`.
|
|
///
|
|
/// - If you need [BinaryOp](crate::BinaryOp), use `op!(bin, "+")` and
|
|
/// `op!(bin, "-")`.
|
|
#[macro_export]
|
|
macro_rules! op {
|
|
(unary,"-") => {
|
|
$crate::UnaryOp::Minus
|
|
};
|
|
(unary,"+") => {
|
|
$crate::UnaryOp::Plus
|
|
};
|
|
("!") => {
|
|
$crate::UnaryOp::Bang
|
|
};
|
|
("~") => {
|
|
$crate::UnaryOp::Tilde
|
|
};
|
|
("typeof") => {
|
|
$crate::UnaryOp::TypeOf
|
|
};
|
|
("void") => {
|
|
$crate::UnaryOp::Void
|
|
};
|
|
("delete") => {
|
|
$crate::UnaryOp::Delete
|
|
};
|
|
|
|
("++") => {
|
|
$crate::UpdateOp::PlusPlus
|
|
};
|
|
("--") => {
|
|
$crate::UpdateOp::MinusMinus
|
|
};
|
|
|
|
("==") => {
|
|
$crate::BinaryOp::EqEq
|
|
};
|
|
("!=") => {
|
|
$crate::BinaryOp::NotEq
|
|
};
|
|
("===") => {
|
|
$crate::BinaryOp::EqEqEq
|
|
};
|
|
("!==") => {
|
|
$crate::BinaryOp::NotEqEq
|
|
};
|
|
("<") => {
|
|
$crate::BinaryOp::Lt
|
|
};
|
|
("<=") => {
|
|
$crate::BinaryOp::LtEq
|
|
};
|
|
(">") => {
|
|
$crate::BinaryOp::Gt
|
|
};
|
|
(">=") => {
|
|
$crate::BinaryOp::GtEq
|
|
};
|
|
("<<") => {
|
|
$crate::BinaryOp::LShift
|
|
};
|
|
(">>") => {
|
|
$crate::BinaryOp::RShift
|
|
};
|
|
(">>>") => {
|
|
$crate::BinaryOp::ZeroFillRShift
|
|
};
|
|
(bin,"+") => {
|
|
$crate::BinaryOp::Add
|
|
};
|
|
(bin,"-") => {
|
|
$crate::BinaryOp::Sub
|
|
};
|
|
("*") => {
|
|
$crate::BinaryOp::Mul
|
|
};
|
|
("/") => {
|
|
$crate::BinaryOp::Div
|
|
};
|
|
("%") => {
|
|
$crate::BinaryOp::Mod
|
|
};
|
|
("|") => {
|
|
$crate::BinaryOp::BitOr
|
|
};
|
|
("^") => {
|
|
$crate::BinaryOp::BitXor
|
|
};
|
|
("&") => {
|
|
$crate::BinaryOp::BitAnd
|
|
};
|
|
("||") => {
|
|
$crate::BinaryOp::LogicalOr
|
|
};
|
|
("&&") => {
|
|
$crate::BinaryOp::LogicalAnd
|
|
};
|
|
("in") => {
|
|
$crate::BinaryOp::In
|
|
};
|
|
("instanceof") => {
|
|
$crate::BinaryOp::InstanceOf
|
|
};
|
|
("**") => {
|
|
$crate::BinaryOp::Exp
|
|
};
|
|
("??") => {
|
|
$crate::BinaryOp::NullishCoalescing
|
|
};
|
|
|
|
("=") => {
|
|
$crate::AssignOp::Assign
|
|
};
|
|
("+=") => {
|
|
$crate::AssignOp::AddAssign
|
|
};
|
|
("-=") => {
|
|
$crate::AssignOp::SubAssign
|
|
};
|
|
("*=") => {
|
|
$crate::AssignOp::MulAssign
|
|
};
|
|
("/=") => {
|
|
$crate::AssignOp::DivAssign
|
|
};
|
|
("%=") => {
|
|
$crate::AssignOp::ModAssign
|
|
};
|
|
("<<=") => {
|
|
$crate::AssignOp::LShiftAssign
|
|
};
|
|
(">>=") => {
|
|
$crate::AssignOp::RShiftAssign
|
|
};
|
|
(">>>=") => {
|
|
$crate::AssignOp::ZeroFillRShiftAssign
|
|
};
|
|
("|=") => {
|
|
$crate::AssignOp::BitOrAssign
|
|
};
|
|
("^=") => {
|
|
$crate::AssignOp::BitXorAssign
|
|
};
|
|
("&=") => {
|
|
$crate::AssignOp::BitAndAssign
|
|
};
|
|
("**=") => {
|
|
$crate::AssignOp::ExpAssign
|
|
};
|
|
("&&=") => {
|
|
$crate::AssignOp::AndAssign
|
|
};
|
|
("||=") => {
|
|
$crate::AssignOp::OrAssign
|
|
};
|
|
("??=") => {
|
|
$crate::AssignOp::NullishAssign
|
|
};
|
|
}
|
|
|
|
macro_rules! test_de {
|
|
($name:ident, $T:path, $s:literal) => {
|
|
#[test]
|
|
#[cfg(feature = "serde-impl")]
|
|
fn $name() {
|
|
let _var: $T = ::serde_json::from_str(&$s).expect("failed to parse json");
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Implement `From<$src>` for `$dst`, by using implementation of `From<$src>`
|
|
/// for `$bridge`.
|
|
///
|
|
/// - `$dst` must implement `From<$bridge>`.
|
|
/// - `$bridge` must implement `From<$src>`.
|
|
///
|
|
///
|
|
/// e.g. For `&str` -> `Box<Expr>`, we convert it by `&str` -> `JsWord` -> `Str`
|
|
/// -> `Lit` -> `Expr` -> `Box<Expr>`.
|
|
macro_rules! bridge_from {
|
|
($dst:ty, $bridge:ty, $src:ty) => {
|
|
impl From<$src> for $dst {
|
|
#[cfg_attr(not(debug_assertions), inline(always))]
|
|
fn from(src: $src) -> $dst {
|
|
let src: $bridge = src.into();
|
|
src.into()
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! bridge_expr_from {
|
|
($bridge:ty, $src:ty) => {
|
|
bridge_from!(crate::Expr, $bridge, $src);
|
|
bridge_from!(Box<crate::Expr>, crate::Expr, $src);
|
|
};
|
|
}
|
|
|
|
macro_rules! bridge_pat_from {
|
|
($bridge:ty, $src:ty) => {
|
|
bridge_from!(crate::Pat, $bridge, $src);
|
|
bridge_from!(crate::Param, crate::Pat, $src);
|
|
bridge_from!(Box<crate::Pat>, crate::Pat, $src);
|
|
};
|
|
}
|
|
|
|
macro_rules! bridge_stmt_from {
|
|
($bridge:ty, $src:ty) => {
|
|
bridge_from!(crate::Stmt, $bridge, $src);
|
|
bridge_from!(crate::ModuleItem, crate::Stmt, $src);
|
|
};
|
|
}
|
|
|
|
macro_rules! bridge_decl_from {
|
|
($bridge:ty, $src:ty) => {
|
|
bridge_from!(crate::Decl, $bridge, $src);
|
|
bridge_from!(crate::Stmt, crate::Decl, $src);
|
|
bridge_from!(crate::ModuleItem, crate::Stmt, $src);
|
|
};
|
|
}
|