use super::trivia::{Trivia, TriviaToken};
use crate::span::Span;
use crate::syntax::ast::Child;
#[derive(Default, Clone, Copy)]
pub struct NodeWidths {
pub id: usize,
pub ty: usize,
}
pub fn child_widths(children: &[Child], trivia: &[TriviaToken]) -> Vec<NodeWidths> {
let mut out = vec![NodeWidths::default(); children.len()];
for group in split_groups(children, trivia) {
let mut w = NodeWidths::default();
for &i in &group {
if let Child::Box(n) = &children[i] {
if let Some(id) = &n.id {
w.id = w.id.max(id.len());
}
if let Some(ty) = &n.ty {
w.ty = w.ty.max(ty.len() + 2); }
}
}
for i in group {
out[i] = w;
}
}
out
}
fn split_groups(children: &[Child], trivia: &[TriviaToken]) -> Vec<Vec<usize>> {
if children.is_empty() {
return Vec::new();
}
let mut groups: Vec<Vec<usize>> = vec![vec![0]];
for i in 1..children.len() {
let prev_end = child_span(&children[i - 1]).end;
let curr_start = child_span(&children[i]).start;
let blank = trivia.iter().any(|t| {
matches!(t.kind, Trivia::BlankLine) && t.pos >= prev_end && t.pos < curr_start
});
if blank {
groups.push(vec![i]);
} else {
groups.last_mut().unwrap().push(i);
}
}
groups
}
fn child_span(c: &Child) -> Span {
match c {
Child::Box(n) => n.span,
Child::Text(t) => t.span,
}
}