aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-07-02 15:47:42 +0100
committerAleksey Kladov <[email protected]>2020-07-02 16:39:51 +0100
commit6c7578bd7a67b0f8fd1fdb6a043c8523104c5807 (patch)
tree86523962b1589754abd296536be6cf34e5aa4110 /crates
parent83f3cdca4f4a3ba612c082bba35c8ecf76abc166 (diff)
Move cargo metadata off the main loop
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_project_model/src/lib.rs4
-rw-r--r--crates/rust-analyzer/src/main_loop.rs15
-rw-r--r--crates/rust-analyzer/src/reload.rs79
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/main.rs1
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 {
150impl ProjectWorkspace { 150impl ProjectWorkspace {
151 pub fn load( 151 pub fn load(
152 manifest: ProjectManifest, 152 manifest: ProjectManifest,
153 cargo_features: &CargoConfig, 153 cargo_config: &CargoConfig,
154 with_sysroot: bool, 154 with_sysroot: bool,
155 ) -> Result<ProjectWorkspace> { 155 ) -> Result<ProjectWorkspace> {
156 let res = match manifest { 156 let res = match manifest {
@@ -166,7 +166,7 @@ impl ProjectWorkspace {
166 ProjectWorkspace::Json { project } 166 ProjectWorkspace::Json { project }
167 } 167 }
168 ProjectManifest::CargoToml(cargo_toml) => { 168 ProjectManifest::CargoToml(cargo_toml) => {
169 let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features) 169 let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_config)
170 .with_context(|| { 170 .with_context(|| {
171 format!( 171 format!(
172 "Failed to read Cargo metadata from Cargo.toml file {}", 172 "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::{
21 lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress}, 21 lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress},
22 Result, 22 Result,
23}; 23};
24use ra_project_model::ProjectWorkspace;
24 25
25pub fn main_loop(config: Config, connection: Connection) -> Result<()> { 26pub fn main_loop(config: Config, connection: Connection) -> Result<()> {
26 log::info!("initial config: {:#?}", config); 27 log::info!("initial config: {:#?}", config);
@@ -58,6 +59,7 @@ enum Event {
58pub(crate) enum Task { 59pub(crate) enum Task {
59 Response(Response), 60 Response(Response),
60 Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>), 61 Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>),
62 Workspaces(Vec<anyhow::Result<ProjectWorkspace>>),
61 Unit, 63 Unit,
62} 64}
63 65
@@ -111,6 +113,14 @@ impl GlobalState {
111 } 113 }
112 114
113 fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> { 115 fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> {
116 if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found
117 {
118 self.show_message(
119 lsp_types::MessageType::Error,
120 "rust-analyzer failed to discover workspace".to_string(),
121 );
122 };
123
114 let registration_options = lsp_types::TextDocumentRegistrationOptions { 124 let registration_options = lsp_types::TextDocumentRegistrationOptions {
115 document_selector: Some(vec![ 125 document_selector: Some(vec![
116 lsp_types::DocumentFilter { 126 lsp_types::DocumentFilter {
@@ -140,7 +150,7 @@ impl GlobalState {
140 |_, _| (), 150 |_, _| (),
141 ); 151 );
142 152
143 self.reload(); 153 self.fetch_workspaces();
144 154
145 while let Some(event) = self.next_event(&inbox) { 155 while let Some(event) = self.next_event(&inbox) {
146 if let Event::Lsp(lsp_server::Message::Notification(not)) = &event { 156 if let Event::Lsp(lsp_server::Message::Notification(not)) = &event {
@@ -182,6 +192,7 @@ impl GlobalState {
182 self.diagnostics.set_native_diagnostics(file_id, diagnostics) 192 self.diagnostics.set_native_diagnostics(file_id, diagnostics)
183 } 193 }
184 } 194 }
195 Task::Workspaces(workspaces) => self.switch_workspaces(workspaces),
185 Task::Unit => (), 196 Task::Unit => (),
186 } 197 }
187 self.analysis_host.maybe_collect_garbage(); 198 self.analysis_host.maybe_collect_garbage();
@@ -320,7 +331,7 @@ impl GlobalState {
320 self.register_request(&req, request_received); 331 self.register_request(&req, request_received);
321 332
322 RequestDispatcher { req: Some(req), global_state: self } 333 RequestDispatcher { req: Some(req), global_state: self }
323 .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.reload()))? 334 .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))?
324 .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))? 335 .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
325 .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))? 336 .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))?
326 .on_sync::<lsp_types::request::Shutdown>(|_, ()| Ok(()))? 337 .on_sync::<lsp_types::request::Shutdown>(|_, ()| 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};
11use crate::{ 11use crate::{
12 config::{Config, FilesWatcher, LinkedProject}, 12 config::{Config, FilesWatcher, LinkedProject},
13 global_state::{GlobalState, Handle}, 13 global_state::{GlobalState, Handle},
14 main_loop::Task,
14}; 15};
15 16
16impl GlobalState { 17impl GlobalState {
@@ -20,51 +21,51 @@ impl GlobalState {
20 self.analysis_host.update_lru_capacity(old_config.lru_capacity); 21 self.analysis_host.update_lru_capacity(old_config.lru_capacity);
21 } 22 }
22 if self.config.linked_projects != old_config.linked_projects { 23 if self.config.linked_projects != old_config.linked_projects {
23 self.reload() 24 self.fetch_workspaces()
24 } else if self.config.flycheck != old_config.flycheck { 25 } else if self.config.flycheck != old_config.flycheck {
25 self.reload_flycheck(); 26 self.reload_flycheck();
26 } 27 }
27 } 28 }
28 pub(crate) fn reload(&mut self) { 29 pub(crate) fn fetch_workspaces(&mut self) {
29 log::info!("reloading projects: {:?}", self.config.linked_projects); 30 self.task_pool.handle.spawn({
30 if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found 31 let linked_projects = self.config.linked_projects.clone();
31 { 32 let cargo_config = self.config.cargo.clone();
32 self.show_message( 33 let with_sysroot = self.config.with_sysroot.clone();
33 lsp_types::MessageType::Error, 34 move || {
34 "rust-analyzer failed to discover workspace".to_string(), 35 let workspaces = linked_projects
35 ); 36 .iter()
36 }; 37 .map(|project| match project {
37 38 LinkedProject::ProjectManifest(manifest) => {
38 let workspaces = { 39 ra_project_model::ProjectWorkspace::load(
39 self.config 40 manifest.clone(),
40 .linked_projects 41 &cargo_config,
41 .iter() 42 with_sysroot,
42 .map(|project| match project { 43 )
43 LinkedProject::ProjectManifest(manifest) => { 44 }
44 ra_project_model::ProjectWorkspace::load( 45 LinkedProject::InlineJsonProject(it) => {
45 manifest.clone(), 46 Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
46 &self.config.cargo, 47 }
47 self.config.with_sysroot,
48 )
49 }
50 LinkedProject::InlineJsonProject(it) => {
51 Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
52 }
53 })
54 .collect::<Vec<_>>()
55 .into_iter()
56 .filter_map(|res| {
57 res.map_err(|err| {
58 log::error!("failed to load workspace: {:#}", err);
59 self.show_message(
60 lsp_types::MessageType::Error,
61 format!("rust-analyzer failed to load workspace: {:#}", err),
62 );
63 }) 48 })
64 .ok() 49 .collect::<Vec<_>>();
50 Task::Workspaces(workspaces)
51 }
52 });
53 }
54 pub(crate) fn switch_workspaces(&mut self, workspaces: Vec<anyhow::Result<ProjectWorkspace>>) {
55 log::info!("reloading projects: {:?}", self.config.linked_projects);
56 let workspaces = workspaces
57 .into_iter()
58 .filter_map(|res| {
59 res.map_err(|err| {
60 log::error!("failed to load workspace: {:#}", err);
61 self.show_message(
62 lsp_types::MessageType::Error,
63 format!("rust-analyzer failed to load workspace: {:#}", err),
64 );
65 }) 65 })
66 .collect::<Vec<_>>() 66 .ok()
67 }; 67 })
68 .collect::<Vec<_>>();
68 69
69 if let FilesWatcher::Client = self.config.files.watcher { 70 if let FilesWatcher::Client = self.config.files.watcher {
70 let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions { 71 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\"
447", 447",
448 ) 448 )
449 .server(); 449 .server();
450 server.wait_until_workspace_is_loaded();
450 451
451 server.request::<OnEnter>( 452 server.request::<OnEnter>(
452 TextDocumentPositionParams { 453 TextDocumentPositionParams {