use crate::{
metadata::{
loader::{LoaderContext, MetadataLoader},
tables::{TableId, TypeDefRaw},
typesystem::CilTypeReference,
},
Error, Result,
};
pub(crate) struct InheritanceResolver;
impl MetadataLoader for InheritanceResolver {
fn load(&self, context: &LoaderContext) -> Result<()> {
if let Some(header) = context.meta {
if let Some(typedef_table) = header.table::<TypeDefRaw>() {
typedef_table
.par_iter()
.try_for_each(|raw_typedef| -> Result<()> {
if raw_typedef.extends.row == 0 {
return Ok(());
}
if let Some(type_def) = context.types.get(&raw_typedef.token) {
match context.get_ref(&raw_typedef.extends) {
CilTypeReference::TypeDef(type_ref)
| CilTypeReference::TypeRef(type_ref)
| CilTypeReference::TypeSpec(type_ref) => {
let base_type_ref = type_ref.upgrade().ok_or_else(|| {
Error::TypeError(format!(
"InheritanceResolver: Type reference was dropped for type {}",
type_def.fullname()
))
})?;
type_def.set_base(&base_type_ref.into())?;
}
_ => {} }
}
Ok(())
})?;
}
}
Ok(())
}
fn table_id(&self) -> Option<TableId> {
None
}
fn dependencies(&self) -> &'static [TableId] {
&[
TableId::TypeDef,
TableId::TypeRef,
TableId::TypeSpec,
TableId::InterfaceImpl,
]
}
}