use super::{Context, LintRule};
use crate::ProgramRef;
use deno_ast::swc::ast::{BinExpr, BinaryOp, Expr, IfStmt, ParenExpr, Stmt};
use deno_ast::swc::utils::drop_span;
use deno_ast::swc::visit::{noop_visit_type, VisitAll, VisitAllWith};
use deno_ast::{SourceRange, SourceRangedForSpanned};
use derive_more::Display;
use std::collections::HashSet;
use std::sync::Arc;
#[derive(Debug)]
pub struct NoDupeElseIf;
const CODE: &str = "no-dupe-else-if";
#[derive(Display)]
enum NoDupeElseIfMessage {
#[display(
fmt = "This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain."
)]
Unexpected,
}
#[derive(Display)]
enum NoDupeElseIfHint {
#[display(
fmt = "Remove or rework the `else if` condition which is duplicated"
)]
RemoveOrRework,
}
impl LintRule for NoDupeElseIf {
fn new() -> Arc<Self> {
Arc::new(NoDupeElseIf)
}
fn tags(&self) -> &'static [&'static str] {
&["recommended"]
}
fn code(&self) -> &'static str {
CODE
}
fn lint_program<'view>(
&self,
context: &mut Context<'view>,
program: ProgramRef<'view>,
) {
let mut visitor = NoDupeElseIfVisitor::new(context);
match program {
ProgramRef::Module(m) => m.visit_all_with(&mut visitor),
ProgramRef::Script(s) => s.visit_all_with(&mut visitor),
}
}
#[cfg(feature = "docs")]
fn docs(&self) -> &'static str {
include_str!("../../docs/rules/no_dupe_else_if.md")
}
}
struct NoDupeElseIfVisitor<'c, 'view> {
context: &'c mut Context<'view>,
checked_ranges: HashSet<SourceRange>,
}
impl<'c, 'view> NoDupeElseIfVisitor<'c, 'view> {
fn new(context: &'c mut Context<'view>) -> Self {
Self {
context,
checked_ranges: HashSet::new(),
}
}
}
impl<'c, 'view> VisitAll for NoDupeElseIfVisitor<'c, 'view> {
noop_visit_type!();
fn visit_if_stmt(&mut self, if_stmt: &IfStmt) {
let range = if_stmt.test.range();
if !self.checked_ranges.contains(&range) {
self.checked_ranges.insert(range);
let span_dropped_test = drop_span(if_stmt.test.clone());
let mut appeared_conditions: Vec<Vec<Vec<Expr>>> = Vec::new();
append_test(&mut appeared_conditions, *span_dropped_test);
let mut next = if_stmt.alt.as_ref();
while let Some(cur) = next {
if let Stmt::If(IfStmt {
ref test, ref alt, ..
}) = &**cur
{
let range = test.range();
let span_dropped_test = drop_span(test.clone());
let mut current_condition_to_check: Vec<Vec<Vec<Expr>>> =
mk_condition_to_check(*span_dropped_test.clone())
.into_iter()
.map(split_by_or_then_and)
.collect();
for ap_cond in &appeared_conditions {
current_condition_to_check = current_condition_to_check
.into_iter()
.map(|current_or_operands| {
current_or_operands
.into_iter()
.filter(|current_or_operand| {
!ap_cond.iter().any(|ap_or_operand| {
is_subset(ap_or_operand, current_or_operand)
})
})
.collect()
})
.collect();
if current_condition_to_check
.iter()
.any(|or_operands| or_operands.is_empty())
{
self.context.add_diagnostic_with_hint(
range,
CODE,
NoDupeElseIfMessage::Unexpected,
NoDupeElseIfHint::RemoveOrRework,
);
break;
}
}
self.checked_ranges.insert(range);
append_test(&mut appeared_conditions, *span_dropped_test);
next = alt.as_ref();
} else {
break;
}
}
}
}
}
fn mk_condition_to_check(cond: Expr) -> Vec<Expr> {
match cond {
Expr::Bin(BinExpr { op, .. }) if op == BinaryOp::LogicalAnd => {
let mut c = vec![cond.clone()];
c.append(&mut split_by_and(cond));
c
}
Expr::Paren(ParenExpr { expr, .. }) => mk_condition_to_check(*expr),
_ => vec![cond],
}
}
fn split_by_bin_op(op_to_split: BinaryOp, expr: Expr) -> Vec<Expr> {
match expr {
Expr::Bin(BinExpr {
op, left, right, ..
}) if op == op_to_split => {
let mut ret = split_by_bin_op(op_to_split, *left);
ret.append(&mut split_by_bin_op(op_to_split, *right));
ret
}
Expr::Paren(ParenExpr { expr, .. }) => split_by_bin_op(op_to_split, *expr),
_ => vec![expr],
}
}
fn split_by_or(expr: Expr) -> Vec<Expr> {
split_by_bin_op(BinaryOp::LogicalOr, expr)
}
fn split_by_and(expr: Expr) -> Vec<Expr> {
split_by_bin_op(BinaryOp::LogicalAnd, expr)
}
fn split_by_or_then_and(expr: Expr) -> Vec<Vec<Expr>> {
split_by_or(expr).into_iter().map(split_by_and).collect()
}
fn is_subset(arr_a: &[Expr], arr_b: &[Expr]) -> bool {
arr_a
.iter()
.all(|a| arr_b.iter().any(|b| equal_in_if_else(a, b)))
}
fn equal_in_if_else(expr1: &Expr, expr2: &Expr) -> bool {
use deno_ast::swc::ast::Expr::*;
match (expr1, expr2) {
(Bin(ref bin1), Bin(ref bin2))
if matches!(bin1.op, BinaryOp::LogicalOr | BinaryOp::LogicalAnd)
&& bin1.op == bin2.op =>
{
equal_in_if_else(&bin1.left, &bin2.left)
&& equal_in_if_else(&bin1.right, &bin2.right)
|| equal_in_if_else(&bin1.left, &bin2.right)
&& equal_in_if_else(&bin1.right, &bin2.left)
}
(Paren(ParenExpr { ref expr, .. }), _) => equal_in_if_else(expr, expr2),
(_, Paren(ParenExpr { ref expr, .. })) => equal_in_if_else(expr1, expr),
(This(_), This(_))
| (Array(_), Array(_))
| (Object(_), Object(_))
| (Fn(_), Fn(_))
| (Unary(_), Unary(_))
| (Update(_), Update(_))
| (Bin(_), Bin(_))
| (Assign(_), Assign(_))
| (Member(_), Member(_))
| (Cond(_), Cond(_))
| (Call(_), Call(_))
| (New(_), New(_))
| (Seq(_), Seq(_))
| (Ident(_), Ident(_))
| (Lit(_), Lit(_))
| (Tpl(_), Tpl(_))
| (TaggedTpl(_), TaggedTpl(_))
| (Arrow(_), Arrow(_))
| (Class(_), Class(_))
| (Yield(_), Yield(_))
| (MetaProp(_), MetaProp(_))
| (Await(_), Await(_))
| (JSXMember(_), JSXMember(_))
| (JSXNamespacedName(_), JSXNamespacedName(_))
| (JSXEmpty(_), JSXEmpty(_))
| (JSXElement(_), JSXElement(_))
| (JSXFragment(_), JSXFragment(_))
| (TsTypeAssertion(_), TsTypeAssertion(_))
| (TsConstAssertion(_), TsConstAssertion(_))
| (TsNonNull(_), TsNonNull(_))
| (TsAs(_), TsAs(_))
| (PrivateName(_), PrivateName(_))
| (OptChain(_), OptChain(_))
| (Invalid(_), Invalid(_)) => expr1 == expr2,
_ => false,
}
}
fn append_test(appeared_conditions: &mut Vec<Vec<Vec<Expr>>>, expr: Expr) {
appeared_conditions.push(split_by_or_then_and(expr));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_dupe_else_if_valid() {
assert_lint_ok! {
NoDupeElseIf,
"if (a) {} else if (b) {}",
"if (a); else if (b); else if (c);",
"if (true) {} else if (false) {} else {}",
"if (1) {} else if (2) {}",
"if (f) {} else if (f()) {}",
"if (f(a)) {} else if (g(a)) {}",
"if (f(a)) {} else if (f(b)) {}",
"if (a === 1) {} else if (a === 2) {}",
"if (a === 1) {} else if (b === 1) {}",
"if (a) {}",
"if (a);",
"if (a) {} else {}",
"if (a) if (a) {}",
"if (a) if (a);",
"if (a) { if (a) {} }",
r#"
if (a) {}
else {
if (a) {}
}
"#,
"if (a) {} if (a) {}",
"if (a); if (a);",
"while (a) if (a);",
"if (a); else a ? a : a;",
r#"
if (a) {
if (b) {}
} else if (b) {}
"#,
r#"
if (a) {
if (b !== 1) {}
else if (b !== 2) {}
} else if (c) {}
"#,
"if (a) if (b); else if (a);",
"if (a) {} else if (!!a) {}",
"if (a === 1) {} else if (a === (1)) {}",
"if (a || b) {} else if (c || d) {}",
"if (a || b) {} else if (a || c) {}",
"if (a) {} else if (a || b) {}",
"if (a) {} else if (b) {} else if (a || b || c) {}",
"if (a && b) {} else if (a) {} else if (b) {}",
"if (a && b) {} else if (b && c) {} else if (a && c) {}",
"if (a && b) {} else if (b || c) {}",
"if (a) {} else if (b && (a || c)) {}",
"if (a) {} else if (b && (c || d && a)) {}",
"if (a && b && c) {} else if (a && b && (c || d)) {}",
};
}
#[test]
fn no_dupe_else_if_invalid() {
assert_lint_err! {
NoDupeElseIf,
"if (a) {} else if (a) {} else if (b) {}": [
{
col: 19,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a); else if (a);": [
{
col: 17,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (a) {} else {}": [
{
col: 19,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (a) {} else if (c) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (a) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (c) {} else if (a) {}": [
{
col: 49,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (b) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (b) {} else {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (c) {} else if (b) {}": [
{
col: 49,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a); else if (b); else if (c); else if (b); else if (d); else;": [
{
col: 43,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a); else if (b); else if (c); else if (d); else if (b); else if (e);": [
{
col: 56,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (a) {} else if (a) {}": [
{
col: 19,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
},
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (a) {} else if (b) {} else if (a) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
},
{
col: 49,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
},
{
col: 64,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) { if (b) {} } else if (a) {}": [
{
col: 30,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (this) {} else if (this) {}": [
{
col: 22,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if ([a]) {} else if ([a]) {}": [
{
col: 21,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if ({a: 1}) {} else if ({a: 1}) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (function () {}) {} else if (function () {}) {}": [
{
col: 32,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (!a) {} else if (!a) {}": [
{
col: 20,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (++a) {} else if (++a) {}": [
{
col: 21,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a === 1) {} else if (a === 1) {}": [
{
col: 25,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (1 < a) {} else if (1 < a) {}": [
{
col: 23,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a = b) {} else if (a = b) {}": [
{
col: 23,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a.b) {} else if (a.b) {}": [
{
col: 21,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a[b]) {} else if (a[b]) {}": [
{
col: 22,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a ? 1 : 2) {} else if (a ? 1 : 2) {}": [
{
col: 27,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a()) {} else if (a()) {}": [
{
col: 21,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (new A()) {} else if (new A()) {}": [
{
col: 25,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (true) {} else if (true) {}": [
{
col: 22,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (`a`) {} else if (`a`) {}": [
{
col: 21,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a`b`) {} else if (a`b`) {}": [
{
col: 22,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a => {}) {} else if (a => {}) {}": [
{
col: 25,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (class A {}) {} else if (class A {}) {}": [
{
col: 28,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
r#"
function* foo(a) {
if (yield a) {}
else if (yield a) {}
}
"#: [
{
line: 4,
col: 11,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (new.target) {} else if (new.target) {}": [
{
col: 28,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (await a) {} else if (await a) {}": [
{
col: 25,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if ((a)) {} else if ((a)) {}": [
{
col: 21,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a && b) {} else if (a && b) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a && b || c) {} else if (a && b || c) {}": [
{
col: 30,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (f(a)) {} else if (f(a)) {}": [
{
col: 22,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a === 1) {} else if (a===1) {}": [
{
col: 25,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a === 1) {} else if (a === /* comment */ 1) {}": [
{
col: 25,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a === 1) {} else if ((a === 1)) {}": [
{
col: 25,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b) {} else if (a) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b) {} else if (a) {} else if (b) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
},
{
col: 39,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b) {} else if (b || a) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (a || b) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b) {} else if (c || d) {} else if (a || d) {}": [
{
col: 44,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if ((a === b && fn(c)) || d) {} else if (fn(c) && a === b) {}": [
{
col: 41,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (a && b) {}": [
{
col: 19,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a && b) {} else if (b && a) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a && b) {} else if (a && b && c) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || c) {} else if (a && b || c) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (c && a || b) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (c && (a || b)) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b && c) {} else if (d && (a || e && c && b)) {}": [
{
col: 39,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b && c) {} else if (b && c && d) {}": [
{
col: 29,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b) {} else if (b && c) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if ((a || b) && c) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if ((a && (b || c)) || d) {} else if ((c || b) && e && a) {}": [
{
col: 38,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a && b || b && c) {} else if (a && b && c) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b && c) {} else if (d && (c && e && b || a)) {}": [
{
col: 39,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || (b && (c || d))) {} else if ((d || c) && b) {}": [
{
col: 38,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b) {} else if ((b || a) && c) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b) {} else if (c) {} else if (d) {} else if (b && (a || c)) {}": [
{
col: 54,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b || c) {} else if (a || (b && d) || (c && e)) {}": [
{
col: 29,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || (b || c)) {} else if (a || (b && c)) {}": [
{
col: 31,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || b) {} else if (c) {} else if (d) {} else if ((a || c) && (b || d)) {}": [
{
col: 54,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (b) {} else if (c && (a || d && b)) {}": [
{
col: 34,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (a || a) {}": [
{
col: 19,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || a) {} else if (a || a) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a || a) {} else if (a) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a) {} else if (a && a) {}": [
{
col: 19,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a && a) {} else if (a && a) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
"if (a && a) {} else if (a) {}": [
{
col: 24,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
r#"
if (foo) {
if (a == 1) {}
else if (a == 1) {}
}
"#: [
{
line: 4,
col: 11,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
],
r#"
if (foo) {
if (a == 1) {}
else if (a > 1) {}
} else if (foo) {}
"#: [
{
line: 5,
col: 11,
message: NoDupeElseIfMessage::Unexpected,
hint: NoDupeElseIfHint::RemoveOrRework,
}
]
};
}
}