use crate::checkstyle::api::ast::DetailAst;
use std::sync::Arc;
pub fn has_modifier(ast: &dyn DetailAst, modifier_type: i32) -> bool {
if let Some(modifiers) = ast.find_first_token_arc(crate::checkstyle::api::ast::token_types::MODIFIERS) {
return modifiers.find_first_token_arc(modifier_type).is_some();
}
false
}
pub fn is_abstract(ast: &dyn DetailAst) -> bool {
has_modifier(ast, crate::checkstyle::api::ast::token_types::LITERAL_ABSTRACT)
}
pub fn is_static(ast: &dyn DetailAst) -> bool {
has_modifier(ast, crate::checkstyle::api::ast::token_types::LITERAL_STATIC)
}
pub fn is_final(ast: &dyn DetailAst) -> bool {
has_modifier(ast, crate::checkstyle::api::ast::token_types::LITERAL_FINAL)
}
pub fn is_public(ast: &dyn DetailAst) -> bool {
has_modifier(ast, crate::checkstyle::api::ast::token_types::LITERAL_PUBLIC)
}
pub fn is_private(ast: &dyn DetailAst) -> bool {
has_modifier(ast, crate::checkstyle::api::ast::token_types::LITERAL_PRIVATE)
}
pub fn is_protected(ast: &dyn DetailAst) -> bool {
has_modifier(ast, crate::checkstyle::api::ast::token_types::LITERAL_PROTECTED)
}
pub fn get_identifier_name(ast: &dyn DetailAst) -> Option<String> {
if let Some(ident) = ast.find_first_token_arc(crate::checkstyle::api::ast::token_types::IDENT) {
return Some(ident.get_text().to_string());
}
None
}
pub fn is_equals_method(ast: &dyn DetailAst) -> bool {
if ast.get_type() != crate::checkstyle::api::ast::token_types::METHOD_DEF {
return false;
}
if is_static(ast) || is_abstract(ast) {
return false;
}
if let Some(name) = get_identifier_name(ast) {
if name == "equals" {
if let Some(params) = ast.find_first_token_arc(crate::checkstyle::api::ast::token_types::PARAMETERS)
{
return params.get_child_count() == 1;
}
}
}
false
}
pub fn find_first_token_recursive(
ast: &Arc<dyn DetailAst>,
token_type: i32,
) -> Option<Arc<dyn DetailAst>> {
if ast.get_type() == token_type {
return Some(ast.clone());
}
if let Some(child) = ast.get_first_child_arc() {
if let Some(found) = find_first_token_recursive(&child, token_type) {
return Some(found);
}
let mut sibling = child.get_next_sibling_arc();
while let Some(s) = sibling {
if let Some(found) = find_first_token_recursive(&s, token_type) {
return Some(found);
}
sibling = s.get_next_sibling_arc();
}
}
None
}
pub fn get_first_node(ast: &Arc<dyn DetailAst>) -> Arc<dyn DetailAst> {
let mut current_node = ast.clone();
if let Some(child) = ast.get_first_child_arc() {
let first_child_node = get_first_node(&child);
if is_before_in_source(&first_child_node, ¤t_node) {
current_node = first_child_node;
}
let mut sibling = child.get_next_sibling_arc();
while let Some(s) = sibling {
let sibling_first = get_first_node(&s);
if is_before_in_source(&sibling_first, ¤t_node) {
current_node = sibling_first;
}
sibling = s.get_next_sibling_arc();
}
}
current_node
}
pub fn get_last_node(ast: &Arc<dyn DetailAst>) -> Arc<dyn DetailAst> {
let mut current_node = ast.clone();
if let Some(child) = ast.get_last_child_arc() {
let last_child_node = get_last_node(&child);
if !is_before_in_source(&last_child_node, ¤t_node) {
current_node = last_child_node;
}
}
current_node
}
pub fn are_on_same_line(ast1: &Arc<dyn DetailAst>, ast2: &Arc<dyn DetailAst>) -> bool {
ast1.get_line_no() == ast2.get_line_no()
}
pub fn is_before_in_source(ast1: &Arc<dyn DetailAst>, ast2: &Arc<dyn DetailAst>) -> bool {
ast1.get_line_no() < ast2.get_line_no()
|| (are_on_same_line(ast1, ast2) && ast1.get_column_no() < ast2.get_column_no())
}