mago_reflection/class_like/
inheritance.rsuse ahash::HashMap;
use ahash::HashSet;
use mago_interner::StringIdentifier;
use mago_interner::ThreadedInterner;
use serde::Deserialize;
use serde::Serialize;
use crate::identifier::ClassLikeName;
use crate::identifier::Name;
use super::ClassLikeReflection;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Default)]
pub struct InheritanceReflection {
pub direct_implemented_interfaces: HashSet<Name>,
pub all_implemented_interfaces: HashSet<Name>,
pub direct_extended_class: Option<Name>,
pub all_extended_classes: HashSet<Name>,
pub direct_extended_interfaces: HashSet<Name>,
pub all_extended_interfaces: HashSet<Name>,
pub require_implementations: HashSet<StringIdentifier>,
pub require_extensions: HashSet<StringIdentifier>,
pub children: HashSet<ClassLikeName>,
pub names: HashMap<StringIdentifier, Name>,
}
impl InheritanceReflection {
pub fn implements_interfaces(&self) -> bool {
!self.all_implemented_interfaces.is_empty()
}
pub fn extends_classes(&self) -> bool {
!self.all_extended_classes.is_empty()
}
pub fn has_children(&self) -> bool {
!self.children.is_empty()
}
pub fn is_instance_of(&self, interner: &ThreadedInterner, other: &ClassLikeReflection) -> bool {
let Some(other_name) = other.name.inner() else {
return false;
};
let other_identifier = interner.lowered(&other_name.value);
if let Some(this_name) = self.direct_extended_class {
let this_identifier = interner.lowered(&this_name.value);
if this_identifier == other_identifier {
return true;
}
}
let Some(other_fqcn) = self.names.get(&other_identifier) else {
return false;
};
self.all_extended_classes.contains(other_fqcn)
|| self.all_implemented_interfaces.contains(other_fqcn)
|| self.all_extended_interfaces.contains(other_fqcn)
}
pub fn extends_class(&self, interner: &ThreadedInterner, other: &ClassLikeReflection) -> bool {
let Some(name) = other.name.inner() else {
return false; };
let identifier = interner.lowered(&name.value);
let Some(other) = self.names.get(&identifier) else {
return false; };
self.all_extended_classes.contains(other)
}
pub fn extends_interface(&self, interner: &ThreadedInterner, other: &ClassLikeReflection) -> bool {
let Some(name) = other.name.inner() else {
return false;
};
let identifier = interner.lowered(&name.value);
let Some(other) = self.names.get(&identifier) else {
return false;
};
self.all_extended_interfaces.contains(other)
}
pub fn implements_interface(&self, interner: &ThreadedInterner, other: &ClassLikeReflection) -> bool {
let Some(name) = other.name.inner() else {
return false;
};
let identifier = interner.lowered(&name.value);
let Some(other) = self.names.get(&identifier) else {
return false;
};
self.all_implemented_interfaces.contains(other)
}
}