From 4e145d4c40629265ee6f58305f6b506fe8bd75e5 Mon Sep 17 00:00:00 2001 From: Joe Neeman Date: Mon, 10 Jun 2024 09:39:10 -0500 Subject: [PATCH] Update dependencies in the background evaluator The background evaluator needs to track dependencies separately, because it doesn't share file ids with the main cache. This updates the background dependencies when the foreground ones get updated. --- lsp/nls/src/background.rs | 33 +++++++++++++++++++++++++++------ lsp/nls/src/server.rs | 4 ++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lsp/nls/src/background.rs b/lsp/nls/src/background.rs index c9cb95ae7d..772ad572bc 100644 --- a/lsp/nls/src/background.rs +++ b/lsp/nls/src/background.rs @@ -5,6 +5,7 @@ use std::{ }; use anyhow::anyhow; +use codespan::FileId; use crossbeam::channel::{bounded, Receiver, RecvTimeoutError, Sender}; use log::warn; use lsp_types::Url; @@ -28,6 +29,10 @@ enum Command { text: String, deps: Vec, }, + UpdateDeps { + uri: Url, + deps: Vec, + }, EvalFile { uri: Url, }, @@ -218,6 +223,9 @@ impl SupervisorState { self.contents.insert(uri.clone(), text); self.deps.insert(uri, deps); } + Command::UpdateDeps { uri, deps } => { + self.deps.insert(uri, deps); + } Command::EvalFile { uri } => { if !self.banned_files.contains(&uri) { // If we re-request an evaluation, remove the old one. (This is quadratic in the @@ -292,17 +300,30 @@ impl BackgroundJobs { } } - pub fn update_file(&mut self, uri: Url, text: String, world: &World) { - let Ok(Some(file_id)) = world.cache.file_id(&uri) else { - return; - }; - let deps = world + fn deps(&self, file_id: FileId, world: &World) -> Vec { + world .cache .get_imports(file_id) .filter_map(|dep_id| world.file_uris.get(&dep_id)) .cloned() - .collect(); + .collect() + } + pub fn update_file_deps(&mut self, uri: Url, world: &World) { + let Ok(Some(file_id)) = world.cache.file_id(&uri) else { + return; + }; + let deps = self.deps(file_id, world); + // Ignore errors here, because if we've failed to set up a background worker + // then we just skip doing background evaluation. + let _ = self.sender.send(Command::UpdateDeps { uri, deps }); + } + + pub fn update_file(&mut self, uri: Url, text: String, world: &World) { + let Ok(Some(file_id)) = world.cache.file_id(&uri) else { + return; + }; + let deps = self.deps(file_id, world); // Ignore errors here, because if we've failed to set up a background worker // then we just skip doing background evaluation. let _ = self.sender.send(Command::UpdateFile { uri, text, deps }); diff --git a/lsp/nls/src/server.rs b/lsp/nls/src/server.rs index e67347ad14..0ef2297517 100644 --- a/lsp/nls/src/server.rs +++ b/lsp/nls/src/server.rs @@ -188,6 +188,8 @@ impl Server { .update_file(uri.clone(), contents, &self.world); self.background_jobs.eval_file(uri); for uri in invalid { + self.background_jobs + .update_file_deps(uri.clone(), &self.world); self.background_jobs.eval_file(uri); } Ok(()) @@ -203,6 +205,8 @@ impl Server { .update_file(uri.clone(), contents, &self.world); self.background_jobs.eval_file(uri); for uri in invalid { + self.background_jobs + .update_file_deps(uri.clone(), &self.world); self.background_jobs.eval_file(uri); } Ok(())