aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/reload.rs
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2021-01-28 15:33:02 +0000
committerEdwin Cheng <[email protected]>2021-01-28 17:04:14 +0000
commit9358eecc042d8b551f58d2d5ddb9c88d258880c1 (patch)
tree7188b0e27d9d00640b5c76319ee59b2d5cab1b05 /crates/rust-analyzer/src/reload.rs
parentf421ee672253499b8ca8d1badf98db42525a5216 (diff)
Async Loading outdir and proc-macro
Diffstat (limited to 'crates/rust-analyzer/src/reload.rs')
-rw-r--r--crates/rust-analyzer/src/reload.rs88
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};
4use flycheck::{FlycheckConfig, FlycheckHandle}; 4use flycheck::{FlycheckConfig, FlycheckHandle};
5use ide::Change; 5use ide::Change;
6use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath}; 6use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath};
7use project_model::{ProcMacroClient, ProjectWorkspace}; 7use project_model::{BuildDataCollector, BuildDataResult, ProcMacroClient, ProjectWorkspace};
8use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; 8use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
9 9
10use crate::{ 10use 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)]
26pub(crate) enum BuildDataProgress {
27 Begin,
28 Report(String),
29 End(anyhow::Result<BuildDataResult>),
30}
31
25impl GlobalState { 32impl 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