From 2590011ea3f191fcaf38e77a9179f263f1ec5aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sm=C3=B3=C5=82ka?= Date: Thu, 6 Feb 2025 14:32:25 +0100 Subject: [PATCH] Store Tricks in a static container (#207) --- src/lang/db/mod.rs | 6 ++++-- src/lang/db/swapper.rs | 8 +++----- src/lang/proc_macros/plugins/downcast.rs | 2 +- src/lib.rs | 24 +++++++++++++++--------- src/state.rs | 11 ++--------- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/lang/db/mod.rs b/src/lang/db/mod.rs index 8832ed2b..4586846c 100644 --- a/src/lang/db/mod.rs +++ b/src/lang/db/mod.rs @@ -26,7 +26,7 @@ pub use self::semantic::*; pub use self::swapper::*; pub use self::syntax::*; use super::proc_macros::db::{ProcMacroDatabase, init_proc_macro_group}; -use crate::Tricks; +use crate::TRICKS; mod semantic; mod swapper; @@ -49,7 +49,7 @@ pub struct AnalysisDatabase { impl AnalysisDatabase { /// Creates a new instance of the database. - pub fn new(tricks: &Tricks) -> Self { + pub fn new() -> Self { let mut db = Self { storage: Default::default() }; init_files_group(&mut db); @@ -60,6 +60,8 @@ impl AnalysisDatabase { db.set_cfg_set(Self::initial_cfg_set().into()); + let tricks = TRICKS.get_or_init(Default::default); + let plugin_suite = [ get_default_plugin_suite(), starknet_plugin_suite(), diff --git a/src/lang/db/swapper.rs b/src/lang/db/swapper.rs index 0d2504ca..5127e5a1 100644 --- a/src/lang/db/swapper.rs +++ b/src/lang/db/swapper.rs @@ -12,11 +12,11 @@ use cairo_lang_utils::{Intern, LookupIntern}; use lsp_types::Url; use tracing::{error, warn}; +use crate::env_config; use crate::lang::db::AnalysisDatabase; use crate::lang::lsp::LsProtoGroup; use crate::lang::proc_macros::db::ProcMacroGroup; use crate::project::ProjectController; -use crate::{Tricks, env_config}; /// Swaps entire [`AnalysisDatabase`] with empty one periodically. /// @@ -52,7 +52,6 @@ impl AnalysisDatabaseSwapper { &mut self, db: &mut AnalysisDatabase, open_files: &HashSet, - tricks: &Tricks, project_controller: &mut ProjectController, ) { let Ok(elapsed) = self.last_replace.elapsed() else { @@ -69,7 +68,7 @@ impl AnalysisDatabaseSwapper { return; } - self.swap(db, open_files, tricks, project_controller) + self.swap(db, open_files, project_controller) } /// Swaps the database. @@ -78,13 +77,12 @@ impl AnalysisDatabaseSwapper { &mut self, db: &mut AnalysisDatabase, open_files: &HashSet, - tricks: &Tricks, project_controller: &mut ProjectController, ) { let Ok(new_db) = catch_unwind(AssertUnwindSafe(|| { project_controller.clear_loaded_workspaces(); - let mut new_db = AnalysisDatabase::new(tricks); + let mut new_db = AnalysisDatabase::new(); self.migrate_proc_macro_state(&mut new_db, db); self.migrate_file_overrides(&mut new_db, db, open_files); self.update_project_for_open_files(open_files, project_controller); diff --git a/src/lang/proc_macros/plugins/downcast.rs b/src/lang/proc_macros/plugins/downcast.rs index 68f87691..2cfd7677 100644 --- a/src/lang/proc_macros/plugins/downcast.rs +++ b/src/lang/proc_macros/plugins/downcast.rs @@ -36,7 +36,7 @@ mod unsafe_downcast_ref_tests { #[test] fn cast_succeed() { - let mut db = AnalysisDatabase::new(&Default::default()); + let mut db = AnalysisDatabase::new(); let input = ExpandAttributeParams { attr: "asd".to_string(), diff --git a/src/lib.rs b/src/lib.rs index b1743496..31535127 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ use std::num::NonZeroU32; use std::panic::RefUnwindSafe; use std::path::PathBuf; use std::process::ExitCode; +use std::sync::OnceLock; use std::time::{Duration, SystemTime}; use std::{io, panic}; @@ -79,6 +80,9 @@ mod server; mod state; mod toolchain; +/// A container to store global customizations initialized upon launch. +pub static TRICKS: OnceLock = OnceLock::new(); + /// Carries various customizations that can be applied to CairoLS. /// /// See [the top-level documentation][lib] documentation for usage examples. @@ -114,7 +118,9 @@ pub fn start_with_tricks(tricks: Tricks) -> ExitCode { info!("language server starting"); env_config::report_to_logs(); - let exit_code = match Backend::new(tricks) { + let _ = TRICKS.set(tricks); + + let exit_code = match Backend::new() { Ok(backend) => { if let Err(err) = backend.run().map(|handle| handle.join()) { error!("language server encountered an unrecoverable error: {err}"); @@ -233,9 +239,10 @@ impl BackendForTesting { ) -> (Box BackendForTesting + Send>, lsp_server::Connection) { let (connection_initializer, client) = ConnectionInitializer::memory(); - let init = Box::new(|| { - BackendForTesting(Backend::initialize(tricks, connection_initializer).unwrap()) - }); + let _ = TRICKS.set(tricks); + + let init = + Box::new(|| BackendForTesting(Backend::initialize(connection_initializer).unwrap())); (init, client) } @@ -246,23 +253,23 @@ impl BackendForTesting { } impl Backend { - fn new(tricks: Tricks) -> Result { + fn new() -> Result { let connection_initializer = ConnectionInitializer::stdio(); - Self::initialize(tricks, connection_initializer) + Self::initialize(connection_initializer) } /// Initializes the connection and crate a ready to run [`Backend`] instance. /// /// As part of the initialization flow, this function exchanges client and server capabilities. - fn initialize(tricks: Tricks, connection_initializer: ConnectionInitializer) -> Result { + fn initialize(connection_initializer: ConnectionInitializer) -> Result { let (id, init_params) = connection_initializer.initialize_start()?; let client_capabilities = init_params.capabilities; let server_capabilities = collect_server_capabilities(&client_capabilities); let connection = connection_initializer.initialize_finish(id, server_capabilities)?; - let state = State::new(connection.make_sender(), client_capabilities, tricks); + let state = State::new(connection.make_sender(), client_capabilities); Ok(Self { connection, state }) } @@ -418,7 +425,6 @@ impl Backend { state.db_swapper.maybe_swap( &mut state.db, &state.open_files, - &state.tricks, &mut state.project_controller, ); } diff --git a/src/state.rs b/src/state.rs index dc7b0a1e..ea66d1e7 100644 --- a/src/state.rs +++ b/src/state.rs @@ -6,7 +6,6 @@ use std::sync::Arc; use lsp_types::{ClientCapabilities, Url}; use salsa::ParallelDatabase; -use crate::Tricks; use crate::config::Config; use crate::ide::analysis_progress::{AnalysisProgressController, ProcMacroRequestTracker}; use crate::lang::db::{AnalysisDatabase, AnalysisDatabaseSwapper}; @@ -25,7 +24,6 @@ pub struct State { pub client_capabilities: Owned, pub scarb_toolchain: ScarbToolchain, pub db_swapper: AnalysisDatabaseSwapper, - pub tricks: Owned, pub diagnostics_controller: DiagnosticsController, pub proc_macro_controller: ProcMacroClientController, pub project_controller: ProjectController, @@ -33,11 +31,7 @@ pub struct State { } impl State { - pub fn new( - sender: ClientSender, - client_capabilities: ClientCapabilities, - tricks: Tricks, - ) -> Self { + pub fn new(sender: ClientSender, client_capabilities: ClientCapabilities) -> Self { let notifier = Client::new(sender).notifier(); let scarb_toolchain = ScarbToolchain::new(notifier.clone()); @@ -55,13 +49,12 @@ impl State { DiagnosticsController::new(notifier.clone(), analysis_progress_controller.clone()); Self { - db: AnalysisDatabase::new(&tricks), + db: AnalysisDatabase::new(), open_files: Default::default(), config: Default::default(), client_capabilities: Owned::new(client_capabilities.into()), scarb_toolchain: scarb_toolchain.clone(), db_swapper: AnalysisDatabaseSwapper::new(), - tricks: Owned::new(tricks.into()), diagnostics_controller, analysis_progress_controller, proc_macro_controller,