aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/main_loop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop.rs')
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs31
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;
2mod subscriptions; 2mod subscriptions;
3pub(crate) mod pending_requests; 3pub(crate) mod pending_requests;
4 4
5use std::{fmt, path::PathBuf, sync::Arc, time::Instant}; 5use std::{fmt, path::PathBuf, sync::Arc, time::Instant, error::Error};
6 6
7use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; 7use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender};
8use failure::{bail, format_err};
9use failure_derive::Fail;
10use gen_lsp_server::{ 8use 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::{
32const THREADPOOL_SIZE: usize = 8; 30const THREADPOOL_SIZE: usize = 8;
33const MAX_IN_FLIGHT_LIBS: usize = THREADPOOL_SIZE - 3; 31const 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)]
37pub struct LspError { 34pub 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
45impl 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
51impl Error for LspError {}
52
48pub fn main_loop( 53pub 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
602fn is_canceled(e: &failure::Error) -> bool { 607fn 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}