use super::{Expression, Spanned};
use crate::{
expression::Identifier,
visitor::{VisitWith, Visitor, VisitorMut},
};
use boa_interner::{Interner, ToInternedString};
use core::ops::ControlFlow;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Clone, Debug, PartialEq)]
pub enum PropertyName {
Literal(Identifier),
Computed(Expression),
}
impl PropertyName {
#[must_use]
pub const fn literal(&self) -> Option<Identifier> {
if let Self::Literal(ident) = self {
Some(*ident)
} else {
None
}
}
#[must_use]
pub const fn computed(&self) -> Option<&Expression> {
if let Self::Computed(expr) = self {
Some(expr)
} else {
None
}
}
#[must_use]
pub fn prop_name(&self) -> Option<Identifier> {
match self {
Self::Literal(ident) => Some(*ident),
Self::Computed(Expression::Literal(lit)) => lit
.as_string()
.map(|value| Identifier::new(value, lit.span())),
Self::Computed(_) => None,
}
}
}
impl ToInternedString for PropertyName {
fn to_interned_string(&self, interner: &Interner) -> String {
match self {
Self::Literal(key) => interner.resolve_expect(key.sym()).to_string(),
Self::Computed(key) => format!("[{}]", key.to_interned_string(interner)),
}
}
}
impl From<Identifier> for PropertyName {
fn from(name: Identifier) -> Self {
Self::Literal(name)
}
}
impl From<Expression> for PropertyName {
fn from(name: Expression) -> Self {
Self::Computed(name)
}
}
impl VisitWith for PropertyName {
fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: Visitor<'a>,
{
match self {
Self::Literal(ident) => visitor.visit_sym(ident.sym_ref()),
Self::Computed(expr) => visitor.visit_expression(expr),
}
}
fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: VisitorMut<'a>,
{
match self {
Self::Literal(ident) => visitor.visit_sym_mut(ident.sym_mut()),
Self::Computed(expr) => visitor.visit_expression_mut(expr),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum MethodDefinitionKind {
Get,
Set,
Ordinary,
Generator,
AsyncGenerator,
Async,
}