Skip to content

Commit

Permalink
feat(core): detect improper contraction usage before verbs
Browse files Browse the repository at this point in the history
  • Loading branch information
elijah-potter committed Jan 22, 2025
1 parent a605aec commit 663f717
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 20 deletions.
1 change: 1 addition & 0 deletions harper-core/dictionary.dict
Original file line number Diff line number Diff line change
Expand Up @@ -47557,6 +47557,7 @@ usurp/4SDRZG
usurpation/1M
usurper/1M
usury/1M
us/8
utensil/1SM
uteri/1
uterine/51
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{
patterns::{Pattern, SequencePattern, WordSet},
patterns::{Pattern, SequencePattern},
Token, TokenStringExt,
};

use super::{Lint, LintKind, PatternLinter, Suggestion};
use crate::linting::{Lint, LintKind, PatternLinter, Suggestion};

pub struct LetUsRedundancy {
pattern: Box<dyn Pattern>,
Expand All @@ -13,7 +13,7 @@ impl Default for LetUsRedundancy {
fn default() -> Self {
let pattern = SequencePattern::aco("let's")
.then_whitespace()
.then_word_set(WordSet::all(&["us", "me"]));
.then_pronoun();

Self {
pattern: Box::new(pattern),
Expand Down Expand Up @@ -41,15 +41,3 @@ impl PatternLinter for LetUsRedundancy {
"Many are not aware that the contraction `let's` is short for `let us`. As a result, many will incorrectly use it before a pronoun, such as in the phrase `let's us do`."
}
}

#[cfg(test)]
mod tests {
use crate::linting::tests::assert_suggestion_result;

use super::LetUsRedundancy;

#[test]
fn issue_426() {
assert_suggestion_result("let's us do", LetUsRedundancy::default(), "let's do");
}
}
30 changes: 30 additions & 0 deletions harper-core/src/linting/lets_confusion/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
mod let_us_redundancy;
mod no_contraction_with_verb;

use super::merge_linters::merge_linters;
use let_us_redundancy::LetUsRedundancy;
use no_contraction_with_verb::NoContractionWithVerb;

merge_linters!(LetsConfusion => LetUsRedundancy, NoContractionWithVerb => "TODO");

#[cfg(test)]
mod tests {
use crate::linting::tests::assert_suggestion_result;

use super::LetsConfusion;

#[test]
fn issue_426_us() {
assert_suggestion_result("let's us do", LetsConfusion::default(), "let's do");
}

#[test]
fn issue_426_me() {
assert_suggestion_result("let's me do", LetsConfusion::default(), "let's do");
}

#[test]
fn from_harper_docs() {
assert_suggestion_result("Often the longest and the shortest words are the most helpful, so lets push them first.", LetsConfusion::default(), "Often the longest and the shortest words are the most helpful, so let's push them first.");
}
}
47 changes: 47 additions & 0 deletions harper-core/src/linting/lets_confusion/no_contraction_with_verb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::{
linting::{Lint, LintKind, Suggestion},
patterns::{Pattern, SequencePattern},
Token,
};

use crate::linting::PatternLinter;

pub struct NoContractionWithVerb {
pattern: Box<dyn Pattern>,
}

impl Default for NoContractionWithVerb {
fn default() -> Self {
let pattern = SequencePattern::aco("lets").then_whitespace().then_verb();

Self {
pattern: Box::new(pattern),
}
}
}

impl PatternLinter for NoContractionWithVerb {
fn pattern(&self) -> &dyn Pattern {
self.pattern.as_ref()
}

fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Lint {
let problem_span = matched_tokens.first().unwrap().span;
let template = problem_span.get_content(source);

Lint {
span: problem_span,
lint_kind: LintKind::WordChoice,
suggestions: vec![
Suggestion::replace_with_match_case_str("let's", template),
Suggestion::replace_with_match_case_str("let us", template),
],
message: "It seems you forgot to include a subject here.".to_owned(),
priority: 31,
}
}

fn description(&self) -> &'static str {
"Make sure you include a subject."
}
}
6 changes: 3 additions & 3 deletions harper-core/src/linting/lint_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::capitalize_personal_pronouns::CapitalizePersonalPronouns;
use super::correct_number_suffix::CorrectNumberSuffix;
use super::dot_initialisms::DotInitialisms;
use super::ellipsis_length::EllipsisLength;
use super::let_us_redundancy::LetUsRedundancy;
use super::lets_confusion::LetsConfusion;
use super::linking_verbs::LinkingVerbs;
use super::long_sentences::LongSentences;
use super::matcher::Matcher;
Expand Down Expand Up @@ -190,8 +190,8 @@ create_lint_group_config!(
OxfordComma => true,
PronounContraction => true,
CurrencyPlacement => true,
LetUsRedundancy => true,
SomewhatSomething => true
SomewhatSomething => true,
LetsConfusion => true
);

impl<T: Dictionary + Default> Default for LintGroup<T> {
Expand Down
4 changes: 2 additions & 2 deletions harper-core/src/linting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod currency_placement;
mod dashes;
mod dot_initialisms;
mod ellipsis_length;
mod let_us_redundancy;
mod lets_confusion;
mod linking_verbs;
mod lint;
mod lint_group;
Expand Down Expand Up @@ -42,7 +42,7 @@ pub use correct_number_suffix::CorrectNumberSuffix;
pub use currency_placement::CurrencyPlacement;
pub use dot_initialisms::DotInitialisms;
pub use ellipsis_length::EllipsisLength;
pub use let_us_redundancy::LetUsRedundancy;
pub use lets_confusion::LetsConfusion;
pub use linking_verbs::LinkingVerbs;
pub use lint::{Lint, LintKind, Suggestion};
pub use lint_group::{LintGroup, LintGroupConfig};
Expand Down
1 change: 1 addition & 0 deletions harper-core/tests/run_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ create_test!(amazon_hostname.md, 0);
create_test!(issue_159.md, 1);
create_test!(issue_358.md, 0);
create_test!(issue_195.md, 0);
create_test!(pr_452.md, 2);

// Make sure it doesn't panic
create_test!(lukas_homework.md, 3);
1 change: 1 addition & 0 deletions harper-core/tests/test_sources/pr_452.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Lets go and check if this lint let's us catch this class of errors.

0 comments on commit 663f717

Please sign in to comment.