use std::sync::{LazyLock, Mutex};
use cairo_lang_debug::DebugWithDb;
use cairo_lang_defs::db::{init_defs_group, init_external_files};
use cairo_lang_filesystem::db::{init_dev_corelib, init_files_group};
use cairo_lang_filesystem::detect::detect_corelib;
use cairo_lang_filesystem::flag::{Flag, FlagsGroup};
use cairo_lang_filesystem::ids::FlagLongId;
use cairo_lang_semantic::db::{PluginSuiteInput, init_semantic_group};
use cairo_lang_semantic::inline_macros::get_default_plugin_suite;
use salsa::Database;
use crate::Lowered;
use crate::db::init_lowering_group;
use crate::fmt::LoweredFormatter;
use crate::optimizations::config::Optimizations;
use crate::utils::InliningStrategy;
#[salsa::db]
#[derive(Clone)]
pub struct LoweringDatabaseForTesting {
storage: salsa::Storage<LoweringDatabaseForTesting>,
}
#[salsa::db]
impl salsa::Database for LoweringDatabaseForTesting {}
impl LoweringDatabaseForTesting {
pub fn new() -> Self {
let mut res = LoweringDatabaseForTesting { storage: Default::default() };
init_external_files(&mut res);
init_files_group(&mut res);
init_defs_group(&mut res);
init_semantic_group(&mut res);
res.set_default_plugins_from_suite(get_default_plugin_suite());
let corelib_path = detect_corelib().expect("Corelib not found in default location.");
init_dev_corelib(&mut res, corelib_path);
init_lowering_group(
&mut res,
Optimizations::enabled_with_default_movable_functions(InliningStrategy::Default),
None,
);
res
}
pub fn snapshot(&self) -> LoweringDatabaseForTesting {
self.clone()
}
}
pub static SHARED_DB: LazyLock<Mutex<LoweringDatabaseForTesting>> =
LazyLock::new(|| Mutex::new(LoweringDatabaseForTesting::new()));
pub static SHARED_DB_FUTURE_SIERRA: LazyLock<Mutex<LoweringDatabaseForTesting>> =
LazyLock::new(|| {
let mut db = LoweringDatabaseForTesting::new();
db.set_flag(FlagLongId(Flag::FUTURE_SIERRA.into()), Some(Flag::FutureSierra(true)));
Mutex::new(db)
});
impl LoweringDatabaseForTesting {
pub fn with_future_sierra() -> Self {
SHARED_DB_FUTURE_SIERRA.lock().unwrap().snapshot()
}
}
impl Default for LoweringDatabaseForTesting {
fn default() -> Self {
SHARED_DB.lock().unwrap().snapshot()
}
}
pub fn formatted_lowered(db: &dyn Database, lowered: Option<&Lowered<'_>>) -> String {
match lowered {
Some(lowered) => {
let lowered_formatter = LoweredFormatter::new(db, &lowered.variables);
format!("{:?}", lowered.debug(&lowered_formatter))
}
None => "<Failed lowering function - run with RUST_LOG=warn (or less) to see diagnostics>"
.to_string(),
}
}