Archived
57 lines
2.2 KiB
Rust
57 lines
2.2 KiB
Rust
//! Core trait and context types for architectural rules.
|
|
|
|
use std::collections::HashMap;
|
|
use crate::error::ArchDiagnostic;
|
|
|
|
/// Information about a single function call within a function body.
|
|
#[derive(Debug, Clone)]
|
|
pub struct CallInfo {
|
|
/// The name of the function being called.
|
|
pub callee: String,
|
|
/// True if this call appears inside a loop body (for or while).
|
|
pub is_in_loop: bool,
|
|
}
|
|
|
|
/// Full context about a single function being checked by arch rules.
|
|
pub struct FnContext<'a> {
|
|
/// Name of the function under analysis.
|
|
pub fn_name: &'a str,
|
|
/// Decorator names applied directly to this function (e.g. "accessor", "public").
|
|
pub annotations: &'a [String],
|
|
/// All calls made from within this function body.
|
|
pub body_calls: &'a [CallInfo],
|
|
/// Global map of function name → decorator names for the whole program.
|
|
pub all_fn_annotations: &'a HashMap<String, Vec<String>>,
|
|
/// TypeNames that appear in `activate TypeName where ...` calls in this function.
|
|
pub activate_types: &'a [String],
|
|
/// Whether this function contains a `sealed { }` block inside a loop.
|
|
pub has_sealed_in_loop: bool,
|
|
/// The return type of the function as a string (e.g. "Result", "Void", "String").
|
|
pub return_type_name: &'a str,
|
|
}
|
|
|
|
impl<'a> FnContext<'a> {
|
|
/// Returns true if this function has the given annotation/decorator.
|
|
pub fn has_annotation(&self, name: &str) -> bool {
|
|
self.annotations.iter().any(|a| a == name)
|
|
}
|
|
|
|
/// Returns true if the named callee has the given annotation in the program.
|
|
pub fn callee_has_annotation(&self, callee: &str, ann: &str) -> bool {
|
|
self.all_fn_annotations
|
|
.get(callee)
|
|
.map(|anns| anns.iter().any(|a| a == ann))
|
|
.unwrap_or(false)
|
|
}
|
|
}
|
|
|
|
/// An architectural rule that can be checked against a function context.
|
|
pub trait ArchRule: Send + Sync {
|
|
/// Short unique identifier, e.g. "VBD-001".
|
|
fn name(&self) -> &str;
|
|
/// Human-readable description of what this rule enforces.
|
|
fn description(&self) -> &str;
|
|
/// Run the rule against a function context, returning any diagnostics.
|
|
fn check(&self, ctx: &FnContext<'_>) -> Vec<ArchDiagnostic>;
|
|
}
|