use crate::expr::{Expr, SequenceExpr};
use crate::linting::expr_linter::Chunk;
use crate::linting::{ExprLinter, Lint, LintKind};
use crate::token::Token;
use crate::token_string_ext::TokenStringExt;
pub struct AllowTo {
exp: SequenceExpr,
}
impl Default for AllowTo {
fn default() -> Self {
Self {
exp: SequenceExpr::word_set(&["allow", "allowing", "allows"])
.t_ws()
.t_aco("to")
.then_optional(SequenceExpr::default().t_ws().then_adverb())
.t_ws()
.then_any_word(),
}
}
}
impl ExprLinter for AllowTo {
type Unit = Chunk;
fn expr(&self) -> &dyn Expr {
&self.exp
}
fn match_to_lint(&self, toks: &[Token], _src: &[char]) -> Option<Lint> {
let span = toks.span()?;
let first = toks.first()?;
let allow = first.get_str(_src);
let message = format!(
"For correct usage, either add a subject between `{allow}` and `to` (e.g., `{allow} someone to do`) or use the present participle (e.g., `{allow} doing`)."
);
Some(Lint {
span,
lint_kind: LintKind::Grammar,
suggestions: vec![],
message,
..Default::default()
})
}
fn description(&self) -> &'static str {
"Flags erroneous usage of `allow to` without a subject."
}
}
#[cfg(test)]
mod tests {
use super::AllowTo;
use crate::linting::tests::{assert_lint_count, assert_no_lints};
#[test]
fn flag_allow_to() {
assert_lint_count(
"Allow to change approval policy during running task # 4394.",
AllowTo::default(),
1,
);
}
#[test]
fn flag_allowing_to() {
assert_lint_count(
"Allowing to have multiple views with different filtering # 952.",
AllowTo::default(),
1,
);
}
#[test]
fn flag_allows_to() {
assert_lint_count(
"It is easily doable for classic IHostBuilder, because its extension allows to pass configure action",
AllowTo::default(),
1,
);
}
#[test]
fn dont_flag_allowed_to() {
assert_no_lints(
"In C and C++ aliasing has to do with what expression types we are allowed to access stored values through.",
AllowTo::default(),
);
}
#[test]
fn dont_flag_allow_pronoun_to() {
assert_no_lints(
"It would be really great to allow me to enter body data using multipart form",
AllowTo::default(),
);
}
#[test]
fn dont_flag_allow_noun_to() {
assert_no_lints(
"Allows users to export SMART statistics from any connected hard drive",
AllowTo::default(),
);
}
#[test]
fn dont_flag_allow_np_to() {
assert_no_lints(
"This vulnerability allows an authenticated attacker to infer data from the database by measuring response times",
AllowTo::default(),
);
}
}