use crate::node::{BinOpKind, LiteralKind, NodeKind, NormalizedNode, UnOpKind};
use crate::normalization_context::NormalizationContext;
use syn::punctuated::Punctuated;
use syn::BinOp;
use syn::Expr;
use syn::Lit;
use syn::Macro;
use syn::Member;
use syn::UnOp;
#[must_use]
pub fn member_to_string(member: &Member) -> String {
match member {
Member::Named(ident) => ident.to_string(),
Member::Unnamed(idx) => idx.index.to_string(),
}
}
impl NormalizationContext {
pub fn normalize_macro(&mut self, mac: &Macro) -> NormalizedNode {
let name = mac
.path
.segments
.last()
.map(|s| s.ident.to_string())
.unwrap_or_default();
let args = if mac.tokens.is_empty() {
Vec::new()
} else {
match mac.parse_body_with(Punctuated::<Expr, syn::Token![,]>::parse_terminated) {
Ok(punct) => punct.into_iter().map(|e| self.normalize_expr(&e)).collect(),
Err(_) => vec![NormalizedNode::leaf(NodeKind::Opaque)],
}
};
NormalizedNode::with_children(NodeKind::MacroCall { name }, args)
}
}
#[must_use]
pub const fn normalize_lit(lit: &Lit) -> NormalizedNode {
match lit {
Lit::Str(_) => NormalizedNode::leaf(NodeKind::Literal(LiteralKind::Str)),
Lit::ByteStr(_) => NormalizedNode::leaf(NodeKind::Literal(LiteralKind::ByteStr)),
Lit::CStr(_) => NormalizedNode::leaf(NodeKind::Literal(LiteralKind::CStr)),
Lit::Byte(_) => NormalizedNode::leaf(NodeKind::Literal(LiteralKind::Byte)),
Lit::Char(_) => NormalizedNode::leaf(NodeKind::Literal(LiteralKind::Char)),
Lit::Int(_) => NormalizedNode::leaf(NodeKind::Literal(LiteralKind::Int)),
Lit::Float(_) => NormalizedNode::leaf(NodeKind::Literal(LiteralKind::Float)),
Lit::Bool(_) => NormalizedNode::leaf(NodeKind::Literal(LiteralKind::Bool)),
_ => NormalizedNode::leaf(NodeKind::Opaque),
}
}
#[must_use]
pub const fn normalize_bin_op(op: &BinOp) -> BinOpKind {
match op {
BinOp::Add(_) => BinOpKind::Add,
BinOp::Sub(_) => BinOpKind::Sub,
BinOp::Mul(_) => BinOpKind::Mul,
BinOp::Div(_) => BinOpKind::Div,
BinOp::Rem(_) => BinOpKind::Rem,
BinOp::And(_) => BinOpKind::And,
BinOp::Or(_) => BinOpKind::Or,
BinOp::BitXor(_) => BinOpKind::BitXor,
BinOp::BitAnd(_) => BinOpKind::BitAnd,
BinOp::BitOr(_) => BinOpKind::BitOr,
BinOp::Shl(_) => BinOpKind::Shl,
BinOp::Shr(_) => BinOpKind::Shr,
BinOp::Eq(_) => BinOpKind::Eq,
BinOp::Lt(_) => BinOpKind::Lt,
BinOp::Le(_) => BinOpKind::Le,
BinOp::Ne(_) => BinOpKind::Ne,
BinOp::Ge(_) => BinOpKind::Ge,
BinOp::Gt(_) => BinOpKind::Gt,
BinOp::AddAssign(_) => BinOpKind::AddAssign,
BinOp::SubAssign(_) => BinOpKind::SubAssign,
BinOp::MulAssign(_) => BinOpKind::MulAssign,
BinOp::DivAssign(_) => BinOpKind::DivAssign,
BinOp::RemAssign(_) => BinOpKind::RemAssign,
BinOp::BitXorAssign(_) => BinOpKind::BitXorAssign,
BinOp::BitAndAssign(_) => BinOpKind::BitAndAssign,
BinOp::BitOrAssign(_) => BinOpKind::BitOrAssign,
BinOp::ShlAssign(_) => BinOpKind::ShlAssign,
BinOp::ShrAssign(_) => BinOpKind::ShrAssign,
_ => BinOpKind::Other,
}
}
#[must_use]
pub const fn normalize_un_op(op: &UnOp) -> UnOpKind {
match op {
UnOp::Deref(_) => UnOpKind::Deref,
UnOp::Not(_) => UnOpKind::Not,
UnOp::Neg(_) => UnOpKind::Neg,
_ => UnOpKind::Other,
}
}