feat(core): create rule to catch Me and <PRON> (#2245)

This commit is contained in:
Elijah Potter
2025-11-28 12:14:11 -07:00
committed by GitHub
parent d9299b5e63
commit addb5bf441
4 changed files with 164 additions and 2 deletions

View File

@@ -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);

View File

@@ -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;

View 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.",
);
}
}

View File

@@ -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| {