selene_lib/lints/
parenthese_conditions.rs1use super::*;
2use crate::ast_util::range;
3use std::convert::Infallible;
4
5use full_moon::{
6 ast::{self, Ast},
7 visitors::Visitor,
8};
9
10pub struct ParentheseConditionsLint;
11
12impl Lint for ParentheseConditionsLint {
13 type Config = ();
14 type Error = Infallible;
15
16 const SEVERITY: Severity = Severity::Warning;
17 const LINT_TYPE: LintType = LintType::Style;
18
19 fn new(_: Self::Config) -> Result<Self, Self::Error> {
20 Ok(ParentheseConditionsLint)
21 }
22
23 fn pass(&self, ast: &Ast, _: &Context, _: &AstContext) -> Vec<Diagnostic> {
24 let mut visitor = ParentheseConditionsVisitor {
25 positions: Vec::new(),
26 };
27
28 visitor.visit_ast(ast);
29
30 visitor
31 .positions
32 .iter()
33 .map(|position| {
34 Diagnostic::new(
35 "parenthese_conditions",
36 "lua does not require parentheses around conditions".to_owned(),
37 Label::new(*position),
38 )
39 })
40 .collect()
41 }
42}
43
44struct ParentheseConditionsVisitor {
45 positions: Vec<(usize, usize)>,
46}
47
48impl ParentheseConditionsVisitor {
49 fn lint_condition(&mut self, condition: &ast::Expression) {
50 if matches!(condition, ast::Expression::Parentheses { .. }) {
51 self.positions.push(range(condition));
52 }
53 }
54}
55
56impl Visitor for ParentheseConditionsVisitor {
57 fn visit_if(&mut self, node: &ast::If) {
58 self.lint_condition(node.condition());
59
60 if let Some(else_ifs) = node.else_if() {
61 for else_if in else_ifs {
62 self.lint_condition(else_if.condition());
63 }
64 }
65 }
66
67 fn visit_repeat(&mut self, node: &ast::Repeat) {
68 self.lint_condition(node.until());
69 }
70
71 fn visit_while(&mut self, node: &ast::While) {
72 self.lint_condition(node.condition());
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::{super::test_util::test_lint, *};
79
80 #[test]
81 fn test_parenthese_conditions() {
82 test_lint(
83 ParentheseConditionsLint::new(()).unwrap(),
84 "parenthese_conditions",
85 "parenthese_conditions",
86 );
87 }
88}