-
Notifications
You must be signed in to change notification settings - Fork 63
fix: avoid redundant workspace reloads on startup #995
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,6 +53,8 @@ pub struct EmmyLuaAnalysis { | |
| pub compilation: LuaCompilation, | ||
| pub diagnostic: LuaDiagnostic, | ||
| pub emmyrc: Arc<Emmyrc>, | ||
| #[cfg(test)] | ||
| reindex_count: usize, | ||
| } | ||
|
|
||
| impl EmmyLuaAnalysis { | ||
|
|
@@ -62,6 +64,8 @@ impl EmmyLuaAnalysis { | |
| compilation: LuaCompilation::new(emmyrc.clone()), | ||
| diagnostic: LuaDiagnostic::new(), | ||
| emmyrc, | ||
| #[cfg(test)] | ||
| reindex_count: 0, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -239,17 +243,24 @@ impl EmmyLuaAnalysis { | |
| let mut kept_paths = open_paths.clone(); | ||
| kept_paths.extend(files.iter().map(|(path, _)| path.clone())); | ||
|
|
||
| let stale_uris = { | ||
| let (had_existing_non_std_local_files, stale_uris) = { | ||
| let db = self.compilation.get_db(); | ||
| let vfs = db.get_vfs(); | ||
| let module_index = db.get_module_index(); | ||
| vfs.get_all_local_file_ids() | ||
| let mut had_existing_non_std_local_files = false; | ||
| let stale_uris = vfs | ||
| .get_all_local_file_ids() | ||
| .into_iter() | ||
| .filter(|file_id| !module_index.is_std(file_id)) | ||
| .filter(|file_id| { | ||
| let is_non_std = !module_index.is_std(file_id); | ||
| had_existing_non_std_local_files |= is_non_std; | ||
| is_non_std | ||
| }) | ||
| .filter_map(|file_id| vfs.get_file_path(&file_id).cloned()) | ||
| .filter(|path| !kept_paths.contains(path)) | ||
| .filter_map(|path| file_path_to_uri(&path)) | ||
| .collect::<Vec<_>>() | ||
| .collect::<Vec<_>>(); | ||
| (had_existing_non_std_local_files, stale_uris) | ||
| }; | ||
| for uri in &stale_uris { | ||
| self.remove_file_by_uri(uri); | ||
|
|
@@ -267,7 +278,9 @@ impl EmmyLuaAnalysis { | |
| .map(|(uri, text)| (uri, Some(text))) | ||
| .collect(), | ||
| ); | ||
| self.reindex(); | ||
| if had_existing_non_std_local_files { | ||
| self.reindex(); | ||
| } | ||
| stale_uris | ||
| } | ||
|
|
||
|
|
@@ -291,6 +304,10 @@ impl EmmyLuaAnalysis { | |
| } | ||
|
|
||
| pub fn reindex(&mut self) { | ||
| #[cfg(test)] | ||
| { | ||
| self.reindex_count += 1; | ||
| } | ||
| let file_ids = self.compilation.get_db().get_vfs().get_all_file_ids(); | ||
| self.compilation.clear_index(); | ||
| self.compilation.update_index(file_ids); | ||
|
|
@@ -417,3 +434,44 @@ impl Default for EmmyLuaAnalysis { | |
|
|
||
| unsafe impl Send for EmmyLuaAnalysis {} | ||
| unsafe impl Sync for EmmyLuaAnalysis {} | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn reload_workspace_files_skips_reindex_when_bootstrapping_workspace() { | ||
| let mut analysis = EmmyLuaAnalysis::new(); | ||
| let workspace_root = std::env::current_dir().unwrap(); | ||
| let file_path = workspace_root.join("__reload_workspace_startup_test.lua"); | ||
| analysis.add_main_workspace(workspace_root); | ||
|
|
||
| analysis.reload_workspace_files( | ||
| vec![(file_path.clone(), Some("return true\n".to_string()))], | ||
| Vec::new(), | ||
| ); | ||
|
|
||
| assert_eq!(analysis.reindex_count, 0); | ||
| assert!( | ||
| analysis | ||
| .get_file_id(&file_path_to_uri(&file_path).unwrap()) | ||
| .is_some() | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn reload_workspace_files_reindexes_existing_workspace_files() { | ||
| let mut analysis = EmmyLuaAnalysis::new(); | ||
| let workspace_root = std::env::current_dir().unwrap(); | ||
| let file_path = workspace_root.join("__reload_workspace_existing_test.lua"); | ||
| analysis.add_main_workspace(workspace_root); | ||
| analysis.update_files_by_path(vec![(file_path.clone(), Some("return true\n".to_string()))]); | ||
|
|
||
| analysis.reload_workspace_files( | ||
| vec![(file_path, Some("return false\n".to_string()))], | ||
| Vec::new(), | ||
| ); | ||
|
|
||
| assert_eq!(analysis.reindex_count, 1); | ||
| } | ||
| } | ||
|
Comment on lines
+439
to
+477
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests create files in the current working directory and do not clean them up, which can pollute the development environment. It's best practice for tests to be self-contained. Please use a temporary directory for test files and ensure they are cleaned up. The mod tests {
use super::*;
#[test]
fn reload_workspace_files_skips_reindex_when_bootstrapping_workspace() {
let temp_dir = tempfile::tempdir().unwrap();
let workspace_root = temp_dir.path().to_path_buf();
let mut analysis = EmmyLuaAnalysis::new();
let file_path = workspace_root.join("__reload_workspace_startup_test.lua");
analysis.add_main_workspace(workspace_root);
analysis.reload_workspace_files(
vec![(file_path.clone(), Some("return true\n".to_string()))],
Vec::new(),
);
assert_eq!(analysis.reindex_count, 0);
assert!(
analysis
.get_file_id(&file_path_to_uri(&file_path).unwrap())
.is_some()
);
}
#[test]
fn reload_workspace_files_reindexes_existing_workspace_files() {
let temp_dir = tempfile::tempdir().unwrap();
let workspace_root = temp_dir.path().to_path_buf();
let mut analysis = EmmyLuaAnalysis::new();
let file_path = workspace_root.join("__reload_workspace_existing_test.lua");
analysis.add_main_workspace(workspace_root);
analysis.update_files_by_path(vec![(file_path.clone(), Some("return true\n".to_string()))]);
analysis.reload_workspace_files(
vec![(file_path, Some("return false\n".to_string()))],
Vec::new(),
);
assert_eq!(analysis.reindex_count, 1);
}
} |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a side-effect inside a
filterclosure makes the code less readable and harder to reason about. A more idiomatic and clearer approach would be to separate the check for existing files from the filtering logic. For example, you could usepeekable()on the iterator to check if it's empty before proceeding to collect the stale URIs. This would make the intent of the code more explicit.