Skip to content

Commit 299ab04

Browse files
Veykrilregexident
authored andcommitted
Wait with change processing until the vfs is done
1 parent ea2bd9e commit 299ab04

File tree

5 files changed

+34
-30
lines changed

5 files changed

+34
-30
lines changed

crates/rust-analyzer/src/global_state.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::{
3333
lsp_ext,
3434
main_loop::Task,
3535
mem_docs::MemDocs,
36-
op_queue::OpQueue,
36+
op_queue::{Cause, OpQueue},
3737
reload,
3838
target_spec::{CargoTargetSpec, ProjectJsonTargetSpec, TargetSpec},
3939
task_pool::{TaskPool, TaskQueue},
@@ -108,8 +108,8 @@ pub(crate) struct GlobalState {
108108
pub(crate) vfs: Arc<RwLock<(vfs::Vfs, IntMap<FileId, LineEndings>)>>,
109109
pub(crate) vfs_config_version: u32,
110110
pub(crate) vfs_progress_config_version: u32,
111-
pub(crate) vfs_progress_n_total: usize,
112-
pub(crate) vfs_progress_n_done: usize,
111+
pub(crate) vfs_done: bool,
112+
pub(crate) wants_to_switch: Option<Cause>,
113113

114114
/// `workspaces` field stores the data we actually use, while the `OpQueue`
115115
/// stores the result of the last fetch.
@@ -252,8 +252,8 @@ impl GlobalState {
252252
vfs: Arc::new(RwLock::new((vfs::Vfs::default(), IntMap::default()))),
253253
vfs_config_version: 0,
254254
vfs_progress_config_version: 0,
255-
vfs_progress_n_total: 0,
256-
vfs_progress_n_done: 0,
255+
vfs_done: true,
256+
wants_to_switch: None,
257257

258258
workspaces: Arc::from(Vec::new()),
259259
crate_graph_file_dependencies: FxHashSet::default(),

crates/rust-analyzer/src/main_loop.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,14 @@ impl GlobalState {
381381
}
382382
}
383383
let event_handling_duration = loop_start.elapsed();
384-
385-
let state_changed = self.process_changes();
386-
let memdocs_added_or_removed = self.mem_docs.take_changes();
384+
let (state_changed, memdocs_added_or_removed) = if self.vfs_done {
385+
if let Some(cause) = self.wants_to_switch.take() {
386+
self.switch_workspaces(cause);
387+
}
388+
(self.process_changes(), self.mem_docs.take_changes())
389+
} else {
390+
(false, false)
391+
};
387392

388393
if self.is_quiescent() {
389394
let became_quiescent = !was_quiescent;
@@ -691,7 +696,7 @@ impl GlobalState {
691696
if let Err(e) = self.fetch_workspace_error() {
692697
error!("FetchWorkspaceError:\n{e}");
693698
}
694-
self.switch_workspaces("fetched workspace".to_owned());
699+
self.wants_to_switch = Some("fetched workspace".to_owned());
695700
(Progress::End, None)
696701
}
697702
};
@@ -737,8 +742,9 @@ impl GlobalState {
737742
error!("FetchBuildDataError:\n{e}");
738743
}
739744

740-
self.switch_workspaces("fetched build data".to_owned());
741-
745+
if self.wants_to_switch.is_none() {
746+
self.wants_to_switch = Some("fetched build data".to_owned());
747+
}
742748
(Some(Progress::End), None)
743749
}
744750
};
@@ -798,8 +804,7 @@ impl GlobalState {
798804
};
799805

800806
self.vfs_progress_config_version = config_version;
801-
self.vfs_progress_n_total = n_total;
802-
self.vfs_progress_n_done = n_done;
807+
self.vfs_done = state == Progress::End;
803808

804809
let mut message = format!("{n_done}/{n_total}");
805810
if let Some(dir) = dir {

crates/rust-analyzer/src/reload.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ pub(crate) enum ProcMacroProgress {
6262

6363
impl GlobalState {
6464
pub(crate) fn is_quiescent(&self) -> bool {
65-
!(self.last_reported_status.is_none()
66-
|| self.fetch_workspaces_queue.op_in_progress()
67-
|| self.fetch_build_data_queue.op_in_progress()
68-
|| self.fetch_proc_macros_queue.op_in_progress()
69-
|| self.discover_workspace_queue.op_in_progress()
70-
|| self.vfs_progress_config_version < self.vfs_config_version
71-
|| self.vfs_progress_n_done < self.vfs_progress_n_total)
65+
self.vfs_done
66+
&& self.last_reported_status.is_some()
67+
&& !self.fetch_workspaces_queue.op_in_progress()
68+
&& !self.fetch_build_data_queue.op_in_progress()
69+
&& !self.fetch_proc_macros_queue.op_in_progress()
70+
&& !self.discover_workspace_queue.op_in_progress()
71+
&& self.vfs_progress_config_version >= self.vfs_config_version
7272
}
7373

7474
pub(crate) fn update_configuration(&mut self, config: Config) {
@@ -102,15 +102,13 @@ impl GlobalState {
102102
}
103103

104104
pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams {
105-
let mut status = lsp_ext::ServerStatusParams {
106-
health: lsp_ext::Health::Ok,
107-
quiescent: self.is_quiescent(),
108-
message: None,
109-
};
105+
let quiescent = self.is_quiescent();
106+
let mut status =
107+
lsp_ext::ServerStatusParams { health: lsp_ext::Health::Ok, quiescent, message: None };
110108
let mut message = String::new();
111109

112110
if !self.config.cargo_autoreload(None)
113-
&& self.is_quiescent()
111+
&& quiescent
114112
&& self.fetch_workspaces_queue.op_requested()
115113
&& self.config.discover_workspace_config().is_none()
116114
{
@@ -242,7 +240,7 @@ impl GlobalState {
242240
let discover_command = self.config.discover_workspace_config().cloned();
243241
let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
244242
|| self.vfs_progress_config_version < self.vfs_config_version
245-
|| self.vfs_progress_n_done < self.vfs_progress_n_total);
243+
|| !self.vfs_done);
246244

247245
move |sender| {
248246
let progress = {

crates/vfs-notify/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ type NotifyEvent = notify::Result<notify::Event>;
6161

6262
struct NotifyActor {
6363
sender: loader::Sender,
64+
// FIXME: Consider hashset
6465
watched_entries: Vec<loader::Entry>,
6566
// Drop order is significant.
6667
watcher: Option<(RecommendedWatcher, Receiver<NotifyEvent>)>,

crates/vfs/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ impl Vfs {
201201
pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) -> bool {
202202
let _p = span!(Level::INFO, "Vfs::set_file_contents").entered();
203203
let file_id = self.alloc_file_id(path);
204-
let state = self.get(file_id);
205-
let change_kind = match (state, contents) {
204+
let state: FileState = self.get(file_id);
205+
let change = match (state, contents) {
206206
(FileState::Deleted, None) => return false,
207207
(FileState::Deleted, Some(v)) => {
208208
let hash = hash_once::<FxHasher>(&*v);
@@ -225,7 +225,7 @@ impl Vfs {
225225
};
226226
};
227227

228-
let changed_file = ChangedFile { file_id, change: change_kind };
228+
let changed_file = ChangedFile { file_id, change };
229229
match self.changes.entry(file_id) {
230230
// two changes to the same file in one cycle, merge them appropriately
231231
Entry::Occupied(mut o) => {

0 commit comments

Comments
 (0)