Skip to content

Commit 683ec6c

Browse files
committed
Simplify check API
1 parent 2f8a7c2 commit 683ec6c

File tree

9 files changed

+105
-177
lines changed

9 files changed

+105
-177
lines changed

src/diagnostic.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::path::PathBuf;
44

55
use serde::{Deserialize, Serialize};
66

7-
use crate::changelog::ParsedChangelog;
87
use crate::rule::Rule;
98
use crate::span::{Locator, Position, Ranged, Span};
109

src/linter.rs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use std::path::PathBuf;
44
use crate::changelog::parsed;
55
use crate::changelog::traits::*;
66
use crate::diagnostic::Diagnostic;
7+
use crate::rule::Rule;
78
use crate::ruleset::RuleSet;
9+
use crate::span::Span;
810

911
#[macro_use]
1012
mod macros;
@@ -27,6 +29,17 @@ pub struct Linter<'a> {
2729
filename: Option<PathBuf>,
2830
}
2931

32+
#[derive(Default)]
33+
pub(crate) struct Context {
34+
diagnostics: Vec<Diagnostic>,
35+
}
36+
37+
impl Context {
38+
fn report(&mut self, rule: Rule, span: Option<Span>) {
39+
self.diagnostics.push(Diagnostic::new(rule, span));
40+
}
41+
}
42+
3043
impl<'a> Linter<'a> {
3144
/// Create a new linter with the given ruleset.
3245
pub fn new(ruleset: &'a RuleSet) -> Self {
@@ -46,44 +59,42 @@ impl<'a> Linter<'a> {
4659

4760
/// Lint a changelog.
4861
pub fn lint(&self, changelog: &parsed::ParsedChangelog) -> Vec<Diagnostic> {
49-
let mut diagnostics: Vec<Diagnostic> = Vec::new();
5062
let mut checks: Vec<_> = checks()
5163
.into_iter()
5264
.filter(|check| self.ruleset.is_enabled(check.rule()))
5365
.collect();
66+
let mut context = Context::default();
5467
for check in checks.iter_mut() {
55-
check.visit_changelog(changelog);
68+
check.visit_changelog(&mut context, changelog);
5669
if let Some(unreleased) = changelog.unreleased() {
57-
check.visit_unreleased(unreleased);
70+
check.visit_unreleased(&mut context, unreleased);
5871
for changes in unreleased.changes() {
59-
check.visit_changes(changes);
72+
check.visit_changes(&mut context, changes);
6073
}
6174
}
6275
for span in &changelog.invalid_spans {
63-
check.visit_invalid_span(span);
76+
check.visit_invalid_span(&mut context, span);
6477
}
6578
}
6679
for release in changelog.releases() {
6780
for check in checks.iter_mut() {
68-
check.visit_release(release);
81+
check.visit_release(&mut context, release);
6982
for changes in release.changes() {
70-
check.visit_changes(changes);
83+
check.visit_changes(&mut context, changes);
7184
}
7285
}
7386
}
7487
for check in checks.iter_mut() {
75-
diagnostics.append(
76-
&mut check
77-
.diagnostics()
78-
.into_iter()
79-
.map(|mut d| {
80-
d.path = self.filename.clone();
81-
d
82-
})
83-
.collect(),
84-
);
88+
check.finalize(&mut context);
8589
}
86-
diagnostics
90+
context
91+
.diagnostics
92+
.into_iter()
93+
.map(|mut diagnostic| {
94+
diagnostic.path = self.filename.clone();
95+
diagnostic
96+
})
97+
.collect()
8798
}
8899
}
89100

src/linter/check.rs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
11
use crate::changelog::parsed;
2-
use crate::diagnostic::Diagnostic;
32
use crate::rule::Rule;
4-
use crate::span::Span;
3+
4+
use super::Context;
55

66
pub(crate) trait Check {
77
/// Return the `Rule` this check evaluates.
88
fn rule(&self) -> Rule;
99

10-
/// Return spans that this check matched.
11-
fn spans(&self) -> &[Span] {
12-
&[]
10+
fn visit_changelog(&mut self, _context: &mut Context, _changelog: &parsed::ParsedChangelog) {}
11+
fn visit_unreleased(&mut self, _context: &mut Context, _unreleased: &parsed::ParsedUnreleased) {
1312
}
13+
fn visit_release(&mut self, _context: &mut Context, _release: &parsed::ParsedRelease) {}
14+
fn visit_changes(&mut self, _context: &mut Context, _changes: &parsed::ParsedChanges) {}
15+
fn visit_invalid_span(&mut self, _context: &mut Context, _span: &parsed::InvalidSpan) {}
1416

15-
fn visit_changelog(&mut self, _changelog: &parsed::ParsedChangelog) {}
16-
fn visit_unreleased(&mut self, _unreleased: &parsed::ParsedUnreleased) {}
17-
fn visit_release(&mut self, _release: &parsed::ParsedRelease) {}
18-
fn visit_changes(&mut self, _changes: &parsed::ParsedChanges) {}
19-
fn visit_invalid_span(&mut self, _span: &parsed::InvalidSpan) {}
20-
21-
/// Publish diagnostics generated by this check.
22-
fn diagnostics(&self) -> Vec<Diagnostic> {
23-
self.spans()
24-
.iter()
25-
.map(|span| Diagnostic::new(self.rule(), Some(*span)))
26-
.collect()
27-
}
17+
fn finalize(&mut self, _context: &mut Context) {}
2818
}

src/linter/checks/content.rs

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,67 +3,55 @@ use std::collections::HashSet;
33
use crate::changelog::parsed;
44
use crate::linter::Check;
55
use crate::rule::Rule;
6-
use crate::span::Span;
6+
7+
use super::preamble::*;
78

89
invalid_span!(InvalidTitle);
910

1011
invalid_span!(InvalidSectionHeading);
1112

1213
#[derive(Default)]
13-
pub struct EmptySection {
14-
spans: Vec<Span>,
15-
}
14+
pub struct EmptySection;
1615

1716
// TODO: Store better spans for these headings.
1817
impl Check for EmptySection {
1918
fn rule(&self) -> Rule {
2019
Rule::EmptySection
2120
}
2221

23-
fn spans(&self) -> &[Span] {
24-
self.spans.as_slice()
25-
}
26-
27-
fn visit_release(&mut self, release: &parsed::ParsedRelease) {
22+
fn visit_release(&mut self, context: &mut Context, release: &parsed::ParsedRelease) {
2823
if release.changes.is_empty() {
29-
self.spans.push(release.heading_span);
24+
context.report(self.rule(), Some(release.heading_span));
3025
}
3126
}
3227

33-
fn visit_changes(&mut self, changes: &parsed::ParsedChanges) {
28+
fn visit_changes(&mut self, context: &mut Context, changes: &parsed::ParsedChanges) {
3429
if changes.items.is_empty() {
35-
self.spans.push(changes.heading_span)
30+
context.report(self.rule(), Some(changes.heading_span));
3631
}
3732
}
3833
}
3934

4035
#[derive(Default)]
41-
pub struct UnknownChangeType {
42-
spans: Vec<Span>,
43-
}
36+
pub struct UnknownChangeType;
4437

4538
impl Check for UnknownChangeType {
4639
fn rule(&self) -> Rule {
4740
Rule::UnknownChangeType
4841
}
4942

50-
fn spans(&self) -> &[Span] {
51-
self.spans.as_slice()
52-
}
53-
54-
fn visit_changes(&mut self, changes: &parsed::ParsedChanges) {
43+
fn visit_changes(&mut self, context: &mut Context, changes: &parsed::ParsedChanges) {
5544
if !matches!(
5645
changes.kind.value,
5746
"Added" | "Changed" | "Deprecated" | "Fixed" | "Removed" | "Security"
5847
) {
59-
self.spans.push(changes.kind.span);
48+
context.report(self.rule(), Some(changes.kind.span));
6049
}
6150
}
6251
}
6352

6453
#[derive(Default)]
6554
pub struct DuplicateChangeType {
66-
spans: Vec<Span>,
6755
seen: HashSet<String>,
6856
}
6957

@@ -72,21 +60,17 @@ impl Check for DuplicateChangeType {
7260
Rule::DuplicateChangeType
7361
}
7462

75-
fn spans(&self) -> &[Span] {
76-
self.spans.as_slice()
77-
}
78-
79-
fn visit_unreleased(&mut self, _unreleased: &parsed::ParsedUnreleased) {
63+
fn visit_unreleased(&mut self, _context: &mut Context, _unreleased: &parsed::ParsedUnreleased) {
8064
self.seen.clear();
8165
}
8266

83-
fn visit_release(&mut self, _unreleased: &parsed::ParsedRelease) {
67+
fn visit_release(&mut self, _context: &mut Context, _unreleased: &parsed::ParsedRelease) {
8468
self.seen.clear();
8569
}
8670

87-
fn visit_changes(&mut self, changes: &parsed::ParsedChanges) {
71+
fn visit_changes(&mut self, context: &mut Context, changes: &parsed::ParsedChanges) {
8872
if !self.seen.insert(changes.kind.value.to_string()) {
89-
self.spans.push(changes.kind.span);
73+
context.report(self.rule(), Some(changes.kind.span));
9074
}
9175
}
9276
}

src/linter/checks/links.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::changelog::parsed;
22
use crate::linter::Check;
33
use crate::rule::Rule;
4-
use crate::span::Span;
4+
5+
use super::preamble::*;
56

67
invalid_span!(UndefinedLinkReference);
78

src/linter/checks/preamble.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
pub(crate) use crate::diagnostic::Diagnostic;
1+
pub(crate) use crate::linter::Context;
22
pub(crate) use crate::linter::check::Check;
33
pub(crate) use crate::rule::Rule;
44
pub(crate) use crate::span::Span;
55

66
pub(crate) use crate::changelog::parsed;
7-
pub(crate) use crate::changelog::traits::*;

0 commit comments

Comments
 (0)