aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs103
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
10use crossbeam_channel::{select, unbounded, RecvError, Sender}; 10use crossbeam_channel::{select, unbounded, RecvError, Sender};
11use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; 11use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
12use lsp_types::{ClientCapabilities, NumberOrString}; 12use lsp_types::{ClientCapabilities, NumberOrString, Url};
13use ra_cargo_watch::{CheckOptions, CheckTask}; 13use ra_cargo_watch::{CheckOptions, CheckTask};
14use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; 14use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId};
15use ra_prof::profile; 15use 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
587fn 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
627fn 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
632struct PoolDispatcher<'a> { 641struct PoolDispatcher<'a> {
633 req: Option<Request>, 642 req: Option<Request>,
634 pool: &'a ThreadPool, 643 pool: &'a ThreadPool,