use std::fmt;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
pub enum NodeKind {
Block,
Empty,
Yield,
ExprStmt,
VarDecl,
Assign,
If,
While,
DoWhile,
For,
ForEach,
Return,
Break,
Continue,
Throw,
Try,
Catch,
Synchronized,
Switch,
Case,
Label,
Assert,
Binary,
Unary,
Call,
Literal,
VarRef,
Ternary,
Cast,
Paren,
Member,
Index,
New,
NewArray,
ArrayLit,
This,
InstanceOf,
Lambda,
MethodRef,
Raw,
Custom(u16),
}
impl NodeKind {
#[inline]
pub fn slot(self) -> usize {
match self {
NodeKind::Block => 0,
NodeKind::Empty => 1,
NodeKind::Yield => 2,
NodeKind::ExprStmt => 2,
NodeKind::VarDecl => 3,
NodeKind::Assign => 4,
NodeKind::If => 5,
NodeKind::While => 6,
NodeKind::DoWhile => 7,
NodeKind::For => 8,
NodeKind::ForEach => 9,
NodeKind::Return => 10,
NodeKind::Break => 11,
NodeKind::Continue => 12,
NodeKind::Throw => 13,
NodeKind::Try => 14,
NodeKind::Catch => 15,
NodeKind::Synchronized => 16,
NodeKind::Switch => 17,
NodeKind::Case => 18,
NodeKind::Label => 19,
NodeKind::Assert => 20,
NodeKind::Binary => 21,
NodeKind::Unary => 22,
NodeKind::Call => 23,
NodeKind::Literal => 24,
NodeKind::VarRef => 25,
NodeKind::Ternary => 26,
NodeKind::Cast => 27,
NodeKind::Paren => 28,
NodeKind::Member => 29,
NodeKind::Index => 30,
NodeKind::New => 31,
NodeKind::NewArray => 32,
NodeKind::ArrayLit => 33,
NodeKind::This => 34,
NodeKind::InstanceOf => 35,
NodeKind::Lambda => 36,
NodeKind::MethodRef => 37,
NodeKind::Raw => 38,
NodeKind::Custom(_) => 39,
}
}
pub const SLOT_COUNT: usize = 42;
}
impl NodeKind {
pub fn is_stmt(self) -> bool {
use NodeKind::*;
matches!(
self,
Block | Empty | ExprStmt | VarDecl | Assign | If | While | DoWhile | For | ForEach
| Return | Break | Continue | Throw | Switch | Case | Try | Catch
| Synchronized | Label | Assert | Raw
)
}
}
impl fmt::Display for NodeKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Rem,
Shl,
Shr,
UShr,
Lt,
Le,
Gt,
Ge,
Eq,
Ne,
BitAnd,
BitXor,
BitOr,
And,
Or,
}
impl BinOp {
pub fn is_comparison(self) -> bool {
matches!(self, BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge | BinOp::Eq | BinOp::Ne)
}
pub fn is_short_circuit(self) -> bool {
matches!(self, BinOp::And | BinOp::Or)
}
pub fn may_div_zero(self) -> bool {
matches!(self, BinOp::Div | BinOp::Rem)
}
pub fn is_arith(self) -> bool {
matches!(
self,
BinOp::Add
| BinOp::Sub
| BinOp::Mul
| BinOp::Div
| BinOp::Rem
| BinOp::Shl
| BinOp::Shr
| BinOp::UShr
| BinOp::BitAnd
| BinOp::BitXor
| BinOp::BitOr
)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum UnOp {
Not,
Neg,
BitNot,
Plus,
PreInc,
PreDec,
PostInc,
PostDec,
}
impl UnOp {
pub fn is_incdec(self) -> bool {
matches!(
self,
UnOp::PreInc | UnOp::PreDec | UnOp::PostInc | UnOp::PostDec
)
}
}
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum LitRef<'a> {
Bool(bool),
Int(i64),
Long(i64),
Float(f64),
Double(f64),
Char(char),
Str(&'a str),
Null,
}
impl<'a> LitRef<'a> {
pub fn is_bool(self) -> bool {
matches!(self, LitRef::Bool(_))
}
pub fn as_int(self) -> Option<i64> {
match self {
LitRef::Int(v) | LitRef::Long(v) => Some(v),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct RegionEvent<Id, Key> {
pub kind: EventKind,
pub node: Id,
pub key: Key,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum EventKind {
Use,
Write,
Shadow,
Opaque,
}