-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added linter for multiple sequential pronouns
- Loading branch information
1 parent
7c4e1db
commit 5b40b9c
Showing
5 changed files
with
155 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
harper-core/src/linting/multiple_sequential_pronouns.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use crate::{CharString, Document, Lint, LintKind, Linter, Span, TokenStringExt}; | ||
|
||
/// Linter that checks if multiple pronouns are being used right after each | ||
/// other. This is a common mistake to make during the revision process. | ||
#[derive(Debug)] | ||
pub struct MultipleSequentialPronouns { | ||
/// Since there aren't many pronouns, it's faster to store this as a vector. | ||
pronouns: Vec<CharString> | ||
} | ||
|
||
impl MultipleSequentialPronouns { | ||
fn new() -> Self { | ||
let pronoun_strs = [ | ||
"me", "my", "I", "we", "you", "he", "him", "her", "she", "it", "they" | ||
]; | ||
|
||
let mut pronouns: Vec<CharString> = pronoun_strs | ||
.iter() | ||
.map(|s| s.chars().collect::<CharString>()) | ||
.collect(); | ||
|
||
pronouns.sort(); | ||
|
||
Self { pronouns } | ||
} | ||
|
||
fn is_pronoun(&self, word: &[char]) -> bool { | ||
self.pronouns | ||
.binary_search_by_key(&word, |w| w.as_slice()) | ||
.is_ok() | ||
} | ||
} | ||
|
||
impl Linter for MultipleSequentialPronouns { | ||
fn lint(&mut self, document: &Document) -> Vec<Lint> { | ||
let mut lints = Vec::new(); | ||
|
||
let mut found_pronouns = Vec::new(); | ||
|
||
for sentence in document.sentences() { | ||
for word in sentence.iter_words() { | ||
let word_chars = document.get_span_content(word.span); | ||
|
||
if self.is_pronoun(word_chars) { | ||
found_pronouns.push(word); | ||
} else if found_pronouns.len() == 1 { | ||
found_pronouns.clear(); | ||
} else if found_pronouns.len() > 1 { | ||
let first = found_pronouns.first().unwrap(); | ||
let last = found_pronouns.last().unwrap(); | ||
|
||
lints.push(Lint { | ||
span: Span::new(first.span.start, last.span.end), | ||
lint_kind: LintKind::Repetition, | ||
message: "There are too many personal pronouns in sequence here." | ||
.to_owned(), | ||
priority: 63, | ||
..Default::default() | ||
}); | ||
found_pronouns.clear(); | ||
} | ||
} | ||
} | ||
|
||
lints | ||
} | ||
} | ||
|
||
impl Default for MultipleSequentialPronouns { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::MultipleSequentialPronouns; | ||
use crate::linting::tests::assert_lint_count; | ||
|
||
#[test] | ||
fn can_detect_two_pronouns() { | ||
assert_lint_count( | ||
"...little bit about my I want to do.", | ||
MultipleSequentialPronouns::new(), | ||
1 | ||
) | ||
} | ||
|
||
#[test] | ||
fn can_detect_three_pronouns() { | ||
assert_lint_count( | ||
"...little bit about my I you want to do.", | ||
MultipleSequentialPronouns::new(), | ||
1 | ||
) | ||
} | ||
|
||
#[test] | ||
fn allows_single_pronouns() { | ||
assert_lint_count( | ||
"...little bit about I want to do.", | ||
MultipleSequentialPronouns::new(), | ||
0 | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters