Skip to main content

forge_lint/sol/analysis/
interface.rs

1//! Match contract function shapes (ABI signatures, receiver contract type).
2
3use solar::sema::hir::{self, ContractId, Expr, ExprKind, ItemId, Res, TypeKind, VariableId};
4
5/// True if `id`'s elementary type matches the given ABI string.
6pub fn is_elementary(hir: &hir::Hir<'_>, id: VariableId, abi: &str) -> bool {
7    matches!(&hir.variable(id).ty.kind, TypeKind::Elementary(ty) if ty.to_abi_str() == abi)
8}
9
10/// Static contract type of a method-call receiver: a contract-typed variable
11/// or an `IFoo(addr)` interface wrap.
12pub fn receiver_contract_id(hir: &hir::Hir<'_>, recv: &Expr<'_>) -> Option<ContractId> {
13    match &recv.peel_parens().kind {
14        ExprKind::Ident([Res::Item(ItemId::Variable(id)), ..]) => {
15            if let TypeKind::Custom(ItemId::Contract(cid)) = hir.variable(*id).ty.kind {
16                Some(cid)
17            } else {
18                None
19            }
20        }
21        ExprKind::Call(callee, ..) => {
22            if let ExprKind::Ident([Res::Item(ItemId::Contract(cid))]) = &callee.peel_parens().kind
23            {
24                Some(*cid)
25            } else {
26                None
27            }
28        }
29        _ => None,
30    }
31}