diff options
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 103 |
1 files changed, 56 insertions, 47 deletions
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index e087c4f7e..7822be2e2 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -9,7 +9,7 @@ use std::{error::Error, fmt, panic, path::PathBuf, sync::Arc, time::Instant}; | |||
9 | 9 | ||
10 | use crossbeam_channel::{select, unbounded, RecvError, Sender}; | 10 | use crossbeam_channel::{select, unbounded, RecvError, Sender}; |
11 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; | 11 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; |
12 | use lsp_types::{ClientCapabilities, NumberOrString}; | 12 | use lsp_types::{ClientCapabilities, NumberOrString, Url}; |
13 | use ra_cargo_watch::{CheckOptions, CheckTask}; | 13 | use ra_cargo_watch::{CheckOptions, CheckTask}; |
14 | use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; | 14 | use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; |
15 | use ra_prof::profile; | 15 | use ra_prof::profile; |
@@ -336,52 +336,7 @@ fn loop_turn( | |||
336 | world_state.maybe_collect_garbage(); | 336 | world_state.maybe_collect_garbage(); |
337 | loop_state.in_flight_libraries -= 1; | 337 | loop_state.in_flight_libraries -= 1; |
338 | } | 338 | } |
339 | Event::CheckWatcher(task) => match task { | 339 | Event::CheckWatcher(task) => on_check_task(task, world_state, task_sender)?, |
340 | CheckTask::ClearDiagnostics => { | ||
341 | let cleared_files = world_state.check_watcher.state.write().clear(); | ||
342 | |||
343 | // Send updated diagnostics for each cleared file | ||
344 | for url in cleared_files { | ||
345 | let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?; | ||
346 | if let Some(file_id) = world_state.vfs.read().path2file(&path) { | ||
347 | let params = handlers::publish_diagnostics( | ||
348 | &world_state.snapshot(), | ||
349 | FileId(file_id.0), | ||
350 | )?; | ||
351 | let not = notification_new::<req::PublishDiagnostics>(params); | ||
352 | task_sender.send(Task::Notify(not)).unwrap(); | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | |||
357 | CheckTask::AddDiagnostic(url, diagnostic) => { | ||
358 | world_state | ||
359 | .check_watcher | ||
360 | .state | ||
361 | .write() | ||
362 | .add_diagnostic_with_fixes(url.clone(), diagnostic); | ||
363 | |||
364 | // We manually send a diagnostic update when the watcher asks | ||
365 | // us to, to avoid the issue of having to change the file to | ||
366 | // receive updated diagnostics. | ||
367 | let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?; | ||
368 | if let Some(file_id) = world_state.vfs.read().path2file(&path) { | ||
369 | let params = | ||
370 | handlers::publish_diagnostics(&world_state.snapshot(), FileId(file_id.0))?; | ||
371 | let not = notification_new::<req::PublishDiagnostics>(params); | ||
372 | task_sender.send(Task::Notify(not)).unwrap(); | ||
373 | } | ||
374 | } | ||
375 | |||
376 | CheckTask::Status(progress) => { | ||
377 | let params = req::ProgressParams { | ||
378 | token: req::ProgressToken::String("rustAnalyzer/cargoWatcher".to_string()), | ||
379 | value: req::ProgressParamsValue::WorkDone(progress), | ||
380 | }; | ||
381 | let not = notification_new::<req::Progress>(params); | ||
382 | task_sender.send(Task::Notify(not)).unwrap(); | ||
383 | } | ||
384 | }, | ||
385 | Event::Msg(msg) => match msg { | 340 | Event::Msg(msg) => match msg { |
386 | Message::Request(req) => on_request( | 341 | Message::Request(req) => on_request( |
387 | world_state, | 342 | world_state, |
@@ -629,6 +584,60 @@ fn on_notification( | |||
629 | Ok(()) | 584 | Ok(()) |
630 | } | 585 | } |
631 | 586 | ||
587 | fn on_check_task( | ||
588 | task: CheckTask, | ||
589 | world_state: &WorldState, | ||
590 | task_sender: &Sender<Task>, | ||
591 | ) -> Result<()> { | ||
592 | match task { | ||
593 | CheckTask::ClearDiagnostics => { | ||
594 | let cleared_files = world_state.check_watcher.state.write().clear(); | ||
595 | |||
596 | // Send updated diagnostics for each cleared file | ||
597 | for url in cleared_files { | ||
598 | publish_diagnostics_for_url(&url, world_state, task_sender)?; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | CheckTask::AddDiagnostic(url, diagnostic) => { | ||
603 | world_state | ||
604 | .check_watcher | ||
605 | .state | ||
606 | .write() | ||
607 | .add_diagnostic_with_fixes(url.clone(), diagnostic); | ||
608 | |||
609 | // We manually send a diagnostic update when the watcher asks | ||
610 | // us to, to avoid the issue of having to change the file to | ||
611 | // receive updated diagnostics. | ||
612 | publish_diagnostics_for_url(&url, world_state, task_sender)?; | ||
613 | } | ||
614 | |||
615 | CheckTask::Status(progress) => { | ||
616 | let params = req::ProgressParams { | ||
617 | token: req::ProgressToken::String("rustAnalyzer/cargoWatcher".to_string()), | ||
618 | value: req::ProgressParamsValue::WorkDone(progress), | ||
619 | }; | ||
620 | let not = notification_new::<req::Progress>(params); | ||
621 | task_sender.send(Task::Notify(not)).unwrap(); | ||
622 | } | ||
623 | } | ||
624 | Ok(()) | ||
625 | } | ||
626 | |||
627 | fn publish_diagnostics_for_url( | ||
628 | url: &Url, | ||
629 | world_state: &WorldState, | ||
630 | task_sender: &Sender<Task>, | ||
631 | ) -> Result<()> { | ||
632 | let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?; | ||
633 | if let Some(file_id) = world_state.vfs.read().path2file(&path) { | ||
634 | let params = handlers::publish_diagnostics(&world_state.snapshot(), FileId(file_id.0))?; | ||
635 | let not = notification_new::<req::PublishDiagnostics>(params); | ||
636 | task_sender.send(Task::Notify(not)).unwrap(); | ||
637 | } | ||
638 | Ok(()) | ||
639 | } | ||
640 | |||
632 | struct PoolDispatcher<'a> { | 641 | struct PoolDispatcher<'a> { |
633 | req: Option<Request>, | 642 | req: Option<Request>, |
634 | pool: &'a ThreadPool, | 643 | pool: &'a ThreadPool, |