fix: Fix completions disappearing when typing two keys in quick succession

This commit is contained in:
Lukas Wirth
2022-06-01 00:20:28 +02:00
parent 1234d8647f
commit e2da967578
7 changed files with 83 additions and 74 deletions

View File

@@ -1,12 +1,12 @@
//! See [RequestDispatcher].
use std::{fmt, panic, thread};
use ide::Cancelled;
use lsp_server::ExtractError;
use serde::{de::DeserializeOwned, Serialize};
use crate::{
global_state::{GlobalState, GlobalStateSnapshot},
lsp_utils::is_cancelled,
main_loop::Task,
LspError, Result,
};
@@ -37,38 +37,41 @@ impl<'a> RequestDispatcher<'a> {
pub(crate) fn on_sync_mut<R>(
&mut self,
f: fn(&mut GlobalState, R::Params) -> Result<R::Result>,
) -> Result<&mut Self>
) -> &mut Self
where
R: lsp_types::request::Request,
R::Params: DeserializeOwned + panic::UnwindSafe + fmt::Debug,
R::Result: Serialize,
{
let (id, params, panic_context) = match self.parse::<R>() {
let (req, params, panic_context) = match self.parse::<R>() {
Some(it) => it,
None => return Ok(self),
None => return self,
};
let result = {
let _pctx = stdx::panic_context::enter(panic_context);
f(self.global_state, params)
};
match result_to_response::<R>(req.id.clone(), result) {
Ok(response) => self.global_state.respond(response),
Err(_) => self.global_state.task_pool.handle.send_retry(req),
};
let _pctx = stdx::panic_context::enter(panic_context);
let result = f(self.global_state, params);
let response = result_to_response::<R>(id, result);
self.global_state.respond(response);
Ok(self)
self
}
/// Dispatches the request onto the current thread.
pub(crate) fn on_sync<R>(
&mut self,
f: fn(GlobalStateSnapshot, R::Params) -> Result<R::Result>,
) -> Result<&mut Self>
) -> &mut Self
where
R: lsp_types::request::Request + 'static,
R: lsp_types::request::Request,
R::Params: DeserializeOwned + panic::UnwindSafe + fmt::Debug,
R::Result: Serialize,
{
let (id, params, panic_context) = match self.parse::<R>() {
let (req, params, panic_context) = match self.parse::<R>() {
Some(it) => it,
None => return Ok(self),
None => return self,
};
let global_state_snapshot = self.global_state.snapshot();
@@ -76,10 +79,13 @@ impl<'a> RequestDispatcher<'a> {
let _pctx = stdx::panic_context::enter(panic_context);
f(global_state_snapshot, params)
});
let response = thread_result_to_response::<R>(id, result);
self.global_state.respond(response);
Ok(self)
match thread_result_to_response::<R>(req.id.clone(), result) {
Ok(response) => self.global_state.respond(response),
Err(_) => self.global_state.task_pool.handle.send_retry(req),
};
self
}
/// Dispatches the request onto thread pool
@@ -92,7 +98,7 @@ impl<'a> RequestDispatcher<'a> {
R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
R::Result: Serialize,
{
let (id, params, panic_context) = match self.parse::<R>() {
let (req, params, panic_context) = match self.parse::<R>() {
Some(it) => it,
None => return self,
};
@@ -104,8 +110,10 @@ impl<'a> RequestDispatcher<'a> {
let _pctx = stdx::panic_context::enter(panic_context);
f(world, params)
});
let response = thread_result_to_response::<R>(id, result);
Task::Response(response)
match thread_result_to_response::<R>(req.id.clone(), result) {
Ok(response) => Task::Response(response),
Err(_) => Task::Retry(req),
}
}
});
@@ -124,7 +132,7 @@ impl<'a> RequestDispatcher<'a> {
}
}
fn parse<R>(&mut self) -> Option<(lsp_server::RequestId, R::Params, String)>
fn parse<R>(&mut self) -> Option<(lsp_server::Request, R::Params, String)>
where
R: lsp_types::request::Request,
R::Params: DeserializeOwned + fmt::Debug,
@@ -134,12 +142,12 @@ impl<'a> RequestDispatcher<'a> {
_ => return None,
};
let res = crate::from_json(R::METHOD, req.params);
let res = crate::from_json(R::METHOD, &req.params);
match res {
Ok(params) => {
let panic_context =
format!("\nversion: {}\nrequest: {} {:#?}", env!("REV"), R::METHOD, params);
Some((req.id, params, panic_context))
Some((req, params, panic_context))
}
Err(err) => {
let response = lsp_server::Response::new_err(
@@ -157,7 +165,7 @@ impl<'a> RequestDispatcher<'a> {
fn thread_result_to_response<R>(
id: lsp_server::RequestId,
result: thread::Result<Result<R::Result>>,
) -> lsp_server::Response
) -> Result<lsp_server::Response, Cancelled>
where
R: lsp_types::request::Request,
R::Params: DeserializeOwned,
@@ -166,19 +174,22 @@ where
match result {
Ok(result) => result_to_response::<R>(id, result),
Err(panic) => {
let mut message = "request handler panicked".to_string();
let panic_message = panic
.downcast_ref::<String>()
.map(String::as_str)
.or_else(|| panic.downcast_ref::<&str>().copied());
let mut message = "request handler panicked".to_string();
if let Some(panic_message) = panic_message {
message.push_str(": ");
message.push_str(panic_message)
};
lsp_server::Response::new_err(id, lsp_server::ErrorCode::InternalError as i32, message)
Ok(lsp_server::Response::new_err(
id,
lsp_server::ErrorCode::InternalError as i32,
message,
))
}
}
}
@@ -186,33 +197,27 @@ where
fn result_to_response<R>(
id: lsp_server::RequestId,
result: Result<R::Result>,
) -> lsp_server::Response
) -> Result<lsp_server::Response, Cancelled>
where
R: lsp_types::request::Request,
R::Params: DeserializeOwned,
R::Result: Serialize,
{
match result {
let res = match result {
Ok(resp) => lsp_server::Response::new_ok(id, &resp),
Err(e) => match e.downcast::<LspError>() {
Ok(lsp_error) => lsp_server::Response::new_err(id, lsp_error.code, lsp_error.message),
Err(e) => {
if is_cancelled(&*e) {
lsp_server::Response::new_err(
id,
lsp_server::ErrorCode::ContentModified as i32,
"content modified".to_string(),
)
} else {
lsp_server::Response::new_err(
id,
lsp_server::ErrorCode::InternalError as i32,
e.to_string(),
)
}
}
Err(e) => match e.downcast::<Cancelled>() {
Ok(cancelled) => return Err(*cancelled),
Err(e) => lsp_server::Response::new_err(
id,
lsp_server::ErrorCode::InternalError as i32,
e.to_string(),
),
},
},
}
};
Ok(res)
}
pub(crate) struct NotificationDispatcher<'a> {