feat: brandish→brand (#2325)

* feat: brandish→brand

* fix: sort `mod`s

* fix: exclude 3 pronouns; variation tests
This commit is contained in:
Andrew Dunbar 2025-12-11 18:23:27 +00:00 committed by GitHub
parent 3fa856a68c
commit 86edc6e34f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 205 additions and 0 deletions

View file

@ -0,0 +1,202 @@
use crate::{
Lint, Token, TokenKind,
expr::{Expr, SequenceExpr},
linting::{ExprLinter, LintKind, Suggestion, expr_linter::Chunk},
};
pub struct BrandBrandish {
expr: Box<dyn Expr>,
}
impl Default for BrandBrandish {
fn default() -> Self {
Self {
expr: Box::new(
SequenceExpr::word_set(&["brandish", "brandished", "brandishes", "brandishing"])
.t_ws()
// "her" is also a possessive determiner as in "she brandished her sword"
// "it" and "them" can refer to objects as in "draw your sword(s) and brandish it/them"
.then_kind_except(TokenKind::is_object_pronoun, &["her", "it", "them"]),
),
}
}
}
impl ExprLinter for BrandBrandish {
type Unit = Chunk;
fn expr(&self) -> &dyn Expr {
self.expr.as_ref()
}
fn match_to_lint(&self, toks: &[Token], src: &[char]) -> Option<Lint> {
let verb_span = toks.first()?.span;
let verb_chars = verb_span.get_content(src);
enum Form {
Base,
Past,
ThirdPerson,
Ing,
}
let infl = match verb_chars.last().map(|c| c.to_ascii_lowercase()) {
Some('h') => Form::Base,
Some('d') => Form::Past,
Some('s') => Form::ThirdPerson,
Some('g') => Form::Ing,
_ => return None,
};
Some(Lint {
span: verb_span,
lint_kind: LintKind::Malapropism,
suggestions: vec![Suggestion::replace_with_match_case_str(
match infl {
Form::Base => "brand",
Form::Past => "branded",
Form::ThirdPerson => "brands",
Form::Ing => "branding",
},
verb_chars,
)],
message: "`Brandish` means to wield a weapon. You probably mean `brand`.".to_string(),
..Default::default()
})
}
fn description(&self) -> &str {
"Looks for `brandish` wrongly used when `brand` is intended."
}
}
#[cfg(test)]
mod tests {
use crate::linting::{brand_brandish::BrandBrandish, tests::assert_suggestion_result};
#[test]
fn correct_brandish_a_traitor() {
assert_suggestion_result(
"Unretire Gretzky's sweater . Brandish him a traitor.",
BrandBrandish::default(),
"Unretire Gretzky's sweater . Brand him a traitor.",
);
}
#[test]
fn correct_brandish_a_criminal() {
assert_suggestion_result(
"lied to stop kuma's ideology from taking root and to brandish him a criminal that they could arrest",
BrandBrandish::default(),
"lied to stop kuma's ideology from taking root and to brand him a criminal that they could arrest",
);
}
#[test]
fn correct_brandish_as_a() {
assert_suggestion_result(
"he was so afraid his thoughts could brandish him as a paedophile",
BrandBrandish::default(),
"he was so afraid his thoughts could brand him as a paedophile",
);
}
#[test]
fn correct_brandish_an_offender() {
assert_suggestion_result(
"Chanel Oberlin's reason for purposely leading on Pete Martinez in order to humiliate him and brandish him a registered sex offender",
BrandBrandish::default(),
"Chanel Oberlin's reason for purposely leading on Pete Martinez in order to humiliate him and brand him a registered sex offender",
);
}
#[test]
fn correct_brandish_with_nicknames() {
assert_suggestion_result(
"?? spoke out over the move by Kenyans to continuously brandish him with nicknames even after ...",
BrandBrandish::default(),
"?? spoke out over the move by Kenyans to continuously brand him with nicknames even after ...",
);
}
#[test]
fn correct_brandish_as_a_aymbol() {
assert_suggestion_result(
"brandish him as an acclaimed symbol of humility, integrity and incorruptibility in the face of today's corrupt economic and political elite1",
BrandBrandish::default(),
"brand him as an acclaimed symbol of humility, integrity and incorruptibility in the face of today's corrupt economic and political elite1",
);
}
#[test]
fn correct_brandish_as_illegal() {
assert_suggestion_result(
"To attempt to brandish him as an “illegal immigrant” is absolutely ridiculous and warrants an immediate retraction and apology.",
BrandBrandish::default(),
"To attempt to brand him as an “illegal immigrant” is absolutely ridiculous and warrants an immediate retraction and apology.",
);
}
#[test]
fn correct_brandish_with_nickname() {
assert_suggestion_result(
"The small minded townsfolk brandish him with the nickname \"Genepool\" due to his physical and cognitive shortcomings.",
BrandBrandish::default(),
"The small minded townsfolk brand him with the nickname \"Genepool\" due to his physical and cognitive shortcomings.",
);
}
#[test]
fn correct_brandish_with_label() {
assert_suggestion_result(
"One such reason that critics brandish him with this label is due to Peterson's opposition to Canada's Bill C-16",
BrandBrandish::default(),
"One such reason that critics brand him with this label is due to Peterson's opposition to Canada's Bill C-16",
);
}
#[test]
fn correct_brandished_us() {
assert_suggestion_result(
"The mark they brandished us with will fade to dust when we finally meet our end.",
BrandBrandish::default(),
"The mark they branded us with will fade to dust when we finally meet our end.",
)
}
#[test]
fn correct_brandishing_him() {
assert_suggestion_result(
"he said some words trying to hit back at the center for brandishing him as a Pakistani at an NRC rally",
BrandBrandish::default(),
"he said some words trying to hit back at the center for branding him as a Pakistani at an NRC rally",
)
}
#[test]
fn correct_brandish_us() {
assert_suggestion_result(
"Our resolute determination for the ultimate quality and all-inclusive directory of food commodities brandish us as a flawless associate in B2B",
BrandBrandish::default(),
"Our resolute determination for the ultimate quality and all-inclusive directory of food commodities brand us as a flawless associate in B2B",
)
}
#[test]
fn correct_brandished_him() {
assert_suggestion_result(
"Frank discovers Myra brandished him with the letter 'R', for rapist.",
BrandBrandish::default(),
"Frank discovers Myra branded him with the letter 'R', for rapist.",
)
}
#[test]
fn correct_brandishes_him() {
assert_suggestion_result(
"Whether one turns a blind eye to Tim's wrongs or brandishes him a traitor will plant audiences in their own personal line in the sand.",
BrandBrandish::default(),
"Whether one turns a blind eye to Tim's wrongs or brands him a traitor will plant audiences in their own personal line in the sand.",
)
}
}

View file

@ -34,6 +34,7 @@ use super::be_allowed::BeAllowed;
use super::best_of_all_time::BestOfAllTime;
use super::boring_words::BoringWords;
use super::bought::Bought;
use super::brand_brandish::BrandBrandish;
use super::cant::Cant;
use super::capitalize_personal_pronouns::CapitalizePersonalPronouns;
use super::cautionary_tale::CautionaryTale;
@ -507,6 +508,7 @@ impl LintGroup {
insert_expr_rule!(BeAllowed, true);
insert_expr_rule!(BestOfAllTime, true);
insert_expr_rule!(BoringWords, false);
insert_expr_rule!(BrandBrandish, true);
insert_expr_rule!(Bought, true);
insert_expr_rule!(Cant, true);
insert_struct_rule!(CapitalizePersonalPronouns, true);

View file

@ -25,6 +25,7 @@ mod be_allowed;
mod best_of_all_time;
mod boring_words;
mod bought;
mod brand_brandish;
mod call_them;
mod cant;
mod capitalize_personal_pronouns;