use std::collections::BTreeMap;
use clang::Type;
use codehelion_helper::ir::ResolvedType;
use crate::types::category;
use super::identity;
#[derive(Default)]
pub(super) struct TypeTable {
at: BTreeMap<String, u32>,
resolved: Vec<ResolvedType>,
}
impl TypeTable {
pub(super) fn intern(&mut self, ty: Type<'_>) -> u32 {
let canonical = ty.get_canonical_type();
let display = canonical.get_display_name();
if let Some(index) = self.at.get(&display) {
return *index;
}
let index = u32::try_from(self.resolved.len()).unwrap_or(u32::MAX);
self.at.insert(display.clone(), index);
self.resolved.push(ResolvedType {
display,
category: category(ty),
arguments: Vec::new(),
definition: canonical.get_declaration().map(identity),
});
let arguments = self.arguments(canonical);
if let Some(recorded) = self.resolved.get_mut(index as usize) {
recorded.arguments = arguments;
}
index
}
fn arguments(&mut self, ty: Type<'_>) -> Vec<u32> {
if let Some(pointee) = ty.get_pointee_type() {
return vec![self.intern(pointee)];
}
if let Some(element) = ty.get_element_type() {
return vec![self.intern(element)];
}
ty.get_template_argument_types()
.unwrap_or_default()
.into_iter()
.flatten()
.map(|argument| self.intern(argument))
.collect()
}
pub(super) fn into_vec(self) -> Vec<ResolvedType> {
self.resolved
}
}