use mago_database::file::File;
use mago_span::HasSpan;
use crate::ast::Program;
use crate::ast::Trivia;
use crate::ast::TriviaKind;
#[inline]
pub fn get_docblock_for_node<'arena>(
program: &'arena Program<'arena>,
file: &File,
node: impl HasSpan,
) -> Option<&'arena Trivia<'arena>> {
get_docblock_before_position(file, program.trivia.as_slice(), node.span().start.offset)
}
pub fn get_docblock_before_position<'arena>(
file: &File,
trivias: &'arena [Trivia<'arena>],
node_start_offset: u32,
) -> Option<&'arena Trivia<'arena>> {
let candidate_partition_idx = trivias.partition_point(|trivia| trivia.span.start.offset < node_start_offset);
if candidate_partition_idx == 0 {
return None;
}
let mut covered_from = node_start_offset;
for i in (0..candidate_partition_idx).rev() {
let trivia = &trivias[i];
let trivia_end = trivia.span.end_offset();
let gap_slice = file.contents.as_bytes().get(trivia_end as usize..covered_from as usize).unwrap_or(&[]);
if !gap_slice.iter().all(u8::is_ascii_whitespace) {
return None;
}
match trivia.kind {
TriviaKind::DocBlockComment => {
return Some(trivia);
}
TriviaKind::WhiteSpace
| TriviaKind::SingleLineComment
| TriviaKind::MultiLineComment
| TriviaKind::HashComment => {
covered_from = trivia.span.start_offset();
}
}
}
None
}