mirror of
https://github.com/Automattic/harper.git
synced 2025-12-05 19:26:55 -06:00
feat(core): create rule to catch Me and <PRON> (#2245)
This commit is contained in:
@@ -156,6 +156,7 @@ use super::spaces::Spaces;
|
||||
use super::spell_check::SpellCheck;
|
||||
use super::spelled_numbers::SpelledNumbers;
|
||||
use super::split_words::SplitWords;
|
||||
use super::subject_pronoun::SubjectPronoun;
|
||||
use super::that_than::ThatThan;
|
||||
use super::that_which::ThatWhich;
|
||||
use super::the_how_why::TheHowWhy;
|
||||
@@ -496,6 +497,7 @@ impl LintGroup {
|
||||
insert_expr_rule!(CautionaryTale, true);
|
||||
insert_expr_rule!(ChangeTack, true);
|
||||
insert_expr_rule!(ChockFull, true);
|
||||
insert_struct_rule!(SubjectPronoun, true);
|
||||
insert_struct_rule!(FindFine, true);
|
||||
insert_struct_rule!(CommaFixes, true);
|
||||
insert_struct_rule!(CompoundNouns, true);
|
||||
|
||||
@@ -166,6 +166,7 @@ mod spaces;
|
||||
mod spell_check;
|
||||
mod spelled_numbers;
|
||||
mod split_words;
|
||||
mod subject_pronoun;
|
||||
mod suggestion;
|
||||
mod take_serious;
|
||||
mod that_than;
|
||||
|
||||
159
harper-core/src/linting/subject_pronoun.rs
Normal file
159
harper-core/src/linting/subject_pronoun.rs
Normal file
@@ -0,0 +1,159 @@
|
||||
use crate::expr::{AnchorStart, Expr, SequenceExpr};
|
||||
use crate::{Token, TokenStringExt};
|
||||
|
||||
use super::expr_linter::Chunk;
|
||||
use super::{ExprLinter, Lint, LintKind, Suggestion};
|
||||
|
||||
pub struct SubjectPronoun {
|
||||
expr: Box<dyn Expr>,
|
||||
}
|
||||
|
||||
impl Default for SubjectPronoun {
|
||||
fn default() -> Self {
|
||||
let expr = SequenceExpr::default()
|
||||
.then(AnchorStart)
|
||||
.t_aco("me")
|
||||
.t_ws()
|
||||
.t_aco("and")
|
||||
.t_ws()
|
||||
.then_proper_noun();
|
||||
|
||||
Self {
|
||||
expr: Box::new(expr),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ExprLinter for SubjectPronoun {
|
||||
type Unit = Chunk;
|
||||
|
||||
fn expr(&self) -> &dyn Expr {
|
||||
self.expr.as_ref()
|
||||
}
|
||||
|
||||
fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Option<Lint> {
|
||||
let span = matched_tokens.span()?;
|
||||
|
||||
let mut suggestion_chars = Vec::new();
|
||||
suggestion_chars.extend_from_slice(matched_tokens.last()?.span.get_content(source));
|
||||
suggestion_chars.extend(" and I".chars());
|
||||
|
||||
Some(Lint {
|
||||
span,
|
||||
lint_kind: LintKind::Grammar,
|
||||
suggestions: vec![Suggestion::ReplaceWith(suggestion_chars)],
|
||||
message: "Put the other person first and use `I` in this compound subject.".to_owned(),
|
||||
priority: 31,
|
||||
})
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"Fixes sentences that start with `me and X` by putting the proper noun first and using `I`."
|
||||
}
|
||||
}
|
||||
|
||||
fn append_token_chars(chars: &mut Vec<char>, token: &Token, source: &[char]) {
|
||||
chars.extend(token.span.get_content(source).iter().copied());
|
||||
}
|
||||
|
||||
fn append_tokens_chars(chars: &mut Vec<char>, tokens: &[Token], source: &[char]) {
|
||||
for token in tokens {
|
||||
append_token_chars(chars, token, source);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::SubjectPronoun;
|
||||
use crate::linting::tests::assert_suggestion_result;
|
||||
|
||||
#[test]
|
||||
fn alex_ladder() {
|
||||
assert_suggestion_result(
|
||||
"Me and Alex carried the huge ladder.",
|
||||
SubjectPronoun::default(),
|
||||
"Alex and I carried the huge ladder.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jordan_lamp() {
|
||||
assert_suggestion_result(
|
||||
"Me and Jordan fixed the broken lamp.",
|
||||
SubjectPronoun::default(),
|
||||
"Jordan and I fixed the broken lamp.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn taylor_crate() {
|
||||
assert_suggestion_result(
|
||||
"Me and Taylor opened the dusty crate.",
|
||||
SubjectPronoun::default(),
|
||||
"Taylor and I opened the dusty crate.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kayla_dog() {
|
||||
assert_suggestion_result(
|
||||
"Me and Kayla chased the noisy dog.",
|
||||
SubjectPronoun::default(),
|
||||
"Kayla and I chased the noisy dog.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn madison_yard() {
|
||||
assert_suggestion_result(
|
||||
"Me and Madison painted the small yard shed.",
|
||||
SubjectPronoun::default(),
|
||||
"Madison and I painted the small yard shed.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn avery_tree() {
|
||||
assert_suggestion_result(
|
||||
"Me and Avery climbed the old tree.",
|
||||
SubjectPronoun::default(),
|
||||
"Avery and I climbed the old tree.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blake_room() {
|
||||
assert_suggestion_result(
|
||||
"Me and Blake cleaned the crowded room.",
|
||||
SubjectPronoun::default(),
|
||||
"Blake and I cleaned the crowded room.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn riley_train() {
|
||||
assert_suggestion_result(
|
||||
"Me and Riley watched the slow train go by.",
|
||||
SubjectPronoun::default(),
|
||||
"Riley and I watched the slow train go by.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cameron_door() {
|
||||
assert_suggestion_result(
|
||||
"Me and Cameron fixed the loose door hinge.",
|
||||
SubjectPronoun::default(),
|
||||
"Cameron and I fixed the loose door hinge.",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jamie_bag() {
|
||||
assert_suggestion_result(
|
||||
"Me and Jamie carried the heavy shopping bag.",
|
||||
SubjectPronoun::default(),
|
||||
"Jamie and I carried the heavy shopping bag.",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ pub struct ModalVerb {
|
||||
impl Default for ModalVerb {
|
||||
fn default() -> Self {
|
||||
let modals = [
|
||||
"can", "could", "may", "might", "must", "shall", "should", "will", "would", "ought",
|
||||
"dare",
|
||||
"can", "can't", "could", "may", "might", "must", "shall", "should", "will", "would",
|
||||
"ought", "dare",
|
||||
];
|
||||
let mut words = WordSet::new(&modals);
|
||||
modals.iter().for_each(|word| {
|
||||
|
||||
Reference in New Issue
Block a user