-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b3f9c62
commit 113bc36
Showing
8 changed files
with
246 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
macro_rules! merge_linters { | ||
($name:ident => $($linter:ident),* => $desc:expr) => { | ||
pub use merge_rule_hidden::$name; | ||
|
||
mod merge_rule_hidden { | ||
use paste::paste; | ||
use crate::{Document, linting::{Lint, Linter}}; | ||
|
||
$( | ||
use super::$linter; | ||
)* | ||
|
||
paste! { | ||
#[derive(Default)] | ||
pub struct $name { | ||
$( | ||
[< $linter:snake >]: $linter, | ||
)* | ||
} | ||
|
||
impl Linter for $name { | ||
fn lint(&mut self, document: &Document) -> Vec<Lint>{ | ||
let mut lints = Vec::new(); | ||
|
||
$( | ||
lints.extend(self.[< $linter:snake >].lint(document)); | ||
)* | ||
|
||
lints | ||
} | ||
|
||
fn description(&self) -> &'static str { | ||
$desc | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
|
||
pub(crate) use merge_linters; |
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
70 changes: 70 additions & 0 deletions
70
harper-core/src/linting/pronoun_contraction/avoid_contraction.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,70 @@ | ||
use crate::{ | ||
patterns::{Pattern, SequencePattern}, | ||
Token, | ||
}; | ||
|
||
use super::super::{Lint, LintKind, PatternLinter, Suggestion}; | ||
|
||
pub struct AvoidContraction { | ||
pattern: Box<dyn Pattern>, | ||
} | ||
|
||
impl Default for AvoidContraction { | ||
fn default() -> Self { | ||
let pattern = SequencePattern::aco("you're").then_whitespace().then_noun(); | ||
|
||
Self { | ||
pattern: Box::new(pattern), | ||
} | ||
} | ||
} | ||
|
||
impl PatternLinter for AvoidContraction { | ||
fn pattern(&self) -> &dyn Pattern { | ||
self.pattern.as_ref() | ||
} | ||
|
||
fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Lint { | ||
let word = matched_tokens[0].span.get_content(source); | ||
|
||
Lint { | ||
span: matched_tokens[0].span, | ||
lint_kind: LintKind::WordChoice, | ||
suggestions: vec![Suggestion::replace_with_match_case( | ||
vec!['y', 'o', 'u', 'r'], | ||
word, | ||
)], | ||
message: "I appears you intended to use the possessive version of this word".to_owned(), | ||
priority: 63, | ||
} | ||
} | ||
|
||
fn description(&self) -> &'static str { | ||
"This rule looks for situations where a contraction was used where it shouldn't." | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::linting::tests::assert_suggestion_result; | ||
|
||
use super::AvoidContraction; | ||
|
||
#[test] | ||
fn issue_139() { | ||
assert_suggestion_result( | ||
"it would be great if you're PR was merged into tower-lsp", | ||
AvoidContraction::default(), | ||
"it would be great if your PR was merged into tower-lsp", | ||
); | ||
} | ||
|
||
#[test] | ||
fn car() { | ||
assert_suggestion_result( | ||
"You're car is black.", | ||
AvoidContraction::default(), | ||
"Your car is black.", | ||
); | ||
} | ||
} |
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,9 @@ | ||
use super::merge_linters::merge_linters; | ||
|
||
mod avoid_contraction; | ||
mod should_contract; | ||
|
||
use avoid_contraction::AvoidContraction; | ||
use should_contract::ShouldContract; | ||
|
||
merge_linters! {PronounContraction => ShouldContract, AvoidContraction => "Choosing when to contract pronouns is a challenging art. This rule looks for faults." } |
82 changes: 82 additions & 0 deletions
82
harper-core/src/linting/pronoun_contraction/should_contract.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,82 @@ | ||
use crate::{ | ||
patterns::{Pattern, SequencePattern, WordSet}, | ||
CharStringExt, Token, | ||
}; | ||
|
||
use crate::linting::{LintKind, PatternLinter, Suggestion}; | ||
use crate::Lint; | ||
|
||
pub struct ShouldContract { | ||
pattern: Box<dyn Pattern>, | ||
} | ||
|
||
impl Default for ShouldContract { | ||
fn default() -> Self { | ||
Self { | ||
pattern: Box::new( | ||
SequencePattern::default() | ||
.then_word_set(WordSet::all(&["your", "were"])) | ||
.then_whitespace() | ||
.t_aco("the") | ||
.then_whitespace() | ||
.then_noun(), | ||
), | ||
} | ||
} | ||
} | ||
|
||
impl ShouldContract { | ||
fn mistake_to_correct(mistake: &str) -> impl Iterator<Item = Vec<char>> { | ||
match mistake.to_lowercase().as_str() { | ||
"your" => vec!["you're", "you are"], | ||
"were" => vec!["we're", "we are"], | ||
_ => panic!("The pattern in this linter should make a fall-through impossible."), | ||
} | ||
.into_iter() | ||
.map(|v| v.chars().collect()) | ||
} | ||
} | ||
|
||
impl PatternLinter for ShouldContract { | ||
fn pattern(&self) -> &dyn Pattern { | ||
self.pattern.as_ref() | ||
} | ||
|
||
fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Lint { | ||
let mistake = matched_tokens[0].span.get_content(source); | ||
|
||
Lint { | ||
span: matched_tokens[0].span, | ||
lint_kind: LintKind::WordChoice, | ||
suggestions: Self::mistake_to_correct(&mistake.to_lower().to_string()) | ||
.map(|v| Suggestion::replace_with_match_case(v, mistake)) | ||
.collect(), | ||
message: "Use the contraction or separate the words instead.".to_string(), | ||
priority: 31, | ||
} | ||
} | ||
|
||
fn description(&self) -> &'static str { | ||
"Neglecting the apostrophe when contracting pronouns with \"are\" (like \"your\" and \"you are\") is a fatal, but extremely common mistake to make." | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::ShouldContract; | ||
use crate::linting::tests::assert_suggestion_result; | ||
|
||
#[test] | ||
fn issue_225() { | ||
assert_suggestion_result("Your the man", ShouldContract::default(), "You're the man"); | ||
} | ||
|
||
#[test] | ||
fn were_team() { | ||
assert_suggestion_result( | ||
"Were the best team.", | ||
ShouldContract::default(), | ||
"We're the best team.", | ||
); | ||
} | ||
} |
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
Nitpicking and humor: I wouldn't have used a contraction in the description of a rule that aims to avoid contractions