ferrograph 1.5.0

Graph-powered Rust code intelligence
Documentation
//! Analysis pipeline: file discovery, AST, modules, call graph, and downstream phases.

mod ast;
mod borrows;
mod calls;
mod dead_code;
mod discovery;
mod expands;
mod git_coupling;
mod lifetimes;
mod modules;
mod owns;
mod placeholder;
mod primitives;
mod references;
mod traits;

pub use ast::extract_ast;
pub use borrows::{resolve_borrows_edges, resolve_borrows_mut_edges};
pub use calls::build_call_graph;
pub use dead_code::detect_dead_code;
pub use discovery::discover_files;
pub use expands::resolve_expands_to_edges;
pub use git_coupling::analyze_git_coupling;
pub use modules::resolve_modules;
pub use owns::resolve_owns_edges;
pub use references::resolve_reference_edges;
pub use traits::{map_traits, resolve_impl_trait_edges};

use anyhow::Result;
use std::path::Path;

use crate::graph::Store;

/// Pipeline configuration (tier: fast, balanced, full).
#[derive(Clone, Debug, Default)]
pub struct PipelineConfig {
    /// If true, run trait/impl mapping (rust-analyzer, requires `ra` feature).
    pub enable_trait_mapping: bool,
    /// If true, run git change coupling (requires `git` feature).
    pub enable_git_coupling: bool,
}

/// Run the full indexing pipeline on a project root.
///
/// # Errors
/// Fails if any pipeline phase fails (discovery, AST, store writes, etc.).
pub fn run_pipeline(store: &Store, root: &Path, config: &PipelineConfig) -> Result<()> {
    let files = discover_files(root)?;
    for (path, content) in &files {
        extract_ast(store, path, content, root)?;
    }
    primitives::create_primitive_nodes(store)?;
    resolve_modules(store, root)?; // Imports edges must exist before call resolution
    build_call_graph(store)?;
    resolve_impl_trait_edges(store)?; // Resolve placeholder impl→trait edges from AST
    resolve_reference_edges(store)?; // Resolve placeholder type reference edges from AST
    resolve_owns_edges(store)?; // Resolve placeholder owns edges (item → type)
    resolve_borrows_edges(store)?; // Resolve placeholder borrows edges (item → type)
    resolve_borrows_mut_edges(store)?; // Resolve placeholder borrows_mut edges (item → type)
    resolve_expands_to_edges(store)?; // Resolve placeholder macro invocation→definition edges from AST
    if config.enable_trait_mapping {
        map_traits(store, root)?;
    }
    detect_dead_code(store)?;
    if config.enable_git_coupling {
        analyze_git_coupling(store, root)?;
    }
    Ok(())
}