use crate::{
Span, Spanned, ToStringEscaped,
visitor::{VisitWith, Visitor, VisitorMut},
};
use boa_interner::{Interner, Sym, ToInternedString};
use core::ops::ControlFlow;
use super::Expression;
pub const RESERVED_IDENTIFIERS_STRICT: [Sym; 9] = [
Sym::IMPLEMENTS,
Sym::INTERFACE,
Sym::LET,
Sym::PACKAGE,
Sym::PRIVATE,
Sym::PROTECTED,
Sym::PUBLIC,
Sym::STATIC,
Sym::YIELD,
];
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Identifier {
ident: Sym,
span: Span,
}
impl PartialEq<Sym> for Identifier {
#[inline]
fn eq(&self, other: &Sym) -> bool {
self.ident == *other
}
}
impl PartialEq<Identifier> for Sym {
#[inline]
fn eq(&self, other: &Identifier) -> bool {
*self == other.ident
}
}
impl Identifier {
#[inline]
#[must_use]
pub const fn new(ident: Sym, span: Span) -> Self {
Self { ident, span }
}
#[inline]
#[must_use]
pub const fn sym(self) -> Sym {
self.ident
}
#[inline]
#[must_use]
pub const fn sym_ref(&self) -> &Sym {
&self.ident
}
#[inline]
#[must_use]
pub const fn sym_mut(&mut self) -> &mut Sym {
&mut self.ident
}
}
impl Spanned for Identifier {
#[inline]
fn span(&self) -> Span {
self.span
}
}
impl ToInternedString for Identifier {
#[inline]
fn to_interned_string(&self, interner: &Interner) -> String {
interner.resolve_expect(self.ident).join(
String::from,
ToStringEscaped::to_string_escaped,
true,
)
}
}
impl From<Identifier> for Expression {
#[inline]
fn from(local: Identifier) -> Self {
Self::Identifier(local)
}
}
impl VisitWith for Identifier {
fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: Visitor<'a>,
{
visitor.visit_sym(&self.ident)
}
fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: VisitorMut<'a>,
{
visitor.visit_sym_mut(&mut self.ident)
}
}