diff options
author | Edwin Cheng <[email protected]> | 2021-01-28 15:33:02 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2021-01-28 17:04:14 +0000 |
commit | 9358eecc042d8b551f58d2d5ddb9c88d258880c1 (patch) | |
tree | 7188b0e27d9d00640b5c76319ee59b2d5cab1b05 /crates/rust-analyzer/src/reload.rs | |
parent | f421ee672253499b8ca8d1badf98db42525a5216 (diff) |
Async Loading outdir and proc-macro
Diffstat (limited to 'crates/rust-analyzer/src/reload.rs')
-rw-r--r-- | crates/rust-analyzer/src/reload.rs | 88 |
1 files changed, 77 insertions, 11 deletions
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index ef73099cf..289bbc443 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -4,7 +4,7 @@ use std::{mem, sync::Arc}; | |||
4 | use flycheck::{FlycheckConfig, FlycheckHandle}; | 4 | use flycheck::{FlycheckConfig, FlycheckHandle}; |
5 | use ide::Change; | 5 | use ide::Change; |
6 | use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath}; | 6 | use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath}; |
7 | use project_model::{ProcMacroClient, ProjectWorkspace}; | 7 | use project_model::{BuildDataCollector, BuildDataResult, ProcMacroClient, ProjectWorkspace}; |
8 | use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; | 8 | use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
@@ -22,6 +22,13 @@ pub(crate) enum ProjectWorkspaceProgress { | |||
22 | End(Vec<anyhow::Result<ProjectWorkspace>>), | 22 | End(Vec<anyhow::Result<ProjectWorkspace>>), |
23 | } | 23 | } |
24 | 24 | ||
25 | #[derive(Debug)] | ||
26 | pub(crate) enum BuildDataProgress { | ||
27 | Begin, | ||
28 | Report(String), | ||
29 | End(anyhow::Result<BuildDataResult>), | ||
30 | } | ||
31 | |||
25 | impl GlobalState { | 32 | impl GlobalState { |
26 | pub(crate) fn update_configuration(&mut self, config: Config) { | 33 | pub(crate) fn update_configuration(&mut self, config: Config) { |
27 | let _p = profile::span("GlobalState::update_configuration"); | 34 | let _p = profile::span("GlobalState::update_configuration"); |
@@ -41,7 +48,7 @@ impl GlobalState { | |||
41 | } | 48 | } |
42 | match self.status { | 49 | match self.status { |
43 | Status::Loading | Status::NeedsReload => return, | 50 | Status::Loading | Status::NeedsReload => return, |
44 | Status::Ready | Status::Invalid => (), | 51 | Status::Ready { .. } | Status::Invalid => (), |
45 | } | 52 | } |
46 | if self.config.cargo_autoreload() { | 53 | if self.config.cargo_autoreload() { |
47 | self.fetch_workspaces_request(); | 54 | self.fetch_workspaces_request(); |
@@ -89,7 +96,8 @@ impl GlobalState { | |||
89 | if self.config.status_notification() { | 96 | if self.config.status_notification() { |
90 | let lsp_status = match new_status { | 97 | let lsp_status = match new_status { |
91 | Status::Loading => lsp_ext::Status::Loading, | 98 | Status::Loading => lsp_ext::Status::Loading, |
92 | Status::Ready => lsp_ext::Status::Ready, | 99 | Status::Ready { partial: true } => lsp_ext::Status::ReadyPartial, |
100 | Status::Ready { partial: false } => lsp_ext::Status::Ready, | ||
93 | Status::Invalid => lsp_ext::Status::Invalid, | 101 | Status::Invalid => lsp_ext::Status::Invalid, |
94 | Status::NeedsReload => lsp_ext::Status::NeedsReload, | 102 | Status::NeedsReload => lsp_ext::Status::NeedsReload, |
95 | }; | 103 | }; |
@@ -99,11 +107,37 @@ impl GlobalState { | |||
99 | } | 107 | } |
100 | } | 108 | } |
101 | 109 | ||
110 | pub(crate) fn fetch_build_data_request(&mut self, build_data_collector: BuildDataCollector) { | ||
111 | self.fetch_build_data_queue.request_op(build_data_collector); | ||
112 | } | ||
113 | |||
114 | pub(crate) fn fetch_build_data_if_needed(&mut self) { | ||
115 | let mut build_data_collector = match self.fetch_build_data_queue.should_start_op() { | ||
116 | Some(it) => it, | ||
117 | None => return, | ||
118 | }; | ||
119 | self.task_pool.handle.spawn_with_sender(move |sender| { | ||
120 | sender.send(Task::FetchBuildData(BuildDataProgress::Begin)).unwrap(); | ||
121 | |||
122 | let progress = { | ||
123 | let sender = sender.clone(); | ||
124 | move |msg| { | ||
125 | sender.send(Task::FetchBuildData(BuildDataProgress::Report(msg))).unwrap() | ||
126 | } | ||
127 | }; | ||
128 | let res = build_data_collector.collect(&progress); | ||
129 | sender.send(Task::FetchBuildData(BuildDataProgress::End(res))).unwrap(); | ||
130 | }); | ||
131 | } | ||
132 | pub(crate) fn fetch_build_data_completed(&mut self) { | ||
133 | self.fetch_build_data_queue.op_completed() | ||
134 | } | ||
135 | |||
102 | pub(crate) fn fetch_workspaces_request(&mut self) { | 136 | pub(crate) fn fetch_workspaces_request(&mut self) { |
103 | self.fetch_workspaces_queue.request_op() | 137 | self.fetch_workspaces_queue.request_op(()) |
104 | } | 138 | } |
105 | pub(crate) fn fetch_workspaces_if_needed(&mut self) { | 139 | pub(crate) fn fetch_workspaces_if_needed(&mut self) { |
106 | if !self.fetch_workspaces_queue.should_start_op() { | 140 | if self.fetch_workspaces_queue.should_start_op().is_none() { |
107 | return; | 141 | return; |
108 | } | 142 | } |
109 | log::info!("will fetch workspaces"); | 143 | log::info!("will fetch workspaces"); |
@@ -154,7 +188,11 @@ impl GlobalState { | |||
154 | self.fetch_workspaces_queue.op_completed() | 188 | self.fetch_workspaces_queue.op_completed() |
155 | } | 189 | } |
156 | 190 | ||
157 | pub(crate) fn switch_workspaces(&mut self, workspaces: Vec<anyhow::Result<ProjectWorkspace>>) { | 191 | pub(crate) fn switch_workspaces( |
192 | &mut self, | ||
193 | workspaces: Vec<anyhow::Result<ProjectWorkspace>>, | ||
194 | workspace_build_data: Option<anyhow::Result<BuildDataResult>>, | ||
195 | ) { | ||
158 | let _p = profile::span("GlobalState::switch_workspaces"); | 196 | let _p = profile::span("GlobalState::switch_workspaces"); |
159 | log::info!("will switch workspaces: {:?}", workspaces); | 197 | log::info!("will switch workspaces: {:?}", workspaces); |
160 | 198 | ||
@@ -176,7 +214,20 @@ impl GlobalState { | |||
176 | }) | 214 | }) |
177 | .collect::<Vec<_>>(); | 215 | .collect::<Vec<_>>(); |
178 | 216 | ||
179 | if &*self.workspaces == &workspaces { | 217 | let workspace_build_data = match workspace_build_data { |
218 | Some(Ok(it)) => Some(it), | ||
219 | Some(Err(err)) => { | ||
220 | log::error!("failed to fetch build data: {:#}", err); | ||
221 | self.show_message( | ||
222 | lsp_types::MessageType::Error, | ||
223 | format!("rust-analyzer failed to fetch build data: {:#}", err), | ||
224 | ); | ||
225 | return; | ||
226 | } | ||
227 | None => None, | ||
228 | }; | ||
229 | |||
230 | if &*self.workspaces == &workspaces && self.workspace_build_data == workspace_build_data { | ||
180 | return; | 231 | return; |
181 | } | 232 | } |
182 | 233 | ||
@@ -189,7 +240,7 @@ impl GlobalState { | |||
189 | let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions { | 240 | let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions { |
190 | watchers: workspaces | 241 | watchers: workspaces |
191 | .iter() | 242 | .iter() |
192 | .flat_map(ProjectWorkspace::to_roots) | 243 | .flat_map(|it| it.to_roots(workspace_build_data.as_ref())) |
193 | .filter(|it| it.is_member) | 244 | .filter(|it| it.is_member) |
194 | .flat_map(|root| { | 245 | .flat_map(|root| { |
195 | root.include.into_iter().map(|it| format!("{}/**/*.rs", it.display())) | 246 | root.include.into_iter().map(|it| format!("{}/**/*.rs", it.display())) |
@@ -215,7 +266,8 @@ impl GlobalState { | |||
215 | let mut change = Change::new(); | 266 | let mut change = Change::new(); |
216 | 267 | ||
217 | let files_config = self.config.files(); | 268 | let files_config = self.config.files(); |
218 | let project_folders = ProjectFolders::new(&workspaces, &files_config.exclude); | 269 | let project_folders = |
270 | ProjectFolders::new(&workspaces, &files_config.exclude, workspace_build_data.as_ref()); | ||
219 | 271 | ||
220 | self.proc_macro_client = match self.config.proc_macro_srv() { | 272 | self.proc_macro_client = match self.config.proc_macro_srv() { |
221 | None => None, | 273 | None => None, |
@@ -257,15 +309,28 @@ impl GlobalState { | |||
257 | res | 309 | res |
258 | }; | 310 | }; |
259 | for ws in workspaces.iter() { | 311 | for ws in workspaces.iter() { |
260 | crate_graph.extend(ws.to_crate_graph(self.proc_macro_client.as_ref(), &mut load)); | 312 | crate_graph.extend(ws.to_crate_graph( |
313 | self.workspace_build_data.as_ref(), | ||
314 | self.proc_macro_client.as_ref(), | ||
315 | &mut load, | ||
316 | )); | ||
261 | } | 317 | } |
262 | 318 | ||
263 | crate_graph | 319 | crate_graph |
264 | }; | 320 | }; |
265 | change.set_crate_graph(crate_graph); | 321 | change.set_crate_graph(crate_graph); |
266 | 322 | ||
323 | if self.config.load_out_dirs_from_check() && workspace_build_data.is_none() { | ||
324 | let mut collector = BuildDataCollector::default(); | ||
325 | for ws in &workspaces { | ||
326 | ws.collect_build_data_configs(&mut collector); | ||
327 | } | ||
328 | self.fetch_build_data_request(collector) | ||
329 | } | ||
330 | |||
267 | self.source_root_config = project_folders.source_root_config; | 331 | self.source_root_config = project_folders.source_root_config; |
268 | self.workspaces = Arc::new(workspaces); | 332 | self.workspaces = Arc::new(workspaces); |
333 | self.workspace_build_data = workspace_build_data; | ||
269 | 334 | ||
270 | self.analysis_host.apply_change(change); | 335 | self.analysis_host.apply_change(change); |
271 | self.process_changes(); | 336 | self.process_changes(); |
@@ -323,12 +388,13 @@ impl ProjectFolders { | |||
323 | pub(crate) fn new( | 388 | pub(crate) fn new( |
324 | workspaces: &[ProjectWorkspace], | 389 | workspaces: &[ProjectWorkspace], |
325 | global_excludes: &[AbsPathBuf], | 390 | global_excludes: &[AbsPathBuf], |
391 | build_data: Option<&BuildDataResult>, | ||
326 | ) -> ProjectFolders { | 392 | ) -> ProjectFolders { |
327 | let mut res = ProjectFolders::default(); | 393 | let mut res = ProjectFolders::default(); |
328 | let mut fsc = FileSetConfig::builder(); | 394 | let mut fsc = FileSetConfig::builder(); |
329 | let mut local_filesets = vec![]; | 395 | let mut local_filesets = vec![]; |
330 | 396 | ||
331 | for root in workspaces.iter().flat_map(|it| it.to_roots()) { | 397 | for root in workspaces.iter().flat_map(|it| it.to_roots(build_data)) { |
332 | let file_set_roots: Vec<VfsPath> = | 398 | let file_set_roots: Vec<VfsPath> = |
333 | root.include.iter().cloned().map(VfsPath::from).collect(); | 399 | root.include.iter().cloned().map(VfsPath::from).collect(); |
334 | 400 | ||