tan_lint/
lib.rs

1pub mod lints;
2
3use lints::snake_case_names_lint::SnakeCaseNamesLint;
4pub use lsp_types::{Diagnostic, DiagnosticSeverity, Range};
5use tan::{ann::Ann, api::parse_string_all, error::Error, expr::Expr};
6
7pub trait Lint {
8    /// A unique name for the lint.
9    fn name(&self) -> String;
10    // #TODO needs return type.
11    /// Runs after the parsing pass.
12    fn run(&mut self, exprs: &[Ann<Expr>]);
13}
14
15pub fn compute_parse_error_diagnostics(errors: Vec<Error>) -> Vec<Diagnostic> {
16    let mut diagnostics: Vec<Diagnostic> = Vec::new();
17
18    for error in errors {
19        if let Some(range) = error.range() {
20            let start = lsp_types::Position {
21                line: range.start.line as u32,
22                character: range.start.col as u32,
23            };
24            let end = lsp_types::Position {
25                line: range.end.line as u32,
26                character: range.end.col as u32,
27            };
28
29            diagnostics.push(Diagnostic {
30                range: Range { start, end },
31                severity: None,
32                code: None,
33                code_description: None,
34                source: None,
35                message: error.to_string(),
36                related_information: None,
37                tags: None,
38                data: None,
39            });
40        } else {
41            // #TODO how to handle errors without range?
42        }
43    }
44
45    diagnostics
46}
47
48pub fn compute_diagnostics(input: &str) -> Vec<Diagnostic> {
49    let result = parse_string_all(input);
50
51    // #TODO should run all lints.
52
53    let diagnostics = match result {
54        Ok(exprs) => {
55            let mut diagnostics = Vec::new();
56
57            // #TODO some Lints may need the input!
58
59            let mut lint = SnakeCaseNamesLint::new();
60            lint.run(&exprs);
61            diagnostics.append(&mut lint.diagnostics);
62
63            diagnostics
64        }
65        Err(errors) => compute_parse_error_diagnostics(errors),
66    };
67
68    diagnostics
69}