diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2023-07-21 09:12:26 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-21 09:12:26 -0400 |
commit | d6e086d681fd0564bbb8e62744aca0514e3bc575 (patch) | |
tree | 5bc4e688c0250283f696c9d0ab68d524ba5a9466 /cli/lsp/language_server.rs | |
parent | da709729e3dd6f310182581ca1c6380ad51443fc (diff) |
fix(lsp): handle watched files events from symlinked config files (#19898)
Related to https://github.com/denoland/vscode_deno/issues/784
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r-- | cli/lsp/language_server.rs | 79 |
1 files changed, 50 insertions, 29 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 5a4c3aeae..3ac9610b3 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -1458,18 +1458,8 @@ impl Inner { &mut self, params: DidChangeWatchedFilesParams, ) { - fn has_lockfile_changed( - lockfile: &Lockfile, - changed_urls: &HashSet<Url>, - ) -> bool { - let lockfile_path = lockfile.filename.clone(); - let Ok(specifier) = ModuleSpecifier::from_file_path(&lockfile_path) else { - return false; - }; - if !changed_urls.contains(&specifier) { - return false; - } - match Lockfile::new(lockfile_path, false) { + fn has_lockfile_content_changed(lockfile: &Lockfile) -> bool { + match Lockfile::new(lockfile.filename.clone(), false) { Ok(new_lockfile) => { // only update if the lockfile has changed FastInsecureHasher::hash(lockfile) @@ -1482,6 +1472,53 @@ impl Inner { } } + fn has_config_changed(config: &Config, changes: &HashSet<Url>) -> bool { + // Check the canonicalized specifier here because file watcher + // changes will be for the canonicalized path in vscode, but also check the + // non-canonicalized specifier in order to please the tests and handle + // a client that might send that instead. + if config + .maybe_config_file_canonicalized_specifier() + .map(|s| changes.contains(s)) + .unwrap_or(false) + { + return true; + } + match config.maybe_config_file() { + Some(file) => { + if changes.contains(&file.specifier) { + return true; + } + } + None => { + // check for auto-discovery + if changes.iter().any(|url| { + url.path().ends_with("/deno.json") + || url.path().ends_with("/deno.jsonc") + }) { + return true; + } + } + } + + // if the lockfile has changed, reload the config as well + if let Some(lockfile) = config.maybe_lockfile() { + let lockfile_matches = config + .maybe_lockfile_canonicalized_specifier() + .map(|s| changes.contains(s)) + .or_else(|| { + ModuleSpecifier::from_file_path(&lockfile.lock().filename) + .ok() + .map(|s| changes.contains(&s)) + }) + .unwrap_or(false); + lockfile_matches && has_lockfile_content_changed(&lockfile.lock()) + } else { + // check for auto-discovery + changes.iter().any(|url| url.path().ends_with("/deno.lock")) + } + } + let mark = self .performance .mark("did_change_watched_files", Some(¶ms)); @@ -1493,23 +1530,7 @@ impl Inner { .collect(); // if the current deno.json has changed, we need to reload it - let has_config_changed = match self.config.maybe_config_file() { - Some(config_file) => changes.contains(&config_file.specifier), - None => { - // check for auto-discovery - changes.iter().any(|url| { - url.path().ends_with("/deno.json") - || url.path().ends_with("/deno.jsonc") - }) - } - } || match self.config.maybe_lockfile() { - Some(lockfile) => has_lockfile_changed(&lockfile.lock(), &changes), - None => { - // check for auto-discovery - changes.iter().any(|url| url.path().ends_with("/deno.lock")) - } - }; - if has_config_changed { + if has_config_changed(&self.config, &changes) { if let Err(err) = self.update_config_file().await { self.client.show_message(MessageType::WARNING, err); } |