Skip to main content

miniextendr_lint/
rules.rs

1//! Lint rule implementations.
2//!
3//! Each submodule contains one or more related lint checks. All rules operate
4//! on the shared [`CrateIndex`] and produce
5//! [`Diagnostic`] values.
6
7pub mod doc_attr_interleave;
8pub mod export_attrs;
9pub mod ffi_unchecked;
10pub mod fn_visibility;
11pub mod impl_validation;
12pub mod lifetime_param;
13pub mod r_reserved_params;
14pub mod rf_error;
15pub mod s4_method_prefix;
16pub mod vctrs_self_ctor;
17
18use crate::crate_index::CrateIndex;
19use crate::diagnostic::Diagnostic;
20
21/// Run all lint rules against the crate index, collecting diagnostics.
22pub fn run_all_rules(index: &CrateIndex) -> Vec<Diagnostic> {
23    let mut diagnostics = Vec::new();
24
25    // Per-file impl validation (MXL008, MXL009, MXL010)
26    impl_validation::check(index, &mut diagnostics);
27
28    // Per-file: function visibility (MXL106)
29    fn_visibility::check(index, &mut diagnostics);
30
31    // Per-file: export attr redundancy (MXL203)
32    export_attrs::check(index, &mut diagnostics);
33
34    // Per-file: R reserved words as parameter names (MXL110)
35    r_reserved_params::check(index, &mut diagnostics);
36
37    // Per-file: direct Rf_error/Rf_errorcall usage (MXL300)
38    rf_error::check(index, &mut diagnostics);
39
40    // Per-file: ffi::*_unchecked() usage (MXL301)
41    ffi_unchecked::check(index, &mut diagnostics);
42
43    // Per-file: s4_* method name on #[miniextendr(s4)] impl (MXL111)
44    s4_method_prefix::check(index, &mut diagnostics);
45
46    // Per-file: explicit lifetime param on #[miniextendr] fn/impl (MXL112)
47    lifetime_param::check(index, &mut diagnostics);
48
49    // Per-file: vctrs ctor returns Self / instance receiver on vctrs impl (MXL120)
50    vctrs_self_ctor::check(index, &mut diagnostics);
51
52    // Per-file: non-doc attribute interrupts doc-comment stream (MXL302)
53    doc_attr_interleave::check(index, &mut diagnostics);
54
55    // Sort by path and line for deterministic output
56    diagnostics.sort_by(|a, b| {
57        a.path
58            .cmp(&b.path)
59            .then(a.line.cmp(&b.line))
60            .then(a.code.cmp(&b.code))
61    });
62
63    diagnostics
64}