Merge #2933
2933: Don't compute diagnostics on the main thread r=matklad a=matklad closes #2909 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
3ea8940d94
@ -9,7 +9,7 @@ use std::{error::Error, fmt, panic, path::PathBuf, sync::Arc, time::Instant};
|
||||
|
||||
use crossbeam_channel::{select, unbounded, RecvError, Sender};
|
||||
use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
|
||||
use lsp_types::{ClientCapabilities, NumberOrString, Url};
|
||||
use lsp_types::{ClientCapabilities, NumberOrString};
|
||||
use ra_cargo_watch::{CheckOptions, CheckTask};
|
||||
use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId};
|
||||
use ra_prof::profile;
|
||||
@ -352,7 +352,7 @@ fn loop_turn(
|
||||
world_state.maybe_collect_garbage();
|
||||
loop_state.in_flight_libraries -= 1;
|
||||
}
|
||||
Event::CheckWatcher(task) => on_check_task(task, world_state, task_sender)?,
|
||||
Event::CheckWatcher(task) => on_check_task(pool, task, world_state, task_sender)?,
|
||||
Event::Msg(msg) => match msg {
|
||||
Message::Request(req) => on_request(
|
||||
world_state,
|
||||
@ -602,31 +602,23 @@ fn on_notification(
|
||||
}
|
||||
|
||||
fn on_check_task(
|
||||
pool: &ThreadPool,
|
||||
task: CheckTask,
|
||||
world_state: &mut WorldState,
|
||||
task_sender: &Sender<Task>,
|
||||
) -> Result<()> {
|
||||
match task {
|
||||
let urls = match task {
|
||||
CheckTask::ClearDiagnostics => {
|
||||
let state = Arc::get_mut(&mut world_state.check_watcher.state)
|
||||
.expect("couldn't get check watcher state as mutable");
|
||||
let cleared_files = state.clear();
|
||||
|
||||
// Send updated diagnostics for each cleared file
|
||||
for url in cleared_files {
|
||||
publish_diagnostics_for_url(&url, world_state, task_sender)?;
|
||||
}
|
||||
state.clear()
|
||||
}
|
||||
|
||||
CheckTask::AddDiagnostic(url, diagnostic) => {
|
||||
let state = Arc::get_mut(&mut world_state.check_watcher.state)
|
||||
.expect("couldn't get check watcher state as mutable");
|
||||
state.add_diagnostic_with_fixes(url.clone(), diagnostic);
|
||||
|
||||
// We manually send a diagnostic update when the watcher asks
|
||||
// us to, to avoid the issue of having to change the file to
|
||||
// receive updated diagnostics.
|
||||
publish_diagnostics_for_url(&url, world_state, task_sender)?;
|
||||
vec![url]
|
||||
}
|
||||
|
||||
CheckTask::Status(progress) => {
|
||||
@ -636,22 +628,30 @@ fn on_check_task(
|
||||
};
|
||||
let not = notification_new::<req::Progress>(params);
|
||||
task_sender.send(Task::Notify(not)).unwrap();
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
|
||||
let subscriptions = urls
|
||||
.into_iter()
|
||||
.map(|url| {
|
||||
let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?;
|
||||
Ok(world_state.vfs.read().path2file(&path).map(|it| FileId(it.0)))
|
||||
})
|
||||
.filter_map(|res| res.transpose())
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
// We manually send a diagnostic update when the watcher asks
|
||||
// us to, to avoid the issue of having to change the file to
|
||||
// receive updated diagnostics.
|
||||
update_file_notifications_on_threadpool(
|
||||
pool,
|
||||
world_state.snapshot(),
|
||||
false,
|
||||
task_sender.clone(),
|
||||
subscriptions,
|
||||
);
|
||||
|
||||
fn publish_diagnostics_for_url(
|
||||
url: &Url,
|
||||
world_state: &WorldState,
|
||||
task_sender: &Sender<Task>,
|
||||
) -> Result<()> {
|
||||
let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?;
|
||||
if let Some(file_id) = world_state.vfs.read().path2file(&path) {
|
||||
let params = handlers::publish_diagnostics(&world_state.snapshot(), FileId(file_id.0))?;
|
||||
let not = notification_new::<req::PublishDiagnostics>(params);
|
||||
task_sender.send(Task::Notify(not)).unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user