From 6c7578bd7a67b0f8fd1fdb6a043c8523104c5807 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 2 Jul 2020 16:47:42 +0200 Subject: Move cargo metadata off the main loop --- crates/ra_project_model/src/lib.rs | 4 +- crates/rust-analyzer/src/main_loop.rs | 15 ++++- crates/rust-analyzer/src/reload.rs | 79 +++++++++++++------------- crates/rust-analyzer/tests/heavy_tests/main.rs | 1 + 4 files changed, 56 insertions(+), 43 deletions(-) diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 8dbf4e6ea..464c3b2e3 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -150,7 +150,7 @@ impl ProjectManifest { impl ProjectWorkspace { pub fn load( manifest: ProjectManifest, - cargo_features: &CargoConfig, + cargo_config: &CargoConfig, with_sysroot: bool, ) -> Result { let res = match manifest { @@ -166,7 +166,7 @@ impl ProjectWorkspace { ProjectWorkspace::Json { project } } ProjectManifest::CargoToml(cargo_toml) => { - let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features) + let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_config) .with_context(|| { format!( "Failed to read Cargo metadata from Cargo.toml file {}", diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index d4d18a808..cfde55431 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -21,6 +21,7 @@ use crate::{ lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress}, Result, }; +use ra_project_model::ProjectWorkspace; pub fn main_loop(config: Config, connection: Connection) -> Result<()> { log::info!("initial config: {:#?}", config); @@ -58,6 +59,7 @@ enum Event { pub(crate) enum Task { Response(Response), Diagnostics(Vec<(FileId, Vec)>), + Workspaces(Vec>), Unit, } @@ -111,6 +113,14 @@ impl GlobalState { } fn run(mut self, inbox: Receiver) -> Result<()> { + if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found + { + self.show_message( + lsp_types::MessageType::Error, + "rust-analyzer failed to discover workspace".to_string(), + ); + }; + let registration_options = lsp_types::TextDocumentRegistrationOptions { document_selector: Some(vec![ lsp_types::DocumentFilter { @@ -140,7 +150,7 @@ impl GlobalState { |_, _| (), ); - self.reload(); + self.fetch_workspaces(); while let Some(event) = self.next_event(&inbox) { if let Event::Lsp(lsp_server::Message::Notification(not)) = &event { @@ -182,6 +192,7 @@ impl GlobalState { self.diagnostics.set_native_diagnostics(file_id, diagnostics) } } + Task::Workspaces(workspaces) => self.switch_workspaces(workspaces), Task::Unit => (), } self.analysis_host.maybe_collect_garbage(); @@ -320,7 +331,7 @@ impl GlobalState { self.register_request(&req, request_received); RequestDispatcher { req: Some(req), global_state: self } - .on_sync::(|s, ()| Ok(s.reload()))? + .on_sync::(|s, ()| Ok(s.fetch_workspaces()))? .on_sync::(|s, p| handlers::handle_join_lines(s.snapshot(), p))? .on_sync::(|s, p| handlers::handle_on_enter(s.snapshot(), p))? .on_sync::(|_, ()| Ok(()))? diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 9fc56349c..74c3344df 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -11,6 +11,7 @@ use vfs::{file_set::FileSetConfig, AbsPath}; use crate::{ config::{Config, FilesWatcher, LinkedProject}, global_state::{GlobalState, Handle}, + main_loop::Task, }; impl GlobalState { @@ -20,51 +21,51 @@ impl GlobalState { self.analysis_host.update_lru_capacity(old_config.lru_capacity); } if self.config.linked_projects != old_config.linked_projects { - self.reload() + self.fetch_workspaces() } else if self.config.flycheck != old_config.flycheck { self.reload_flycheck(); } } - pub(crate) fn reload(&mut self) { - log::info!("reloading projects: {:?}", self.config.linked_projects); - if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found - { - self.show_message( - lsp_types::MessageType::Error, - "rust-analyzer failed to discover workspace".to_string(), - ); - }; - - let workspaces = { - self.config - .linked_projects - .iter() - .map(|project| match project { - LinkedProject::ProjectManifest(manifest) => { - ra_project_model::ProjectWorkspace::load( - manifest.clone(), - &self.config.cargo, - self.config.with_sysroot, - ) - } - LinkedProject::InlineJsonProject(it) => { - Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() }) - } - }) - .collect::>() - .into_iter() - .filter_map(|res| { - res.map_err(|err| { - log::error!("failed to load workspace: {:#}", err); - self.show_message( - lsp_types::MessageType::Error, - format!("rust-analyzer failed to load workspace: {:#}", err), - ); + pub(crate) fn fetch_workspaces(&mut self) { + self.task_pool.handle.spawn({ + let linked_projects = self.config.linked_projects.clone(); + let cargo_config = self.config.cargo.clone(); + let with_sysroot = self.config.with_sysroot.clone(); + move || { + let workspaces = linked_projects + .iter() + .map(|project| match project { + LinkedProject::ProjectManifest(manifest) => { + ra_project_model::ProjectWorkspace::load( + manifest.clone(), + &cargo_config, + with_sysroot, + ) + } + LinkedProject::InlineJsonProject(it) => { + Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() }) + } }) - .ok() + .collect::>(); + Task::Workspaces(workspaces) + } + }); + } + pub(crate) fn switch_workspaces(&mut self, workspaces: Vec>) { + log::info!("reloading projects: {:?}", self.config.linked_projects); + let workspaces = workspaces + .into_iter() + .filter_map(|res| { + res.map_err(|err| { + log::error!("failed to load workspace: {:#}", err); + self.show_message( + lsp_types::MessageType::Error, + format!("rust-analyzer failed to load workspace: {:#}", err), + ); }) - .collect::>() - }; + .ok() + }) + .collect::>(); if let FilesWatcher::Client = self.config.files.watcher { let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions { diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs index cc079790e..7b908d30c 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/heavy_tests/main.rs @@ -447,6 +447,7 @@ version = \"0.0.0\" ", ) .server(); + server.wait_until_workspace_is_loaded(); server.request::( TextDocumentPositionParams { -- cgit v1.2.3