use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
use crate::{decl_engine::DeclEngine, type_system::TypeId, CompileResult, Engines, TypeEngine};
use sway_types::{Ident, Span};
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub struct LogId(usize);
impl std::ops::Deref for LogId {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl LogId {
pub fn new(index: usize) -> LogId {
LogId(index)
}
}
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub struct MessageId(usize);
impl std::ops::Deref for MessageId {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl MessageId {
pub fn new(index: usize) -> MessageId {
MessageId(index)
}
}
#[allow(clippy::enum_variant_names)]
pub enum TypeMetadata {
UnresolvedType(Ident, Option<Span>),
LoggedType(LogId, TypeId),
MessageType(MessageId, TypeId),
}
pub struct CollectTypesMetadataContext<'cx> {
log_id_counter: usize,
message_id_counter: usize,
call_site_spans: Vec<Arc<Mutex<HashMap<TypeId, Span>>>>,
pub(crate) type_engine: &'cx TypeEngine,
pub(crate) decl_engine: &'cx DeclEngine,
}
impl<'cx> CollectTypesMetadataContext<'cx> {
pub fn log_id_counter(&self) -> usize {
self.log_id_counter
}
pub fn log_id_counter_mut(&mut self) -> &mut usize {
&mut self.log_id_counter
}
pub fn message_id_counter(&self) -> usize {
self.message_id_counter
}
pub fn message_id_counter_mut(&mut self) -> &mut usize {
&mut self.message_id_counter
}
pub fn call_site_push(&mut self) {
self.call_site_spans
.push(Arc::new(Mutex::new(HashMap::new())));
}
pub fn call_site_pop(&mut self) {
self.call_site_spans.pop();
}
pub fn call_site_insert(&mut self, type_id: TypeId, span: Span) {
self.call_site_spans
.last()
.and_then(|h| h.lock().ok())
.and_then(|mut l| l.insert(type_id, span));
}
pub fn call_site_get(&mut self, type_id: &TypeId) -> Option<Span> {
for lock in self.call_site_spans.iter() {
if let Ok(hash_map) = lock.lock() {
let opt = hash_map.get(type_id).cloned();
if opt.is_some() {
return opt;
}
}
}
None
}
pub fn new(engines: Engines<'cx>) -> Self {
let (type_engine, decl_engine) = engines.unwrap();
let mut ctx = Self {
type_engine,
decl_engine,
log_id_counter: 0,
message_id_counter: 0,
call_site_spans: vec![],
};
ctx.call_site_push();
ctx
}
}
pub(crate) trait CollectTypesMetadata {
fn collect_types_metadata(
&self,
ctx: &mut CollectTypesMetadataContext,
) -> CompileResult<Vec<TypeMetadata>>;
}