use crate::checkstyle::api::ast::DetailAst;
use crate::checkstyle::api::check::Check;
use crate::checkstyle::api::config::{Configurable, Context, Contextualizable};
use crate::checkstyle::api::error::CheckstyleResult;
use crate::checkstyle::checks::base::AbstractCheck;
use crate::checkstyle::utils::ast_util::{are_on_same_line, get_first_node, get_last_node};
pub struct MultipleVariableDeclarationsCheck {
base: AbstractCheck,
}
impl MultipleVariableDeclarationsCheck {
pub fn new() -> Self {
Self {
base: AbstractCheck::new("MultipleVariableDeclarations".to_string()),
}
}
}
impl Default for MultipleVariableDeclarationsCheck {
fn default() -> Self {
Self::new()
}
}
impl Configurable for MultipleVariableDeclarationsCheck {
fn configure(&mut self, config: &crate::checkstyle::api::config::Configuration) -> CheckstyleResult<()> {
self.base.configure(config)
}
}
impl Contextualizable for MultipleVariableDeclarationsCheck {
fn contextualize(&mut self, context: &Context) -> CheckstyleResult<()> {
self.base.contextualize(context)
}
}
impl Check for MultipleVariableDeclarationsCheck {
fn get_default_tokens(&self) -> Vec<i32> {
self.get_required_tokens()
}
fn get_acceptable_tokens(&self) -> Vec<i32> {
self.get_required_tokens()
}
fn get_required_tokens(&self) -> Vec<i32> {
vec![crate::checkstyle::api::ast::token_types::VARIABLE_DEF]
}
fn visit_token(&mut self, ast: &dyn DetailAst) -> CheckstyleResult<()> {
if let Some(next_node_arc) = ast.get_next_sibling_arc() {
let next_type = next_node_arc.get_type();
let is_comma_separated = next_type == crate::checkstyle::api::ast::token_types::COMMA;
let next_var_node =
if is_comma_separated || next_type == crate::checkstyle::api::ast::token_types::SEMI {
next_node_arc.get_next_sibling_arc()
} else {
Some(next_node_arc)
};
if let Some(next_var) = next_var_node {
if next_var.get_type() == crate::checkstyle::api::ast::token_types::VARIABLE_DEF {
if is_comma_separated {
let parent_type = ast.get_parent_arc().map(|p| p.get_type()).unwrap_or(0);
if parent_type != crate::checkstyle::api::ast::token_types::FOR_INIT {
self.base.log_ast(
ast,
"multiple.variable.declarations.comma".to_string(),
vec![],
);
}
} else {
if let Some(ast_first_child) = ast.get_first_child_arc() {
let next_first = get_first_node(&next_var);
let ast_last = get_last_node(&ast_first_child);
if are_on_same_line(&next_first, &ast_last) {
self.base.log_ast(
ast,
"multiple.variable.declarations".to_string(),
vec![],
);
}
} else {
if ast.get_line_no() == next_var.get_line_no() {
self.base.log_ast(
ast,
"multiple.variable.declarations".to_string(),
vec![],
);
}
}
}
}
}
}
Ok(())
}
fn get_violations(&self) -> std::collections::BTreeSet<crate::checkstyle::api::violation::Violation> {
self.base.get_violations()
}
fn clear_violations(&mut self) {
self.base.clear_violations();
}
}