harper_core/linting/
pattern_linter.rs1use blanket::blanket;
2
3use crate::{
4 Document, LSend, Token, TokenStringExt,
5 patterns::{Pattern, PatternExt},
6};
7
8use super::{Lint, Linter};
9
10#[blanket(derive(Box))]
15pub trait PatternLinter: LSend {
16 fn pattern(&self) -> &dyn Pattern;
18 fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Option<Lint>;
23 fn description(&self) -> &str;
26}
27
28impl<L> Linter for L
29where
30 L: PatternLinter,
31{
32 fn lint(&mut self, document: &Document) -> Vec<Lint> {
33 let mut lints = Vec::new();
34 let source = document.get_source();
35
36 for chunk in document.iter_chunks() {
37 lints.extend(run_on_chunk(self, chunk, source));
38 }
39
40 lints
41 }
42
43 fn description(&self) -> &str {
44 self.description()
45 }
46}
47
48pub fn run_on_chunk(linter: &impl PatternLinter, chunk: &[Token], source: &[char]) -> Vec<Lint> {
49 let mut lints = Vec::new();
50
51 for match_span in linter.pattern().iter_matches(chunk, source) {
52 let lint = linter.match_to_lint(&chunk[match_span.start..match_span.end], source);
53 lints.extend(lint);
54 }
55
56 lints
57}