diff options
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop.rs')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 0790ea472..fe6b360d4 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -2,11 +2,9 @@ mod handlers; | |||
2 | mod subscriptions; | 2 | mod subscriptions; |
3 | pub(crate) mod pending_requests; | 3 | pub(crate) mod pending_requests; |
4 | 4 | ||
5 | use std::{fmt, path::PathBuf, sync::Arc, time::Instant}; | 5 | use std::{fmt, path::PathBuf, sync::Arc, time::Instant, error::Error}; |
6 | 6 | ||
7 | use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; | 7 | use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; |
8 | use failure::{bail, format_err}; | ||
9 | use failure_derive::Fail; | ||
10 | use gen_lsp_server::{ | 8 | use gen_lsp_server::{ |
11 | handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, | 9 | handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, |
12 | }; | 10 | }; |
@@ -32,8 +30,7 @@ use crate::{ | |||
32 | const THREADPOOL_SIZE: usize = 8; | 30 | const THREADPOOL_SIZE: usize = 8; |
33 | const MAX_IN_FLIGHT_LIBS: usize = THREADPOOL_SIZE - 3; | 31 | const MAX_IN_FLIGHT_LIBS: usize = THREADPOOL_SIZE - 3; |
34 | 32 | ||
35 | #[derive(Debug, Fail)] | 33 | #[derive(Debug)] |
36 | #[fail(display = "Language Server request failed with {}. ({})", code, message)] | ||
37 | pub struct LspError { | 34 | pub struct LspError { |
38 | pub code: i32, | 35 | pub code: i32, |
39 | pub message: String, | 36 | pub message: String, |
@@ -45,6 +42,14 @@ impl LspError { | |||
45 | } | 42 | } |
46 | } | 43 | } |
47 | 44 | ||
45 | impl fmt::Display for LspError { | ||
46 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
47 | write!(f, "Language Server request failed with {}. ({})", self.code, self.message) | ||
48 | } | ||
49 | } | ||
50 | |||
51 | impl Error for LspError {} | ||
52 | |||
48 | pub fn main_loop( | 53 | pub fn main_loop( |
49 | ws_roots: Vec<PathBuf>, | 54 | ws_roots: Vec<PathBuf>, |
50 | options: InitializationOptions, | 55 | options: InitializationOptions, |
@@ -177,12 +182,12 @@ fn main_loop_inner( | |||
177 | let event = select! { | 182 | let event = select! { |
178 | recv(msg_receiver) -> msg => match msg { | 183 | recv(msg_receiver) -> msg => match msg { |
179 | Ok(msg) => Event::Msg(msg), | 184 | Ok(msg) => Event::Msg(msg), |
180 | Err(RecvError) => bail!("client exited without shutdown"), | 185 | Err(RecvError) => Err("client exited without shutdown")?, |
181 | }, | 186 | }, |
182 | recv(task_receiver) -> task => Event::Task(task.unwrap()), | 187 | recv(task_receiver) -> task => Event::Task(task.unwrap()), |
183 | recv(state.vfs.read().task_receiver()) -> task => match task { | 188 | recv(state.vfs.read().task_receiver()) -> task => match task { |
184 | Ok(task) => Event::Vfs(task), | 189 | Ok(task) => Event::Vfs(task), |
185 | Err(RecvError) => bail!("vfs died"), | 190 | Err(RecvError) => Err("vfs died")?, |
186 | }, | 191 | }, |
187 | recv(libdata_receiver) -> data => Event::Lib(data.unwrap()) | 192 | recv(libdata_receiver) -> data => Event::Lib(data.unwrap()) |
188 | }; | 193 | }; |
@@ -380,7 +385,7 @@ fn on_notification( | |||
380 | let not = match not.cast::<req::DidOpenTextDocument>() { | 385 | let not = match not.cast::<req::DidOpenTextDocument>() { |
381 | Ok(params) => { | 386 | Ok(params) => { |
382 | let uri = params.text_document.uri; | 387 | let uri = params.text_document.uri; |
383 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; | 388 | let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?; |
384 | if let Some(file_id) = | 389 | if let Some(file_id) = |
385 | state.vfs.write().add_file_overlay(&path, params.text_document.text) | 390 | state.vfs.write().add_file_overlay(&path, params.text_document.text) |
386 | { | 391 | { |
@@ -393,9 +398,9 @@ fn on_notification( | |||
393 | let not = match not.cast::<req::DidChangeTextDocument>() { | 398 | let not = match not.cast::<req::DidChangeTextDocument>() { |
394 | Ok(mut params) => { | 399 | Ok(mut params) => { |
395 | let uri = params.text_document.uri; | 400 | let uri = params.text_document.uri; |
396 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; | 401 | let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?; |
397 | let text = | 402 | let text = |
398 | params.content_changes.pop().ok_or_else(|| format_err!("empty changes"))?.text; | 403 | params.content_changes.pop().ok_or_else(|| format!("empty changes"))?.text; |
399 | state.vfs.write().change_file_overlay(path.as_path(), text); | 404 | state.vfs.write().change_file_overlay(path.as_path(), text); |
400 | return Ok(()); | 405 | return Ok(()); |
401 | } | 406 | } |
@@ -404,7 +409,7 @@ fn on_notification( | |||
404 | let not = match not.cast::<req::DidCloseTextDocument>() { | 409 | let not = match not.cast::<req::DidCloseTextDocument>() { |
405 | Ok(params) => { | 410 | Ok(params) => { |
406 | let uri = params.text_document.uri; | 411 | let uri = params.text_document.uri; |
407 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; | 412 | let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?; |
408 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { | 413 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { |
409 | subs.remove_sub(FileId(file_id.0)); | 414 | subs.remove_sub(FileId(file_id.0)); |
410 | } | 415 | } |
@@ -546,7 +551,7 @@ where | |||
546 | RawResponse::err( | 551 | RawResponse::err( |
547 | id, | 552 | id, |
548 | ErrorCode::InternalError as i32, | 553 | ErrorCode::InternalError as i32, |
549 | format!("{}\n{}", e, e.backtrace()), | 554 | e.to_string() |
550 | ) | 555 | ) |
551 | } | 556 | } |
552 | } | 557 | } |
@@ -599,6 +604,6 @@ fn show_message(typ: req::MessageType, message: impl Into<String>, sender: &Send | |||
599 | sender.send(not.into()).unwrap(); | 604 | sender.send(not.into()).unwrap(); |
600 | } | 605 | } |
601 | 606 | ||
602 | fn is_canceled(e: &failure::Error) -> bool { | 607 | fn is_canceled(e: &Box<dyn std::error::Error + Send + Sync>) -> bool { |
603 | e.downcast_ref::<Canceled>().is_some() | 608 | e.downcast_ref::<Canceled>().is_some() |
604 | } | 609 | } |