weavatrix-rust 2.16.1

Protocol-independent Rust repository intelligence: typed evidence graphs for impact, architecture, APIs, Git, search, and memory
Documentation
use super::AnalysisState;
use crate::language::web3::web3_binds;
use crate::model::Result;
use std::collections::BTreeSet;
use weavatrix_graph::{Edge, EdgeKind, NodeId, NodeKind, SourceSpan};

impl AnalysisState {
    pub(super) fn register_web3_symbol(
        &mut self,
        relative: &str,
        kind: &NodeKind,
        name: &str,
        id: &NodeId,
    ) {
        let kind = kind.as_str();
        if !kind.starts_with("web3.abi.") {
            return;
        }
        let short = kind.trim_start_matches("web3.abi.");
        let stem = name.split('(').next().unwrap_or(name);
        for key in [
            format!("{relative}#{short}:{name}"),
            format!("{relative}#{short}:{stem}"),
        ] {
            self.web3_index.entry(key).or_default().push(id.clone());
        }
    }

    pub(super) fn queue_web3_bind(
        &mut self,
        source: &NodeId,
        name: &str,
        span: SourceSpan,
        relation: EdgeKind,
    ) {
        let Some(key) = name.strip_prefix("web3.bind:") else {
            return;
        };
        self.pending_web3
            .push((source.clone(), key.to_owned(), span, relation));
    }

    pub(in crate::analyzer) fn resolve_web3_bindings(&mut self) -> Result<()> {
        let pending = std::mem::take(&mut self.pending_web3);
        let mut seen = BTreeSet::<(String, String, String, String)>::new();
        for (from, key, span, _relation) in pending {
            let targets = self.lookup_web3(&key);
            if targets.len() != 1 {
                continue;
            }
            for to in targets {
                let detail = format!("web3-bind:{key}");
                if !seen.insert((
                    from.as_str().to_owned(),
                    to.as_str().to_owned(),
                    "web3.binds".into(),
                    detail.clone(),
                )) {
                    continue;
                }
                let provenance = crate::analyzer::support::parsed_provenance(
                    "weavatrix.web3",
                    Some(span.clone()),
                )?
                .with_detail(detail);
                self.graph
                    .add_edge(Edge::new(from.clone(), to, web3_binds(), provenance))?;
            }
        }
        Ok(())
    }

    fn lookup_web3(&self, key: &str) -> Vec<NodeId> {
        self.web3_index.get(key).cloned().unwrap_or_default()
    }
}