use crate::FileId; use crate::ast; use crate::rules::empty_inherit::EmptyInherit; pub mod empty_inherit; pub struct Finding { pub rule_id: &'static str, pub range: ast::SourceRange, pub message: &'static str, } pub struct Diagnostic { pub file_id: FileId, pub finding: Finding, } pub trait NodeRule { type Node; const ID: &'static str; fn select(data: &ast::NodeData) -> Option<&Self::Node>; fn check(node: &Self::Node) -> Option<&'static str>; } fn run_node_rule(node: &ast::Node) -> Option where R: NodeRule, { let typed_node = R::select(&node.data)?; let message = R::check(typed_node)?; Some(Finding { rule_id: R::ID, range: node.range, message, }) } pub fn run_rules(file: &ast::ParsedFile) -> Vec { file.nodes .iter() .flat_map(|node| { [run_node_rule::(node)] .into_iter() .flatten() .map(|finding| Diagnostic { file_id: file.file_id, finding, }) }) .collect() }