use crate::checkstyle::api::ast::DetailAst;
use std::sync::{Arc, Mutex};
#[derive(Debug)]
pub struct DetailAstImpl {
pub token_type: i32,
pub text: String,
pub line_no: usize,
pub column_no: usize,
pub parent: Option<Arc<DetailAstImpl>>,
pub first_child: Arc<Mutex<Option<Arc<DetailAstImpl>>>>,
pub next_sibling: Arc<Mutex<Option<Arc<DetailAstImpl>>>>,
}
impl DetailAstImpl {
pub fn new(token_type: i32, text: String, line_no: usize, column_no: usize) -> Self {
Self {
token_type,
text,
line_no,
column_no,
parent: None,
first_child: Arc::new(Mutex::new(None)),
next_sibling: Arc::new(Mutex::new(None)),
}
}
pub fn set_first_child(&self, child: Option<Arc<DetailAstImpl>>) {
*self.first_child.lock().unwrap() = child;
}
pub fn set_next_sibling(&self, sibling: Option<Arc<DetailAstImpl>>) {
*self.next_sibling.lock().unwrap() = sibling;
}
pub fn get_first_child_arc(&self) -> Option<Arc<DetailAstImpl>> {
self.first_child.lock().unwrap().clone()
}
pub fn get_next_sibling_arc(&self) -> Option<Arc<DetailAstImpl>> {
self.next_sibling.lock().unwrap().clone()
}
}
impl DetailAst for DetailAstImpl {
fn get_child_count(&self) -> usize {
let mut count = 0;
let first_child_guard = self.first_child.lock().unwrap();
let mut child_opt = first_child_guard.clone();
drop(first_child_guard);
while let Some(child) = child_opt {
count += 1;
let next_guard = child.next_sibling.lock().unwrap();
child_opt = next_guard.clone();
}
count
}
fn get_child_count_by_type(&self, token_type: i32) -> usize {
let mut count = 0;
let first_child_guard = self.first_child.lock().unwrap();
let mut child_opt = first_child_guard.clone();
drop(first_child_guard);
while let Some(child) = child_opt {
if child.token_type == token_type {
count += 1;
}
let next_guard = child.next_sibling.lock().unwrap();
child_opt = next_guard.clone();
}
count
}
fn get_parent_arc(&self) -> Option<Arc<dyn DetailAst>> {
self.parent
.as_ref()
.map(|p| p.clone() as Arc<dyn DetailAst>)
}
fn get_text(&self) -> &str {
&self.text
}
fn get_type(&self) -> i32 {
self.token_type
}
fn get_line_no(&self) -> usize {
self.line_no
}
fn get_column_no(&self) -> usize {
self.column_no
}
fn get_last_child_arc(&self) -> Option<Arc<dyn DetailAst>> {
let first_child_guard = self.first_child.lock().unwrap();
let mut child_opt = first_child_guard.clone();
drop(first_child_guard);
let mut last_child: Option<Arc<DetailAstImpl>> = None;
while let Some(child) = child_opt {
last_child = Some(child.clone());
let next_guard = child.next_sibling.lock().unwrap();
child_opt = next_guard.clone();
}
last_child.map(|c| c as Arc<dyn DetailAst>)
}
fn get_previous_sibling_arc(&self) -> Option<Arc<dyn DetailAst>> {
None
}
fn find_first_token_arc(&self, token_type: i32) -> Option<Arc<dyn DetailAst>> {
let first_child_guard = self.first_child.lock().unwrap();
let mut child_opt = first_child_guard.clone();
drop(first_child_guard);
while let Some(child) = child_opt {
if child.token_type == token_type {
return Some(child as Arc<dyn DetailAst>);
}
if let Some(found) = child.find_first_token_arc(token_type) {
return Some(found);
}
let next_guard = child.next_sibling.lock().unwrap();
child_opt = next_guard.clone();
}
None
}
fn get_next_sibling_arc(&self) -> Option<Arc<dyn DetailAst>> {
let next_sibling_guard = self.next_sibling.lock().unwrap();
next_sibling_guard
.as_ref()
.map(|s| s.clone() as Arc<dyn DetailAst>)
}
fn get_first_child_arc(&self) -> Option<Arc<dyn DetailAst>> {
let first_child_guard = self.first_child.lock().unwrap();
first_child_guard
.as_ref()
.map(|c| c.clone() as Arc<dyn DetailAst>)
}
}