From 79fe11ced3283b88c4a24da972e1649eb16a9f1b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 26 May 2023 15:09:19 +0200 Subject: [PATCH] Shuffle some things around --- crates/rust-analyzer/src/global_state.rs | 14 ++- crates/rust-analyzer/src/main_loop.rs | 151 ++++++++++++----------- 2 files changed, 91 insertions(+), 74 deletions(-) diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 08431d6488..defb3e1461 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -52,24 +52,31 @@ pub(crate) type ReqQueue = lsp_server::ReqQueue<(String, Instant), ReqHandler>; pub(crate) struct GlobalState { sender: Sender, req_queue: ReqQueue, + pub(crate) task_pool: Handle, Receiver>, - pub(crate) loader: Handle, Receiver>, + pub(crate) config: Arc, pub(crate) analysis_host: AnalysisHost, pub(crate) diagnostics: DiagnosticCollection, pub(crate) mem_docs: MemDocs, + pub(crate) source_root_config: SourceRootConfig, pub(crate) semantic_tokens_cache: Arc>>, + + // status pub(crate) shutdown_requested: bool, pub(crate) last_reported_status: Option, - pub(crate) source_root_config: SourceRootConfig, + // proc macros pub(crate) proc_macro_changed: bool, pub(crate) proc_macro_clients: Arc<[anyhow::Result]>, + // Flycheck pub(crate) flycheck: Arc<[FlycheckHandle]>, pub(crate) flycheck_sender: Sender, pub(crate) flycheck_receiver: Receiver, + // VFS + pub(crate) loader: Handle, Receiver>, pub(crate) vfs: Arc)>>, pub(crate) vfs_config_version: u32, pub(crate) vfs_progress_config_version: u32, @@ -102,11 +109,12 @@ pub(crate) struct GlobalState { /// the user just adds comments or whitespace to Cargo.toml, we do not want /// to invalidate any salsa caches. pub(crate) workspaces: Arc>, + + // op queues pub(crate) fetch_workspaces_queue: OpQueue<(), Option>>>, pub(crate) fetch_build_data_queue: OpQueue<(), (Arc>, Vec>)>, pub(crate) fetch_proc_macros_queue: OpQueue, bool>, - pub(crate) prime_caches_queue: OpQueue, } diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 99aa48fd07..b3522394cd 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -77,7 +77,7 @@ pub(crate) enum PrimeCachesProgress { impl fmt::Debug for Event { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let debug_verbose_not = |not: &Notification, f: &mut fmt::Formatter<'_>| { + let debug_non_verbose = |not: &Notification, f: &mut fmt::Formatter<'_>| { f.debug_struct("Notification").field("method", ¬.method).finish() }; @@ -86,7 +86,7 @@ impl fmt::Debug for Event { if notification_is::(not) || notification_is::(not) { - return debug_verbose_not(not, f); + return debug_non_verbose(not, f); } } Event::Task(Task::Response(resp)) => { @@ -112,38 +112,7 @@ impl GlobalState { self.update_status_or_notify(); if self.config.did_save_text_document_dynamic_registration() { - let save_registration_options = lsp_types::TextDocumentSaveRegistrationOptions { - include_text: Some(false), - text_document_registration_options: lsp_types::TextDocumentRegistrationOptions { - document_selector: Some(vec![ - lsp_types::DocumentFilter { - language: None, - scheme: None, - pattern: Some("**/*.rs".into()), - }, - lsp_types::DocumentFilter { - language: None, - scheme: None, - pattern: Some("**/Cargo.toml".into()), - }, - lsp_types::DocumentFilter { - language: None, - scheme: None, - pattern: Some("**/Cargo.lock".into()), - }, - ]), - }, - }; - - let registration = lsp_types::Registration { - id: "textDocument/didSave".to_string(), - method: "textDocument/didSave".to_string(), - register_options: Some(serde_json::to_value(save_registration_options).unwrap()), - }; - self.send_request::( - lsp_types::RegistrationParams { registrations: vec![registration] }, - |_, _| (), - ); + self.register_did_save_capability(); } self.fetch_workspaces_queue.request_op("startup".to_string(), ()); @@ -152,17 +121,54 @@ impl GlobalState { } while let Some(event) = self.next_event(&inbox) { - if let Event::Lsp(lsp_server::Message::Notification(not)) = &event { - if not.method == lsp_types::notification::Exit::METHOD { - return Ok(()); - } + if matches!( + &event, + Event::Lsp(lsp_server::Message::Notification(Notification { method, .. })) + if method == lsp_types::notification::Exit::METHOD + ) { + return Ok(()); } - self.handle_event(event)? + self.handle_event(event)?; } Err("client exited without proper shutdown sequence".into()) } + fn register_did_save_capability(&mut self) { + let save_registration_options = lsp_types::TextDocumentSaveRegistrationOptions { + include_text: Some(false), + text_document_registration_options: lsp_types::TextDocumentRegistrationOptions { + document_selector: Some(vec![ + lsp_types::DocumentFilter { + language: None, + scheme: None, + pattern: Some("**/*.rs".into()), + }, + lsp_types::DocumentFilter { + language: None, + scheme: None, + pattern: Some("**/Cargo.toml".into()), + }, + lsp_types::DocumentFilter { + language: None, + scheme: None, + pattern: Some("**/Cargo.lock".into()), + }, + ]), + }, + }; + + let registration = lsp_types::Registration { + id: "textDocument/didSave".to_string(), + method: "textDocument/didSave".to_string(), + register_options: Some(serde_json::to_value(save_registration_options).unwrap()), + }; + self.send_request::( + lsp_types::RegistrationParams { registrations: vec![registration] }, + |_, _| (), + ); + } + fn next_event(&self, inbox: &Receiver) -> Option { select! { recv(inbox) -> msg => @@ -184,20 +190,20 @@ impl GlobalState { // NOTE: don't count blocking select! call as a loop-turn time let _p = profile::span("GlobalState::handle_event"); - let event_dbg = format!("{event:?}"); - tracing::debug!("{:?} handle_event({:?})", loop_start, event); - let task_queue_len = self.task_pool.handle.len(); - if task_queue_len > 0 { - tracing::info!("task queue len: {}", task_queue_len); + let event_dbg_msg = format!("{event:?}"); + tracing::debug!("{:?} handle_event({})", loop_start, event_dbg_msg); + if tracing::enabled!(tracing::Level::INFO) { + let task_queue_len = self.task_pool.handle.len(); + if task_queue_len > 0 { + tracing::info!("task queue len: {}", task_queue_len); + } } let was_quiescent = self.is_quiescent(); match event { Event::Lsp(msg) => match msg { lsp_server::Message::Request(req) => self.on_new_request(loop_start, req), - lsp_server::Message::Notification(not) => { - self.on_notification(not)?; - } + lsp_server::Message::Notification(not) => self.on_notification(not)?, lsp_server::Message::Response(resp) => self.complete_request(resp), }, Event::Task(task) => { @@ -291,7 +297,8 @@ impl GlobalState { } } - if !was_quiescent || state_changed { + let client_refresh = !was_quiescent || state_changed; + if client_refresh { // Refresh semantic tokens if the client supports it. if self.config.semantic_tokens_refresh() { self.semantic_tokens_cache.lock().clear(); @@ -309,9 +316,9 @@ impl GlobalState { } } - if (!was_quiescent || state_changed || memdocs_added_or_removed) - && self.config.publish_diagnostics() - { + let update_diagnostics = (!was_quiescent || state_changed || memdocs_added_or_removed) + && self.config.publish_diagnostics(); + if update_diagnostics { self.update_diagnostics() } } @@ -371,38 +378,40 @@ impl GlobalState { } if let Some((cause, ())) = self.prime_caches_queue.should_start_op() { - tracing::debug!(%cause, "will prime caches"); - let num_worker_threads = self.config.prime_caches_num_threads(); - - self.task_pool.handle.spawn_with_sender({ - let analysis = self.snapshot().analysis; - move |sender| { - sender.send(Task::PrimeCaches(PrimeCachesProgress::Begin)).unwrap(); - let res = analysis.parallel_prime_caches(num_worker_threads, |progress| { - let report = PrimeCachesProgress::Report(progress); - sender.send(Task::PrimeCaches(report)).unwrap(); - }); - sender - .send(Task::PrimeCaches(PrimeCachesProgress::End { - cancelled: res.is_err(), - })) - .unwrap(); - } - }); + self.prime_caches(cause); } self.update_status_or_notify(); let loop_duration = loop_start.elapsed(); if loop_duration > Duration::from_millis(100) && was_quiescent { - tracing::warn!("overly long loop turn took {loop_duration:?}: {event_dbg}"); + tracing::warn!("overly long loop turn took {loop_duration:?}: {event_dbg_msg}"); self.poke_rust_analyzer_developer(format!( - "overly long loop turn took {loop_duration:?}: {event_dbg}" + "overly long loop turn took {loop_duration:?}: {event_dbg_msg}" )); } Ok(()) } + fn prime_caches(&mut self, cause: String) { + tracing::debug!(%cause, "will prime caches"); + let num_worker_threads = self.config.prime_caches_num_threads(); + + self.task_pool.handle.spawn_with_sender({ + let analysis = self.snapshot().analysis; + move |sender| { + sender.send(Task::PrimeCaches(PrimeCachesProgress::Begin)).unwrap(); + let res = analysis.parallel_prime_caches(num_worker_threads, |progress| { + let report = PrimeCachesProgress::Report(progress); + sender.send(Task::PrimeCaches(report)).unwrap(); + }); + sender + .send(Task::PrimeCaches(PrimeCachesProgress::End { cancelled: res.is_err() })) + .unwrap(); + } + }); + } + fn update_status_or_notify(&mut self) { let status = self.current_status(); if self.last_reported_status.as_ref() != Some(&status) {