1#![warn(
2 clippy::disallowed_methods,
3 reason = "Prefer System trait methods over std methods"
4)]
5
6use crate::files::{File, Files};
7use crate::system::System;
8use crate::vendored::VendoredFileSystem;
9use ruff_python_ast::PythonVersion;
10use rustc_hash::FxHasher;
11use std::hash::BuildHasherDefault;
12use std::num::NonZeroUsize;
13use ty_static::EnvVars;
14
15pub mod cancellation;
16pub mod diagnostic;
17pub mod display;
18pub mod file_revision;
19pub mod files;
20pub mod panic;
21pub mod parsed;
22pub mod source;
23pub mod system;
24#[cfg(feature = "testing")]
25pub mod testing;
26pub mod vendored;
27
28#[salsa::interned(debug, heap_size = ruff_memory_usage::heap_size)]
34pub struct PythonFile<'db> {
35 #[returns(copy)]
36 pub file: File,
37 #[returns(copy)]
38 pub python_version: PythonVersion,
39}
40
41impl get_size2::GetSize for PythonFile<'_> {}
43
44#[cfg(not(target_arch = "wasm32"))]
45pub use std::time::{Instant, SystemTime, SystemTimeError};
46
47#[cfg(target_arch = "wasm32")]
48pub use web_time::{Instant, SystemTime, SystemTimeError};
49
50pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
51static VERSION: std::sync::OnceLock<String> = std::sync::OnceLock::new();
52
53pub fn program_version() -> Option<&'static str> {
55 VERSION.get().map(|version| version.as_str())
56}
57
58pub fn set_program_version(version: String) -> Result<(), String> {
63 VERSION.set(version)
64}
65
66pub fn disable_lru(db: &mut dyn Db) {
71 parsed::disable_lru(db);
72}
73
74#[salsa::db]
76pub trait Db: salsa::Database {
77 fn vendored(&self) -> &VendoredFileSystem;
78 fn system(&self) -> &dyn System;
79 fn files(&self) -> &Files;
80}
81
82#[expect(
96 clippy::disallowed_methods,
97 reason = "We don't have access to System here, but this is also only used by the CLI and the server which always run on a real system."
98)]
99pub fn max_parallelism() -> NonZeroUsize {
100 std::env::var(EnvVars::TY_MAX_PARALLELISM)
101 .or_else(|_| std::env::var(EnvVars::RAYON_NUM_THREADS))
102 .ok()
103 .and_then(|s| s.parse().ok())
104 .unwrap_or_else(|| {
105 std::thread::available_parallelism().unwrap_or_else(|_| NonZeroUsize::new(1).unwrap())
106 })
107}
108
109pub const STACK_SIZE: usize = 16 * 1024 * 1024;
115
116pub trait RustDoc {
120 fn rust_doc() -> &'static str;
121}
122
123#[cfg(test)]
124mod tests {
125 use std::sync::{Arc, Mutex};
126
127 use crate::Db;
128 use crate::files::Files;
129 use crate::system::TestSystem;
130 use crate::system::{DbWithTestSystem, System};
131 use crate::vendored::VendoredFileSystem;
132
133 type Events = Arc<Mutex<Vec<salsa::Event>>>;
134
135 #[salsa::db]
139 #[derive(Default, Clone)]
140 pub(crate) struct TestDb {
141 storage: salsa::Storage<Self>,
142 files: Files,
143 system: TestSystem,
144 vendored: VendoredFileSystem,
145 events: Events,
146 }
147
148 impl TestDb {
149 pub(crate) fn new() -> Self {
150 let events = Events::default();
151 Self {
152 storage: salsa::Storage::new(Some(Box::new({
153 let events = events.clone();
154 move |event| {
155 tracing::trace!("event: {:?}", event);
156 let mut events = events.lock().unwrap();
157 events.push(event);
158 }
159 }))),
160 system: TestSystem::default(),
161 vendored: VendoredFileSystem::default(),
162 events,
163 files: Files::default(),
164 }
165 }
166
167 pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> {
170 let mut events = self.events.lock().unwrap();
171
172 std::mem::take(&mut *events)
173 }
174
175 pub(crate) fn clear_salsa_events(&mut self) {
177 self.take_salsa_events();
178 }
179
180 pub(crate) fn with_vendored(&mut self, vendored_file_system: VendoredFileSystem) {
181 self.vendored = vendored_file_system;
182 }
183 }
184
185 #[salsa::db]
186 impl Db for TestDb {
187 fn vendored(&self) -> &VendoredFileSystem {
188 &self.vendored
189 }
190
191 fn system(&self) -> &dyn System {
192 &self.system
193 }
194
195 fn files(&self) -> &Files {
196 &self.files
197 }
198 }
199
200 impl DbWithTestSystem for TestDb {
201 fn test_system(&self) -> &TestSystem {
202 &self.system
203 }
204
205 fn test_system_mut(&mut self) -> &mut TestSystem {
206 &mut self.system
207 }
208 }
209
210 #[salsa::db]
211 impl salsa::Database for TestDb {}
212}