#[cfg(feature = "serde")]
use serde::Serialize;
use crate::Span;
use super::{ArenaVec, Attribute, Block, Comment, Expr, Ident, Name, TypeHint};
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct FunctionDecl<'arena, 'src> {
pub name: Ident<'src>,
pub params: ArenaVec<'arena, Param<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub missing_param_list: bool,
pub body: &'arena Block<'arena, 'src>,
pub return_type: Option<TypeHint<'arena, 'src>>,
pub by_ref: bool,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> FunctionDecl<'arena, 'src> {
pub fn new(
arena: &'arena bumpalo::Bump,
name: Ident<'src>,
body: &'arena Block<'arena, 'src>,
) -> Self {
Self {
name,
params: ArenaVec::new_in(arena),
missing_param_list: false,
body,
return_type: None,
by_ref: false,
attributes: ArenaVec::new_in(arena),
doc_comment: None,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct Param<'arena, 'src> {
pub name: Ident<'src>,
pub type_hint: Option<TypeHint<'arena, 'src>>,
pub default: Option<Expr<'arena, 'src>>,
pub by_ref: bool,
pub variadic: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
pub modifiers: Modifiers,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "ArenaVec::is_empty"))]
pub hooks: ArenaVec<'arena, PropertyHook<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub empty_hook_list: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
pub span: Span,
}
impl<'arena, 'src> Param<'arena, 'src> {
pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>, span: Span) -> Self {
Self {
name,
type_hint: None,
default: None,
by_ref: false,
variadic: false,
modifiers: Modifiers::new(),
attributes: ArenaVec::new_in(arena),
hooks: ArenaVec::new_in(arena),
empty_hook_list: false,
doc_comment: None,
span,
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct Modifiers {
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub visibility: Option<Visibility>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub set_visibility: Option<Visibility>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub is_static: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub is_abstract: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub is_final: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub is_readonly: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub is_var: bool,
}
impl Modifiers {
pub const fn new() -> Self {
Self {
visibility: None,
set_visibility: None,
is_static: false,
is_abstract: false,
is_final: false,
is_readonly: false,
is_var: false,
}
}
pub fn is_empty(&self) -> bool {
*self == Self::new()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub enum Visibility {
Public,
Protected,
Private,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ClassBody<'arena, 'src> {
pub members: ArenaVec<'arena, ClassMember<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip))]
pub span: Span,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct ClassDecl<'arena, 'src> {
pub name: Option<Ident<'src>>,
pub modifiers: ClassModifiers,
pub extends: Option<Name<'arena, 'src>>,
pub implements: ArenaVec<'arena, Name<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(flatten))]
pub body: ClassBody<'arena, 'src>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> ClassDecl<'arena, 'src> {
pub fn new(
arena: &'arena bumpalo::Bump,
name: Option<Ident<'src>>,
body: ClassBody<'arena, 'src>,
) -> Self {
Self {
name,
modifiers: ClassModifiers::default(),
extends: None,
implements: ArenaVec::new_in(arena),
body,
attributes: ArenaVec::new_in(arena),
doc_comment: None,
}
}
}
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct ClassModifiers {
pub is_abstract: bool,
pub is_final: bool,
pub is_readonly: bool,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ClassMember<'arena, 'src> {
pub kind: ClassMemberKind<'arena, 'src>,
pub span: Span,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub enum ClassMemberKind<'arena, 'src> {
Property(PropertyDecl<'arena, 'src>),
Method(MethodDecl<'arena, 'src>),
ClassConst(ClassConstDecl<'arena, 'src>),
TraitUse(TraitUseDecl<'arena, 'src>),
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct PropertyDecl<'arena, 'src> {
pub name: Ident<'src>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
pub modifiers: Modifiers,
pub type_hint: Option<TypeHint<'arena, 'src>>,
pub default: Option<Expr<'arena, 'src>>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "ArenaVec::is_empty"))]
pub hooks: ArenaVec<'arena, PropertyHook<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub empty_hook_list: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> PropertyDecl<'arena, 'src> {
pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>) -> Self {
Self {
name,
modifiers: Modifiers::new(),
type_hint: None,
default: None,
attributes: ArenaVec::new_in(arena),
hooks: ArenaVec::new_in(arena),
empty_hook_list: false,
doc_comment: None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub enum PropertyHookKind {
Get,
Set,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub enum PropertyHookBody<'arena, 'src> {
Block(&'arena Block<'arena, 'src>),
Expression(Expr<'arena, 'src>),
Abstract,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct PropertyHook<'arena, 'src> {
pub kind: PropertyHookKind,
pub body: PropertyHookBody<'arena, 'src>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
pub modifiers: Modifiers,
pub by_ref: bool,
pub params: ArenaVec<'arena, Param<'arena, 'src>>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
pub span: Span,
}
impl<'arena, 'src> PropertyHook<'arena, 'src> {
pub fn new(
arena: &'arena bumpalo::Bump,
kind: PropertyHookKind,
body: PropertyHookBody<'arena, 'src>,
span: Span,
) -> Self {
Self {
kind,
body,
modifiers: Modifiers::new(),
by_ref: false,
params: ArenaVec::new_in(arena),
attributes: ArenaVec::new_in(arena),
span,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct MethodDecl<'arena, 'src> {
pub name: Ident<'src>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
pub modifiers: Modifiers,
pub by_ref: bool,
pub params: ArenaVec<'arena, Param<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
pub missing_param_list: bool,
pub return_type: Option<TypeHint<'arena, 'src>>,
pub body: Option<&'arena Block<'arena, 'src>>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> MethodDecl<'arena, 'src> {
pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>) -> Self {
Self {
name,
modifiers: Modifiers::new(),
by_ref: false,
params: ArenaVec::new_in(arena),
missing_param_list: false,
return_type: None,
body: None,
attributes: ArenaVec::new_in(arena),
doc_comment: None,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct ClassConstDecl<'arena, 'src> {
pub name: Ident<'src>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
pub modifiers: Modifiers,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub type_hint: Option<&'arena TypeHint<'arena, 'src>>,
pub value: Expr<'arena, 'src>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> ClassConstDecl<'arena, 'src> {
pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>, value: Expr<'arena, 'src>) -> Self {
Self {
name,
modifiers: Modifiers::new(),
type_hint: None,
value,
attributes: ArenaVec::new_in(arena),
doc_comment: None,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct TraitUseDecl<'arena, 'src> {
pub traits: ArenaVec<'arena, Name<'arena, 'src>>,
pub adaptations: ArenaVec<'arena, TraitAdaptation<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip))]
#[doc(hidden)]
pub adaptations_brace_span: Option<Span>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> TraitUseDecl<'arena, 'src> {
pub fn new(arena: &'arena bumpalo::Bump, traits: ArenaVec<'arena, Name<'arena, 'src>>) -> Self {
Self {
traits,
adaptations: ArenaVec::new_in(arena),
adaptations_brace_span: None,
doc_comment: None,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct TraitAdaptation<'arena, 'src> {
pub kind: TraitAdaptationKind<'arena, 'src>,
pub span: Span,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub enum TraitAdaptationKind<'arena, 'src> {
Precedence {
trait_name: Name<'arena, 'src>,
method: Name<'arena, 'src>,
insteadof: ArenaVec<'arena, Name<'arena, 'src>>,
},
Alias {
trait_name: Option<Name<'arena, 'src>>,
method: Name<'arena, 'src>,
new_modifier: Option<Visibility>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
is_final: bool,
new_name: Option<Name<'arena, 'src>>,
},
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct InterfaceDecl<'arena, 'src> {
pub name: Ident<'src>,
pub extends: ArenaVec<'arena, Name<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(flatten))]
pub body: ClassBody<'arena, 'src>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> InterfaceDecl<'arena, 'src> {
pub fn new(
arena: &'arena bumpalo::Bump,
name: Ident<'src>,
body: ClassBody<'arena, 'src>,
) -> Self {
Self {
name,
extends: ArenaVec::new_in(arena),
body,
attributes: ArenaVec::new_in(arena),
doc_comment: None,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct TraitDecl<'arena, 'src> {
pub name: Ident<'src>,
#[cfg_attr(feature = "serde", serde(flatten))]
pub body: ClassBody<'arena, 'src>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> TraitDecl<'arena, 'src> {
pub fn new(
arena: &'arena bumpalo::Bump,
name: Ident<'src>,
body: ClassBody<'arena, 'src>,
) -> Self {
Self {
name,
body,
attributes: ArenaVec::new_in(arena),
doc_comment: None,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct EnumBody<'arena, 'src> {
pub members: ArenaVec<'arena, EnumMember<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip))]
pub span: Span,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct EnumDecl<'arena, 'src> {
pub name: Ident<'src>,
pub scalar_type: Option<Name<'arena, 'src>>,
pub implements: ArenaVec<'arena, Name<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(flatten))]
pub body: EnumBody<'arena, 'src>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> EnumDecl<'arena, 'src> {
pub fn new(
arena: &'arena bumpalo::Bump,
name: Ident<'src>,
body: EnumBody<'arena, 'src>,
) -> Self {
Self {
name,
scalar_type: None,
implements: ArenaVec::new_in(arena),
body,
attributes: ArenaVec::new_in(arena),
doc_comment: None,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct EnumMember<'arena, 'src> {
pub kind: EnumMemberKind<'arena, 'src>,
pub span: Span,
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub enum EnumMemberKind<'arena, 'src> {
Case(EnumCase<'arena, 'src>),
Method(MethodDecl<'arena, 'src>),
ClassConst(ClassConstDecl<'arena, 'src>),
TraitUse(TraitUseDecl<'arena, 'src>),
Property(PropertyDecl<'arena, 'src>),
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[non_exhaustive]
pub struct EnumCase<'arena, 'src> {
pub name: Ident<'src>,
pub value: Option<Expr<'arena, 'src>>,
pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub doc_comment: Option<Comment<'src>>,
}
impl<'arena, 'src> EnumCase<'arena, 'src> {
pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>) -> Self {
Self {
name,
value: None,
attributes: ArenaVec::new_in(arena),
doc_comment: None,
}
}
}