mod resolve;
mod source;
mod table;
pub use resolve::{FromAnnotation, Resolved};
pub use source::{AnnotationRef, ArgError, ArgErrorKind, FromArgument};
pub use table::{Annotations, SourceAnnotations};
use crate::{
ast::{
node::{root::Root, MapEntry},
Property, RootEntry, Value,
},
span::Span,
};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "span_print", derive(crate::span::DebugSpans))]
pub struct Annotation {
span: Span,
name: Span,
arguments: Vec<Argument>,
}
impl Annotation {
pub(crate) fn new(span: Span, name: Span, arguments: Vec<Argument>) -> Self {
Self {
span,
name,
arguments,
}
}
#[must_use]
pub fn span(&self) -> Span {
self.span
}
#[must_use]
pub fn name(&self) -> Span {
self.name
}
#[must_use]
pub fn arguments(&self) -> &[Argument] {
&self.arguments
}
#[must_use]
pub fn with_source<'a>(&'a self, text: &'a str) -> AnnotationRef<'a> {
AnnotationRef::new(self, text)
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "span_print", derive(crate::span::DebugSpans))]
#[non_exhaustive]
pub enum Argument {
Flag(Span),
Named { name: Span, value: Value },
}
impl Argument {
#[must_use]
pub fn name(&self) -> Span {
match self {
Self::Flag(name) | Self::Named { name, .. } => *name,
}
}
#[must_use]
pub fn span(&self) -> Span {
match self {
Self::Flag(name) => *name,
Self::Named { name, value } => name.cover(value.span()),
}
}
#[must_use]
pub fn value(&self) -> Option<&Value> {
match self {
Self::Flag(_) => None,
Self::Named { value, .. } => Some(value),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "span_print", derive(crate::span::DebugSpans))]
pub struct Attached<A> {
target: Span,
annotation: A,
}
impl<A> Attached<A> {
pub(crate) fn new(target: Span, annotation: A) -> Self {
Self { target, annotation }
}
#[must_use]
pub fn target(&self) -> Span {
self.target
}
#[must_use]
pub fn annotation(&self) -> &A {
&self.annotation
}
#[must_use]
pub fn into_annotation(self) -> A {
self.annotation
}
}
mod sealed {
pub trait Sealed {}
}
pub trait Annotatable: sealed::Sealed {
fn target(&self) -> Span;
}
macro_rules! annotatable {
($($ty:ty => |$this:ident| $target:expr),* $(,)?) => {$(
impl sealed::Sealed for $ty {}
impl Annotatable for $ty {
fn target(&self) -> Span {
let $this = self;
$target
}
}
)*};
}
annotatable! {
Root => |r| r.span(),
RootEntry => |e| e.span(),
Property => |p| p.span(),
MapEntry => |e| e.span(),
Value => |v| v.span(),
Span => |s| *s,
}