use super::span::Span;
use super::trivia::{TrailingComment, Trivia, TriviaPiece};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Annotated<T> {
pub pre_trivia: Trivia,
pub span: Span,
pub value: T,
pub trail_comment: Option<TrailingComment>,
}
impl<T> Annotated<T> {
pub fn has_trivia(&self) -> bool {
!self.pre_trivia.is_empty() || self.trail_comment.is_some()
}
}
impl<T: Clone> Annotated<T> {
pub fn move_trailing_comment_up(&self) -> Self {
let mut out = self.clone();
if let Some(tc) = out.trail_comment.take() {
out.pre_trivia.push(TriviaPiece::from(&tc));
}
out
}
}
pub struct TriviaSlot<'a> {
pub pre_trivia: &'a Trivia,
pub trail_comment: &'a Option<TrailingComment>,
}
pub struct TriviaSlotMut<'a> {
pub pre_trivia: &'a mut Trivia,
pub trail_comment: &'a mut Option<TrailingComment>,
}
impl<'a, T> From<&'a Annotated<T>> for TriviaSlot<'a> {
fn from(a: &'a Annotated<T>) -> Self {
TriviaSlot {
pre_trivia: &a.pre_trivia,
trail_comment: &a.trail_comment,
}
}
}
impl<'a, T> From<&'a mut Annotated<T>> for TriviaSlotMut<'a> {
fn from(a: &'a mut Annotated<T>) -> Self {
TriviaSlotMut {
pre_trivia: &mut a.pre_trivia,
trail_comment: &mut a.trail_comment,
}
}
}
pub trait FirstToken {
fn first_token(&self) -> TriviaSlot<'_>;
fn first_token_mut(&mut self) -> TriviaSlotMut<'_>;
}
macro_rules! first_token_arm {
(leaf, $rec:ident, $e:expr) => {
$e.into()
};
(recurse, $rec:ident, $e:expr) => {
$e.$rec()
};
}
macro_rules! first_token_impl {
($ty:ty; $($pat:pat => $kind:ident $e:expr),+ $(,)?) => {
impl $crate::ast::FirstToken for $ty {
fn first_token(&self) -> $crate::ast::TriviaSlot<'_> {
match self { $($pat => first_token_arm!($kind, first_token, $e),)+ }
}
fn first_token_mut(&mut self) -> $crate::ast::TriviaSlotMut<'_> {
match self { $($pat => first_token_arm!($kind, first_token_mut, $e),)+ }
}
}
};
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Trailed<T> {
pub value: T,
pub trailing_trivia: Trivia,
}