From 8875f2c8aa9933b35854311256987abeece17f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Fri, 10 Sep 2021 19:34:47 +0300 Subject: [PATCH 1/2] Fix Cargo.toml change detection --- crates/rust-analyzer/src/global_state.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 19ddd7c717d..6744bf62da8 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -186,9 +186,9 @@ impl GlobalState { } for file in changed_files { - if file.is_created_or_deleted() { - if let Some(path) = vfs.file_path(file.file_id).as_path() { - fs_changes.push((path.to_path_buf(), file.change_kind)); + if let Some(path) = vfs.file_path(file.file_id).as_path() { + fs_changes.push((path.to_path_buf(), file.change_kind)); + if file.is_created_or_deleted() { has_fs_changes = true; } } From 4d7a3bb5c72a8ecc5f9fe84f29425bc868908f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 13 Sep 2021 20:58:09 +0300 Subject: [PATCH 2/2] Shuffle code around to avoid an allocation --- crates/rust-analyzer/src/global_state.rs | 16 +++-- crates/rust-analyzer/src/main_loop.rs | 6 +- crates/rust-analyzer/src/reload.rs | 88 ++++++++++-------------- 3 files changed, 50 insertions(+), 60 deletions(-) diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 6744bf62da8..8e947b55402 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -25,7 +25,7 @@ use crate::{ main_loop::Task, mem_docs::MemDocs, op_queue::OpQueue, - reload::SourceRootConfig, + reload::{self, SourceRootConfig}, thread_pool::TaskPool, to_proto::url_from_abs_path, Result, @@ -175,7 +175,8 @@ impl GlobalState { pub(crate) fn process_changes(&mut self) -> bool { let _p = profile::span("GlobalState::process_changes"); let mut fs_changes = Vec::new(); - let mut has_fs_changes = false; + // A file was added or deleted + let mut has_structure_changes = false; let change = { let mut change = Change::new(); @@ -187,9 +188,13 @@ impl GlobalState { for file in changed_files { if let Some(path) = vfs.file_path(file.file_id).as_path() { - fs_changes.push((path.to_path_buf(), file.change_kind)); + let path = path.to_path_buf(); + if reload::should_refresh_for_change(&path, file.change_kind) { + self.fetch_workspaces_queue.request_op(); + } + fs_changes.push((path, file.change_kind)); if file.is_created_or_deleted() { - has_fs_changes = true; + has_structure_changes = true; } } @@ -208,7 +213,7 @@ impl GlobalState { }; change.change_file(file.file_id, text); } - if has_fs_changes { + if has_structure_changes { let roots = self.source_root_config.partition(vfs); change.set_roots(roots); } @@ -216,7 +221,6 @@ impl GlobalState { }; self.analysis_host.apply_change(change); - self.maybe_refresh(&fs_changes); true } diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 0d72f6ec97f..0c48b22bdba 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -21,7 +21,7 @@ use crate::{ handlers, lsp_ext, lsp_utils::{apply_document_changes, is_cancelled, notification_is, Progress}, mem_docs::DocumentData, - reload::{BuildDataProgress, ProjectWorkspaceProgress}, + reload::{self, BuildDataProgress, ProjectWorkspaceProgress}, Result, }; @@ -693,7 +693,9 @@ impl GlobalState { flycheck.update(); } if let Ok(abs_path) = from_proto::abs_path(¶ms.text_document.uri) { - this.maybe_refresh(&[(abs_path, ChangeKind::Modify)]); + if reload::should_refresh_for_change(&abs_path, ChangeKind::Modify) { + this.fetch_workspaces_queue.request_op(); + } } Ok(()) })? diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 2cb5eb46b25..b7fa9e3fa0d 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -58,58 +58,6 @@ impl GlobalState { .raw_database_mut() .set_enable_proc_attr_macros(self.config.expand_proc_attr_macros()); } - pub(crate) fn maybe_refresh(&mut self, changes: &[(AbsPathBuf, ChangeKind)]) { - if !changes.iter().any(|(path, kind)| is_interesting(path, *kind)) { - return; - } - tracing::info!( - "Requesting workspace reload because of the following changes: {}", - itertools::join( - changes - .iter() - .filter(|(path, kind)| is_interesting(path, *kind)) - .map(|(path, kind)| format!("{}: {:?}", path.display(), kind)), - ", " - ) - ); - self.fetch_workspaces_queue.request_op(); - - fn is_interesting(path: &AbsPath, change_kind: ChangeKind) -> bool { - const IMPLICIT_TARGET_FILES: &[&str] = &["build.rs", "src/main.rs", "src/lib.rs"]; - const IMPLICIT_TARGET_DIRS: &[&str] = &["src/bin", "examples", "tests", "benches"]; - let file_name = path.file_name().unwrap_or_default(); - - if file_name == "Cargo.toml" || file_name == "Cargo.lock" { - return true; - } - if change_kind == ChangeKind::Modify { - return false; - } - if path.extension().unwrap_or_default() != "rs" { - return false; - } - if IMPLICIT_TARGET_FILES.iter().any(|it| path.as_ref().ends_with(it)) { - return true; - } - let parent = match path.parent() { - Some(it) => it, - None => return false, - }; - if IMPLICIT_TARGET_DIRS.iter().any(|it| parent.as_ref().ends_with(it)) { - return true; - } - if file_name == "main.rs" { - let grand_parent = match parent.parent() { - Some(it) => it, - None => return false, - }; - if IMPLICIT_TARGET_DIRS.iter().any(|it| grand_parent.as_ref().ends_with(it)) { - return true; - } - } - false - } - } pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams { let mut status = lsp_ext::ServerStatusParams { @@ -617,3 +565,39 @@ pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath) } } } + +pub(crate) fn should_refresh_for_change(path: &AbsPath, change_kind: ChangeKind) -> bool { + const IMPLICIT_TARGET_FILES: &[&str] = &["build.rs", "src/main.rs", "src/lib.rs"]; + const IMPLICIT_TARGET_DIRS: &[&str] = &["src/bin", "examples", "tests", "benches"]; + let file_name = path.file_name().unwrap_or_default(); + + if file_name == "Cargo.toml" || file_name == "Cargo.lock" { + return true; + } + if change_kind == ChangeKind::Modify { + return false; + } + if path.extension().unwrap_or_default() != "rs" { + return false; + } + if IMPLICIT_TARGET_FILES.iter().any(|it| path.as_ref().ends_with(it)) { + return true; + } + let parent = match path.parent() { + Some(it) => it, + None => return false, + }; + if IMPLICIT_TARGET_DIRS.iter().any(|it| parent.as_ref().ends_with(it)) { + return true; + } + if file_name == "main.rs" { + let grand_parent = match parent.parent() { + Some(it) => it, + None => return false, + }; + if IMPLICIT_TARGET_DIRS.iter().any(|it| grand_parent.as_ref().ends_with(it)) { + return true; + } + } + false +}