use mago_interner::ThreadedInterner;
use serde::Deserialize;
use serde::Serialize;
use mago_interner::StringIdentifier;
use mago_span::Span;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct Name {
pub value: StringIdentifier,
pub span: Span,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub enum ClassLikeName {
Class(Name),
Interface(Name),
Enum(Name),
Trait(Name),
AnonymousClass(Span),
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct ClassLikeMemberName {
pub class_like: ClassLikeName,
pub member: Name,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub enum FunctionLikeName {
Function(Name),
Method(ClassLikeName, Name),
PropertyHook(ClassLikeName, Name, Name),
Closure(Span),
ArrowFunction(Span),
}
impl Name {
pub fn new(value: StringIdentifier, span: Span) -> Self {
Self { value, span }
}
}
impl ClassLikeName {
pub fn inner(&self) -> Option<&Name> {
match self {
ClassLikeName::Class(name) => Some(name),
ClassLikeName::Interface(name) => Some(name),
ClassLikeName::Enum(name) => Some(name),
ClassLikeName::Trait(name) => Some(name),
ClassLikeName::AnonymousClass(_) => None,
}
}
pub fn get_key(&self, interner: &ThreadedInterner) -> String {
match self {
ClassLikeName::Class(name)
| ClassLikeName::Interface(name)
| ClassLikeName::Enum(name)
| ClassLikeName::Trait(name) => interner.lookup(&name.value).to_string(),
ClassLikeName::AnonymousClass(span) => {
format!(
"anonymous-class@{}:{}-{}",
interner.lookup(&span.start.source.0),
span.start.offset,
span.end.offset
)
}
}
}
}
impl ClassLikeMemberName {
pub fn get_key(&self, interner: &ThreadedInterner) -> String {
let class_name = self.class_like.get_key(interner);
let member_name = interner.lookup(&self.member.value);
format!("{}::{}", class_name, member_name)
}
}
impl FunctionLikeName {
pub fn get_key(&self, interner: &ThreadedInterner) -> String {
match self {
FunctionLikeName::Function(name) => interner.lookup(&name.value).to_string(),
FunctionLikeName::Method(class_like_name, name) => {
let class_name = class_like_name.get_key(interner);
format!("{}::{}", class_name, interner.lookup(&name.value))
}
FunctionLikeName::PropertyHook(class_like_name, property_name, name) => {
let class_name = class_like_name.get_key(interner);
format!("{}::{}::{}", class_name, interner.lookup(&property_name.value), interner.lookup(&name.value))
}
FunctionLikeName::Closure(span) => {
format!("closure@{}:{}-{}", interner.lookup(&span.start.source.0), span.start.offset, span.end.offset)
}
FunctionLikeName::ArrowFunction(span) => {
format!(
"arrow-function@{}:{}-{}",
interner.lookup(&span.start.source.0),
span.start.offset,
span.end.offset
)
}
}
}
}
impl std::cmp::PartialEq<StringIdentifier> for Name {
fn eq(&self, other: &StringIdentifier) -> bool {
self.value == *other
}
}
impl std::cmp::PartialEq<Name> for StringIdentifier {
fn eq(&self, other: &Name) -> bool {
*self == other.value
}
}
impl std::cmp::PartialEq<StringIdentifier> for ClassLikeName {
fn eq(&self, other: &StringIdentifier) -> bool {
match self {
ClassLikeName::Class(id) => id == other,
ClassLikeName::Interface(id) => id == other,
ClassLikeName::Enum(id) => id == other,
ClassLikeName::Trait(id) => id == other,
ClassLikeName::AnonymousClass(_) => false,
}
}
}
impl std::cmp::PartialEq<ClassLikeName> for StringIdentifier {
fn eq(&self, other: &ClassLikeName) -> bool {
other == self
}
}