xbp-analysis 10.57.0

Language-agnostic static analysis (error-handling / Aspirator-style) for XBP
Documentation
//! Language-independent analysis model built by adapters.

use super::concepts::ConceptInstance;
use super::types::{ControlFlow, ErrorPath, LanguageId, SourceFile};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

/// Per-file abstract model consumed by language-independent rules.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FileModel {
    pub path: PathBuf,
    pub language: LanguageId,
    pub concepts: Vec<ConceptInstance>,
    #[serde(default)]
    pub control_flow: ControlFlow,
    #[serde(default)]
    pub error_paths: Vec<ErrorPath>,
    /// True when the adapter marks the file as generated / macro-expanded only.
    #[serde(default)]
    pub generated: bool,
}

/// Workspace-level model for a single language analysis pass.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct LanguageModel {
    pub language: LanguageId,
    pub files: Vec<FileModel>,
}

impl LanguageModel {
    pub fn new(language: LanguageId) -> Self {
        Self {
            language,
            files: Vec::new(),
        }
    }

    pub fn concepts(&self) -> impl Iterator<Item = (&FileModel, &ConceptInstance)> {
        self.files
            .iter()
            .flat_map(|f| f.concepts.iter().map(move |c| (f, c)))
    }
}

/// Result of parsing a single source file (opaque to domain rules).
#[derive(Debug, Clone)]
pub struct ParseResult {
    pub file: SourceFile,
    pub ok: bool,
    pub diagnostics: Vec<String>,
}