use ruff_db::files::File; use ruff_db::{Db as SourceDb, Upcast}; /// Database giving access to semantic information about a Python program. #[salsa::db] pub trait Db: SourceDb + Upcast { fn is_file_open(&self, file: File) -> bool; } #[cfg(test)] pub(crate) mod tests { use std::sync::Arc; use ruff_db::files::{File, Files}; use ruff_db::system::{DbWithTestSystem, System, TestSystem}; use ruff_db::vendored::VendoredFileSystem; use ruff_db::{Db as SourceDb, Upcast}; use super::Db; #[salsa::db] pub(crate) struct TestDb { storage: salsa::Storage, files: Files, system: TestSystem, vendored: VendoredFileSystem, events: std::sync::Arc>>, } impl TestDb { pub(crate) fn new() -> Self { Self { storage: salsa::Storage::default(), system: TestSystem::default(), vendored: red_knot_vendored::file_system().clone(), events: std::sync::Arc::default(), files: Files::default(), } } /// Takes the salsa events. /// /// ## Panics /// If there are any pending salsa snapshots. pub(crate) fn take_salsa_events(&mut self) -> Vec { let inner = Arc::get_mut(&mut self.events).expect("no pending salsa snapshots"); let events = inner.get_mut().unwrap(); std::mem::take(&mut *events) } /// Clears the salsa events. /// /// ## Panics /// If there are any pending salsa snapshots. pub(crate) fn clear_salsa_events(&mut self) { self.take_salsa_events(); } } impl DbWithTestSystem for TestDb { fn test_system(&self) -> &TestSystem { &self.system } fn test_system_mut(&mut self) -> &mut TestSystem { &mut self.system } } #[salsa::db] impl SourceDb for TestDb { fn vendored(&self) -> &VendoredFileSystem { &self.vendored } fn system(&self) -> &dyn System { &self.system } fn files(&self) -> &Files { &self.files } } impl Upcast for TestDb { fn upcast(&self) -> &(dyn SourceDb + 'static) { self } fn upcast_mut(&mut self) -> &mut (dyn SourceDb + 'static) { self } } #[salsa::db] impl Db for TestDb { fn is_file_open(&self, file: File) -> bool { !file.path(self).is_vendored_path() } } #[salsa::db] impl salsa::Database for TestDb { fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { let event = event(); tracing::trace!("event: {event:?}"); let mut events = self.events.lock().unwrap(); events.push(event); } } }