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.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(
22            Expr { kind: ExprKind::Ident([Res::Item(ItemId::Contract(cid))]), .. },
23            ..,
24        ) => Some(*cid),
25        _ => None,
26    }
27}