use std::cell::RefCell;
use std::sync::Arc;
use mir_codebase::NamespaceBlock;
use super::MirDatabase;
thread_local! {
static ACTIVE: RefCell<Option<(Arc<str>, u32)>> = const { RefCell::new(None) };
}
pub(crate) struct NsScopeGuard(Option<Option<(Arc<str>, u32)>>);
impl Drop for NsScopeGuard {
fn drop(&mut self) {
if let Some(prev) = self.0.take() {
ACTIVE.with(|a| *a.borrow_mut() = prev);
}
}
}
pub(crate) fn enter(db: &dyn MirDatabase, file: &Arc<str>, offset: u32) -> NsScopeGuard {
if db.file_namespace_blocks(file).is_empty() {
return NsScopeGuard(None);
}
NsScopeGuard(Some(
ACTIVE.with(|a| a.borrow_mut().replace((file.clone(), offset))),
))
}
pub(super) fn active_block(
file: &str,
blocks: impl FnOnce() -> Arc<[NamespaceBlock]>,
) -> Option<NamespaceBlock> {
let offset = ACTIVE.with(|a| match &*a.borrow() {
Some((f, off)) if f.as_ref() == file => Some(*off),
_ => None,
})?;
blocks()
.iter()
.find(|b| b.start <= offset && offset < b.end)
.cloned()
}