Skip to main content

pine_lint/
pass.rs

1//! The lint-pass abstraction and the driver that runs every registered pass.
2
3use pine_ast::Program;
4
5use crate::passes;
6use pine_ast::visitor::Visitor;
7use pine_diagnostics::Diagnostic;
8
9/// A single check.
10///
11/// A pass is a [`Visitor`] (so it can walk the tree and collect findings as it
12/// goes) plus a way to hand back what it found. Most passes accumulate into a
13/// `Vec<Diagnostic>` field and return it from [`finish`](LintPass::finish); a
14/// pass that needs a whole-program view can instead ignore the visitor methods
15/// and do its work in `finish`.
16pub trait LintPass: Visitor {
17    /// The rule identifier, matching the `rule` field of the diagnostics it
18    /// emits (e.g. `"eq-na"`).
19    fn name(&self) -> &'static str;
20
21    /// Consume everything collected during the walk. Called once, after the
22    /// driver has run this pass over the program.
23    fn finish(&mut self) -> Vec<Diagnostic>;
24}
25
26/// Every built-in pass, freshly constructed. Add new checks here.
27fn all_passes() -> Vec<Box<dyn LintPass>> {
28    vec![
29        Box::new(passes::EqNa::default()),
30        Box::new(passes::ConstantCondition::default()),
31    ]
32}
33
34/// Run every built-in lint pass over `program` and return all findings,
35/// sorted by line for stable, readable output.
36pub fn lint(program: &Program) -> Vec<Diagnostic> {
37    lint_with(program, all_passes())
38}
39
40/// Run a specific set of passes. Useful for tests that want to exercise one
41/// check in isolation.
42pub fn lint_with(program: &Program, mut passes: Vec<Box<dyn LintPass>>) -> Vec<Diagnostic> {
43    let mut diagnostics = Vec::new();
44    for pass in &mut passes {
45        pass.visit_program(program);
46        diagnostics.extend(pass.finish());
47    }
48    // Stable ordering: located findings by position, then unlocated, preserving
49    // the pass registration order within a position.
50    diagnostics.sort_by_key(|d| d.pos.unwrap_or((u32::MAX, u32::MAX)));
51    diagnostics
52}