fix: Fix completions disappearing when typing two keys in quick succession
This commit is contained in:
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user