use super::{punctuated::Punctuated, span::ContainedSpan, *};
use crate::util::display_option;
use derive_more::Display;
#[derive(Clone, Debug, Display, PartialEq, Owned, Node)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum TypeInfo<'a> {
#[display(fmt = "{}{}{}", "braces.tokens().0", "type_info", "braces.tokens().1")]
Array {
#[cfg_attr(feature = "serde", serde(borrow))]
braces: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
type_info: Box<TypeInfo<'a>>,
},
#[display(fmt = "{}", "_0")]
Basic(#[cfg_attr(feature = "serde", serde(borrow))] Cow<'a, TokenReference<'a>>),
#[display(
fmt = "{}{}{}{}{}",
"parentheses.tokens().0",
"arguments",
"parentheses.tokens().1",
"arrow",
"return_type"
)]
Callback {
#[cfg_attr(feature = "serde", serde(borrow))]
parentheses: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
arguments: Punctuated<'a, TypeInfo<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
arrow: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
return_type: Box<TypeInfo<'a>>,
},
#[display(
fmt = "{}{}{}{}",
"base",
"arrows.tokens().0",
"generics",
"arrows.tokens().1"
)]
Generic {
#[cfg_attr(feature = "serde", serde(borrow))]
base: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
arrows: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
generics: Punctuated<'a, TypeInfo<'a>>,
},
#[display(fmt = "{}{}{}", "left", "ampersand", "right")]
Intersection {
#[cfg_attr(feature = "serde", serde(borrow))]
left: Box<TypeInfo<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
ampersand: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
right: Box<TypeInfo<'a>>,
},
#[display(fmt = "{}{}{}", "module", "punctuation", "type_info")]
Module {
#[cfg_attr(feature = "serde", serde(borrow))]
module: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
punctuation: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
type_info: Box<IndexedTypeInfo<'a>>,
},
#[display(fmt = "{}{}", "base", "question_mark")]
Optional {
#[cfg_attr(feature = "serde", serde(borrow))]
base: Box<TypeInfo<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
question_mark: Cow<'a, TokenReference<'a>>,
},
#[display(fmt = "{}{}{}", "braces.tokens().0", "fields", "braces.tokens().1")]
Table {
#[cfg_attr(feature = "serde", serde(borrow))]
braces: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
fields: Punctuated<'a, TypeField<'a>>,
},
#[display(
fmt = "{}{}{}{}",
"typeof_token",
"parentheses.tokens().0",
"inner",
"parentheses.tokens().1"
)]
Typeof {
#[cfg_attr(feature = "serde", serde(borrow))]
typeof_token: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
parentheses: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
inner: Box<Expression<'a>>,
},
#[display(
fmt = "{}{}{}",
"parentheses.tokens().0",
"types",
"parentheses.tokens().1"
)]
Tuple {
#[cfg_attr(feature = "serde", serde(borrow))]
parentheses: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
types: Punctuated<'a, TypeInfo<'a>>,
},
#[display(fmt = "{}{}{}", "left", "pipe", "right")]
Union {
#[cfg_attr(feature = "serde", serde(borrow))]
left: Box<TypeInfo<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pipe: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
right: Box<TypeInfo<'a>>,
},
}
#[derive(Clone, Debug, Display, PartialEq, Owned, Node)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum IndexedTypeInfo<'a> {
#[display(fmt = "{}", "_0")]
Basic(#[cfg_attr(feature = "serde", serde(borrow))] Cow<'a, TokenReference<'a>>),
#[display(
fmt = "{}{}{}{}",
"base",
"arrows.tokens().0",
"generics",
"arrows.tokens().1"
)]
Generic {
#[cfg_attr(feature = "serde", serde(borrow))]
base: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
arrows: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
generics: Punctuated<'a, TypeInfo<'a>>,
},
}
#[derive(Clone, Debug, Display, PartialEq, Owned, Node, Visit)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[display(fmt = "{}{}{}", "key", "colon", "value")]
pub struct TypeField<'a> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) key: TypeFieldKey<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) colon: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) value: TypeInfo<'a>,
}
impl<'a> TypeField<'a> {
pub fn key(&self) -> &TypeFieldKey<'a> {
&self.key
}
pub fn colon_token(&self) -> &TokenReference<'a> {
&self.colon
}
pub fn value(&self) -> &TypeInfo<'a> {
&self.value
}
pub fn with_key(self, key: TypeFieldKey<'a>) -> Self {
Self { key, ..self }
}
pub fn with_colon_token(self, colon_token: Cow<'a, TokenReference<'a>>) -> Self {
Self {
colon: colon_token,
..self
}
}
pub fn with_value(self, value: TypeInfo<'a>) -> Self {
Self { value, ..self }
}
}
#[derive(Clone, Debug, Display, PartialEq, Owned, Node)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum TypeFieldKey<'a> {
#[display(fmt = "{}", "_0")]
Name(Cow<'a, TokenReference<'a>>),
#[display(fmt = "{}{}{}", "brackets.tokens().0", "inner", "brackets.tokens().1")]
IndexSignature {
#[cfg_attr(feature = "serde", serde(borrow))]
brackets: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
inner: TypeInfo<'a>,
},
}
#[derive(Clone, Debug, Display, PartialEq, Owned, Node, Visit)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[display(fmt = "{}{}", "as_token", "cast_to")]
pub struct AsAssertion<'a> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) as_token: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) cast_to: TypeInfo<'a>,
}
impl<'a> AsAssertion<'a> {
pub fn as_token(&self) -> &TokenReference<'a> {
&self.as_token
}
pub fn cast_to(&self) -> &TypeInfo<'a> {
&self.cast_to
}
pub fn with_as_token(self, as_token: Cow<'a, TokenReference<'a>>) -> Self {
Self { as_token, ..self }
}
pub fn with_cast_to(self, cast_to: TypeInfo<'a>) -> Self {
Self { cast_to, ..self }
}
}
#[derive(Clone, Debug, Display, PartialEq, Owned, Node, Visit)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[display(
fmt = "{}{}{}{}{}",
"type_token",
"base",
"display_option(generics)",
"equal_token",
"declare_as"
)]
pub struct TypeDeclaration<'a> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) type_token: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) base: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) generics: Option<GenericDeclaration<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) equal_token: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) declare_as: TypeInfo<'a>,
}
impl<'a> TypeDeclaration<'a> {
pub fn type_token(&self) -> &TokenReference<'a> {
&self.type_token
}
pub fn type_name(&self) -> &TokenReference<'a> {
&self.base
}
pub fn generics(&self) -> Option<&GenericDeclaration<'a>> {
self.generics.as_ref()
}
pub fn equal_token(&self) -> &TokenReference<'a> {
&self.equal_token
}
pub fn type_definition(&self) -> &TypeInfo<'a> {
&self.declare_as
}
pub fn with_type_token(self, type_token: Cow<'a, TokenReference<'a>>) -> Self {
Self { type_token, ..self }
}
pub fn with_type_name(self, type_name: Cow<'a, TokenReference<'a>>) -> Self {
Self {
base: type_name,
..self
}
}
pub fn with_generics(self, generics: Option<GenericDeclaration<'a>>) -> Self {
Self { generics, ..self }
}
pub fn with_equal_token(self, equal_token: Cow<'a, TokenReference<'a>>) -> Self {
Self {
equal_token,
..self
}
}
pub fn with_type_definition(self, type_definition: TypeInfo<'a>) -> Self {
Self {
declare_as: type_definition,
..self
}
}
}
#[derive(Clone, Debug, Display, PartialEq, Owned, Node, Visit)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[display(fmt = "{}{}{}", "arrows.tokens().0", "generics", "arrows.tokens().1")]
pub struct GenericDeclaration<'a> {
#[cfg_attr(feature = "serde", serde(borrow))]
#[visit(contains = "generics")]
pub(crate) arrows: ContainedSpan<'a>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) generics: Punctuated<'a, Cow<'a, TokenReference<'a>>>,
}
impl<'a> GenericDeclaration<'a> {
pub fn arrows(&self) -> &ContainedSpan<'a> {
&self.arrows
}
pub fn generics(&self) -> &Punctuated<'a, Cow<'a, TokenReference<'a>>> {
&self.generics
}
pub fn with_arrows(self, arrows: ContainedSpan<'a>) -> Self {
Self { arrows, ..self }
}
pub fn with_generics(self, generics: Punctuated<'a, Cow<'a, TokenReference<'a>>>) -> Self {
Self { generics, ..self }
}
}
#[derive(Clone, Debug, Display, PartialEq, Owned, Node, Visit)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[display(fmt = "{}{}", "punctuation", "type_info")]
pub struct TypeSpecifier<'a> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) punctuation: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) type_info: TypeInfo<'a>,
}
impl<'a> TypeSpecifier<'a> {
pub fn punctuation(&self) -> &TokenReference<'a> {
&self.punctuation
}
pub fn type_info(&self) -> &TypeInfo<'a> {
&self.type_info
}
pub fn with_punctuation(self, punctuation: Cow<'a, TokenReference<'a>>) -> Self {
Self {
punctuation,
..self
}
}
pub fn with_type_info(self, type_info: TypeInfo<'a>) -> Self {
Self { type_info, ..self }
}
}
#[derive(Clone, Debug, Display, PartialEq, Owned, Node, Visit)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[display(fmt = "{}{}", "export_token", "type_declaration")]
pub struct ExportedTypeDeclaration<'a> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) export_token: Cow<'a, TokenReference<'a>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) type_declaration: TypeDeclaration<'a>,
}
impl<'a> ExportedTypeDeclaration<'a> {
pub fn export_token(&self) -> &TokenReference<'a> {
&self.export_token
}
pub fn type_declaration(&self) -> &TypeDeclaration<'a> {
&self.type_declaration
}
pub fn with_export_token(self, export_token: Cow<'a, TokenReference<'a>>) -> Self {
Self {
export_token,
..self
}
}
pub fn with_type_declaration(self, type_declaration: TypeDeclaration<'a>) -> Self {
Self {
type_declaration,
..self
}
}
}
make_op!(CompoundOp,
#[doc = "Compound operators, such as X += Y or X -= Y"]
{
PlusEqual,
MinusEqual,
StarEqual,
SlashEqual,
PercentEqual,
CaretEqual,
TwoDotsEqual,
}
);
#[derive(Clone, Debug, Display, PartialEq, Owned, Node, Visit)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[display(fmt = "{}{}{}", "lhs", "compound_operator", "rhs")]
pub struct CompoundAssignment<'a> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub(crate) lhs: Var<'a>,
pub(crate) compound_operator: CompoundOp<'a>,
pub(crate) rhs: Expression<'a>,
}
impl<'a> CompoundAssignment<'a> {
pub fn new(lhs: Var<'a>, compound_operator: CompoundOp<'a>, rhs: Expression<'a>) -> Self {
Self {
lhs,
compound_operator,
rhs,
}
}
pub fn lhs(&self) -> &Var<'a> {
&self.lhs
}
pub fn compound_operator(&self) -> &CompoundOp<'a> {
&self.compound_operator
}
pub fn rhs(&self) -> &Expression<'a> {
&self.rhs
}
pub fn with_lhs(self, lhs: Var<'a>) -> Self {
Self { lhs, ..self }
}
pub fn with_compound_operator(self, compound_operator: CompoundOp<'a>) -> Self {
Self {
compound_operator,
..self
}
}
pub fn with_rhs(self, rhs: Expression<'a>) -> Self {
Self { rhs, ..self }
}
}