mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 21:54:42 +00:00
Wait with change processing until the vfs is done
This commit is contained in:
parent
8286847bee
commit
c6ae9cde99
5 changed files with 34 additions and 30 deletions
|
@ -33,7 +33,7 @@ use crate::{
|
|||
lsp_ext,
|
||||
main_loop::Task,
|
||||
mem_docs::MemDocs,
|
||||
op_queue::OpQueue,
|
||||
op_queue::{Cause, OpQueue},
|
||||
reload,
|
||||
target_spec::{CargoTargetSpec, ProjectJsonTargetSpec, TargetSpec},
|
||||
task_pool::{TaskPool, TaskQueue},
|
||||
|
@ -108,8 +108,8 @@ pub(crate) struct GlobalState {
|
|||
pub(crate) vfs: Arc<RwLock<(vfs::Vfs, IntMap<FileId, LineEndings>)>>,
|
||||
pub(crate) vfs_config_version: u32,
|
||||
pub(crate) vfs_progress_config_version: u32,
|
||||
pub(crate) vfs_progress_n_total: usize,
|
||||
pub(crate) vfs_progress_n_done: usize,
|
||||
pub(crate) vfs_done: bool,
|
||||
pub(crate) wants_to_switch: Option<Cause>,
|
||||
|
||||
/// `workspaces` field stores the data we actually use, while the `OpQueue`
|
||||
/// stores the result of the last fetch.
|
||||
|
@ -252,8 +252,8 @@ impl GlobalState {
|
|||
vfs: Arc::new(RwLock::new((vfs::Vfs::default(), IntMap::default()))),
|
||||
vfs_config_version: 0,
|
||||
vfs_progress_config_version: 0,
|
||||
vfs_progress_n_total: 0,
|
||||
vfs_progress_n_done: 0,
|
||||
vfs_done: true,
|
||||
wants_to_switch: None,
|
||||
|
||||
workspaces: Arc::from(Vec::new()),
|
||||
crate_graph_file_dependencies: FxHashSet::default(),
|
||||
|
|
|
@ -375,9 +375,14 @@ impl GlobalState {
|
|||
}
|
||||
}
|
||||
let event_handling_duration = loop_start.elapsed();
|
||||
|
||||
let state_changed = self.process_changes();
|
||||
let memdocs_added_or_removed = self.mem_docs.take_changes();
|
||||
let (state_changed, memdocs_added_or_removed) = if self.vfs_done {
|
||||
if let Some(cause) = self.wants_to_switch.take() {
|
||||
self.switch_workspaces(cause);
|
||||
}
|
||||
(self.process_changes(), self.mem_docs.take_changes())
|
||||
} else {
|
||||
(false, false)
|
||||
};
|
||||
|
||||
if self.is_quiescent() {
|
||||
let became_quiescent = !was_quiescent;
|
||||
|
@ -672,7 +677,7 @@ impl GlobalState {
|
|||
if let Err(e) = self.fetch_workspace_error() {
|
||||
error!("FetchWorkspaceError:\n{e}");
|
||||
}
|
||||
self.switch_workspaces("fetched workspace".to_owned());
|
||||
self.wants_to_switch = Some("fetched workspace".to_owned());
|
||||
(Progress::End, None)
|
||||
}
|
||||
};
|
||||
|
@ -718,8 +723,9 @@ impl GlobalState {
|
|||
error!("FetchBuildDataError:\n{e}");
|
||||
}
|
||||
|
||||
self.switch_workspaces("fetched build data".to_owned());
|
||||
|
||||
if self.wants_to_switch.is_none() {
|
||||
self.wants_to_switch = Some("fetched build data".to_owned());
|
||||
}
|
||||
(Some(Progress::End), None)
|
||||
}
|
||||
};
|
||||
|
@ -779,8 +785,7 @@ impl GlobalState {
|
|||
};
|
||||
|
||||
self.vfs_progress_config_version = config_version;
|
||||
self.vfs_progress_n_total = n_total;
|
||||
self.vfs_progress_n_done = n_done;
|
||||
self.vfs_done = state == Progress::End;
|
||||
|
||||
let mut message = format!("{n_done}/{n_total}");
|
||||
if let Some(dir) = dir {
|
||||
|
|
|
@ -62,13 +62,13 @@ pub(crate) enum ProcMacroProgress {
|
|||
|
||||
impl GlobalState {
|
||||
pub(crate) fn is_quiescent(&self) -> bool {
|
||||
!(self.last_reported_status.is_none()
|
||||
|| self.fetch_workspaces_queue.op_in_progress()
|
||||
|| self.fetch_build_data_queue.op_in_progress()
|
||||
|| self.fetch_proc_macros_queue.op_in_progress()
|
||||
|| self.discover_workspace_queue.op_in_progress()
|
||||
|| self.vfs_progress_config_version < self.vfs_config_version
|
||||
|| self.vfs_progress_n_done < self.vfs_progress_n_total)
|
||||
self.vfs_done
|
||||
&& self.last_reported_status.is_some()
|
||||
&& !self.fetch_workspaces_queue.op_in_progress()
|
||||
&& !self.fetch_build_data_queue.op_in_progress()
|
||||
&& !self.fetch_proc_macros_queue.op_in_progress()
|
||||
&& !self.discover_workspace_queue.op_in_progress()
|
||||
&& self.vfs_progress_config_version >= self.vfs_config_version
|
||||
}
|
||||
|
||||
pub(crate) fn update_configuration(&mut self, config: Config) {
|
||||
|
@ -102,15 +102,13 @@ impl GlobalState {
|
|||
}
|
||||
|
||||
pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams {
|
||||
let mut status = lsp_ext::ServerStatusParams {
|
||||
health: lsp_ext::Health::Ok,
|
||||
quiescent: self.is_quiescent(),
|
||||
message: None,
|
||||
};
|
||||
let quiescent = self.is_quiescent();
|
||||
let mut status =
|
||||
lsp_ext::ServerStatusParams { health: lsp_ext::Health::Ok, quiescent, message: None };
|
||||
let mut message = String::new();
|
||||
|
||||
if !self.config.cargo_autoreload(None)
|
||||
&& self.is_quiescent()
|
||||
&& quiescent
|
||||
&& self.fetch_workspaces_queue.op_requested()
|
||||
&& self.config.discover_workspace_config().is_none()
|
||||
{
|
||||
|
@ -242,7 +240,7 @@ impl GlobalState {
|
|||
let discover_command = self.config.discover_workspace_config().cloned();
|
||||
let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
|
||||
|| self.vfs_progress_config_version < self.vfs_config_version
|
||||
|| self.vfs_progress_n_done < self.vfs_progress_n_total);
|
||||
|| !self.vfs_done);
|
||||
|
||||
move |sender| {
|
||||
let progress = {
|
||||
|
|
|
@ -61,6 +61,7 @@ type NotifyEvent = notify::Result<notify::Event>;
|
|||
|
||||
struct NotifyActor {
|
||||
sender: loader::Sender,
|
||||
// FIXME: Consider hashset
|
||||
watched_entries: Vec<loader::Entry>,
|
||||
// Drop order is significant.
|
||||
watcher: Option<(RecommendedWatcher, Receiver<NotifyEvent>)>,
|
||||
|
|
|
@ -201,8 +201,8 @@ impl Vfs {
|
|||
pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) -> bool {
|
||||
let _p = span!(Level::INFO, "Vfs::set_file_contents").entered();
|
||||
let file_id = self.alloc_file_id(path);
|
||||
let state = self.get(file_id);
|
||||
let change_kind = match (state, contents) {
|
||||
let state: FileState = self.get(file_id);
|
||||
let change = match (state, contents) {
|
||||
(FileState::Deleted, None) => return false,
|
||||
(FileState::Deleted, Some(v)) => {
|
||||
let hash = hash_once::<FxHasher>(&*v);
|
||||
|
@ -225,7 +225,7 @@ impl Vfs {
|
|||
};
|
||||
};
|
||||
|
||||
let changed_file = ChangedFile { file_id, change: change_kind };
|
||||
let changed_file = ChangedFile { file_id, change };
|
||||
match self.changes.entry(file_id) {
|
||||
// two changes to the same file in one cycle, merge them appropriately
|
||||
Entry::Occupied(mut o) => {
|
||||
|
|
Loading…
Reference in a new issue