mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
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 crossbeam_channel::{select, unbounded, RecvError, Sender};
|
||||||
use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
|
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_cargo_watch::{CheckOptions, CheckTask};
|
||||||
use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId};
|
use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
@ -352,7 +352,7 @@ fn loop_turn(
|
|||||||
world_state.maybe_collect_garbage();
|
world_state.maybe_collect_garbage();
|
||||||
loop_state.in_flight_libraries -= 1;
|
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 {
|
Event::Msg(msg) => match msg {
|
||||||
Message::Request(req) => on_request(
|
Message::Request(req) => on_request(
|
||||||
world_state,
|
world_state,
|
||||||
@ -602,31 +602,23 @@ fn on_notification(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_check_task(
|
fn on_check_task(
|
||||||
|
pool: &ThreadPool,
|
||||||
task: CheckTask,
|
task: CheckTask,
|
||||||
world_state: &mut WorldState,
|
world_state: &mut WorldState,
|
||||||
task_sender: &Sender<Task>,
|
task_sender: &Sender<Task>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match task {
|
let urls = match task {
|
||||||
CheckTask::ClearDiagnostics => {
|
CheckTask::ClearDiagnostics => {
|
||||||
let state = Arc::get_mut(&mut world_state.check_watcher.state)
|
let state = Arc::get_mut(&mut world_state.check_watcher.state)
|
||||||
.expect("couldn't get check watcher state as mutable");
|
.expect("couldn't get check watcher state as mutable");
|
||||||
let cleared_files = state.clear();
|
state.clear()
|
||||||
|
|
||||||
// Send updated diagnostics for each cleared file
|
|
||||||
for url in cleared_files {
|
|
||||||
publish_diagnostics_for_url(&url, world_state, task_sender)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckTask::AddDiagnostic(url, diagnostic) => {
|
CheckTask::AddDiagnostic(url, diagnostic) => {
|
||||||
let state = Arc::get_mut(&mut world_state.check_watcher.state)
|
let state = Arc::get_mut(&mut world_state.check_watcher.state)
|
||||||
.expect("couldn't get check watcher state as mutable");
|
.expect("couldn't get check watcher state as mutable");
|
||||||
state.add_diagnostic_with_fixes(url.clone(), diagnostic);
|
state.add_diagnostic_with_fixes(url.clone(), diagnostic);
|
||||||
|
vec![url]
|
||||||
// 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)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckTask::Status(progress) => {
|
CheckTask::Status(progress) => {
|
||||||
@ -636,22 +628,30 @@ fn on_check_task(
|
|||||||
};
|
};
|
||||||
let not = notification_new::<req::Progress>(params);
|
let not = notification_new::<req::Progress>(params);
|
||||||
task_sender.send(Task::Notify(not)).unwrap();
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user