use alloc::string::String;
use crate::{
ast::{
Alias, AttributeSet, Constant, FunctionType, Ident, Invoke, Procedure, TypeDecl, Visibility,
},
debuginfo::{SourceSpan, Span, Spanned},
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Export {
Procedure(Procedure),
Constant(Constant),
Type(TypeDecl),
Alias(Alias),
}
impl Export {
pub fn with_docs(self, docs: Option<Span<String>>) -> Self {
match self {
Self::Procedure(item) => Self::Procedure(item.with_docs(docs)),
Self::Constant(item) => Self::Constant(item.with_docs(docs)),
Self::Type(item) => Self::Type(item.with_docs(docs)),
Self::Alias(item) => Self::Alias(item.with_docs(docs)),
}
}
pub fn name(&self) -> &Ident {
match self {
Self::Procedure(item) => item.name().as_ref(),
Self::Constant(item) => &item.name,
Self::Type(item) => item.name(),
Self::Alias(item) => item.name(),
}
}
pub fn docs(&self) -> Option<&str> {
match self {
Self::Procedure(item) => item.docs().map(|spanned| spanned.into_inner()),
Self::Constant(item) => item.docs().map(|spanned| spanned.into_inner()),
Self::Type(item) => item.docs().map(|spanned| spanned.into_inner()),
Self::Alias(item) => item.docs().map(|spanned| spanned.into_inner()),
}
}
pub fn attributes(&self) -> Option<&AttributeSet> {
match self {
Self::Procedure(proc) => Some(proc.attributes()),
Self::Constant(_) | Self::Type(_) | Self::Alias(_) => None,
}
}
pub fn visibility(&self) -> Visibility {
match self {
Self::Procedure(item) => item.visibility(),
Self::Constant(item) => item.visibility,
Self::Type(item) => item.visibility(),
Self::Alias(item) => item.visibility(),
}
}
pub fn signature(&self) -> Option<&FunctionType> {
match self {
Self::Procedure(item) => item.signature(),
Self::Constant(_) | Self::Type(_) | Self::Alias(_) => None,
}
}
pub fn num_locals(&self) -> usize {
match self {
Self::Procedure(proc) => proc.num_locals() as usize,
Self::Constant(_) | Self::Type(_) | Self::Alias(_) => 0,
}
}
pub fn is_main(&self) -> bool {
self.name().as_str() == Ident::MAIN
}
#[track_caller]
pub fn unwrap_procedure(&self) -> &Procedure {
match self {
Self::Procedure(item) => item,
Self::Constant(_) => panic!("attempted to unwrap constant as procedure definition"),
Self::Type(_) => panic!("attempted to unwrap type as procedure definition"),
Self::Alias(_) => panic!("attempted to unwrap alias as procedure definition"),
}
}
pub fn invoked<'a, 'b: 'a>(&'b self) -> impl Iterator<Item = &'a Invoke> + 'a {
use crate::ast::procedure::InvokedIter;
match self {
Self::Procedure(item) if item.invoked.is_empty() => InvokedIter::Empty,
Self::Procedure(item) => InvokedIter::NonEmpty(item.invoked.iter()),
Self::Constant(_) | Self::Type(_) | Self::Alias(_) => InvokedIter::Empty,
}
}
}
impl crate::prettier::PrettyPrint for Export {
fn render(&self) -> crate::prettier::Document {
match self {
Self::Procedure(item) => item.render(),
Self::Constant(item) => item.render(),
Self::Type(item) => item.render(),
Self::Alias(item) => item.render(),
}
}
}
impl Spanned for Export {
fn span(&self) -> SourceSpan {
match self {
Self::Procedure(spanned) => spanned.span(),
Self::Constant(spanned) => spanned.span(),
Self::Type(spanned) => spanned.span(),
Self::Alias(spanned) => spanned.span(),
}
}
}