From 86a4d4cb9c526e095985cc26668c4ed653941fc2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Jun 2020 19:23:52 +0200 Subject: Simplify --- crates/rust-analyzer/src/dispatch.rs | 44 ++++++++++++++------------------ crates/rust-analyzer/src/global_state.rs | 14 +++++++--- crates/rust-analyzer/src/main_loop.rs | 42 ++++++++++-------------------- 3 files changed, 43 insertions(+), 57 deletions(-) diff --git a/crates/rust-analyzer/src/dispatch.rs b/crates/rust-analyzer/src/dispatch.rs index 5fdbed8ef..03b373dee 100644 --- a/crates/rust-analyzer/src/dispatch.rs +++ b/crates/rust-analyzer/src/dispatch.rs @@ -1,5 +1,5 @@ //! A visitor for downcasting arbitrary request (JSON) into a specific type. -use std::{panic, time::Instant}; +use std::panic; use serde::{de::DeserializeOwned, Serialize}; @@ -13,7 +13,6 @@ use crate::{ pub(crate) struct RequestDispatcher<'a> { pub(crate) req: Option, pub(crate) global_state: &'a mut GlobalState, - pub(crate) request_received: Instant, } impl<'a> RequestDispatcher<'a> { @@ -34,12 +33,12 @@ impl<'a> RequestDispatcher<'a> { } }; let world = panic::AssertUnwindSafe(&mut *self.global_state); - let task = panic::catch_unwind(move || { + let response = panic::catch_unwind(move || { let result = f(world.0, params); - result_to_task::(id, result) + result_to_response::(id, result) }) .map_err(|_| format!("sync task {:?} panicked", R::METHOD))?; - self.global_state.on_task(task); + self.global_state.respond(response); Ok(self) } @@ -64,7 +63,7 @@ impl<'a> RequestDispatcher<'a> { let world = self.global_state.snapshot(); move || { let result = f(world, params); - result_to_task::(id, result) + Task::Response(result_to_response::(id, result)) } }); @@ -72,17 +71,14 @@ impl<'a> RequestDispatcher<'a> { } pub(crate) fn finish(&mut self) { - match self.req.take() { - None => (), - Some(req) => { - log::error!("unknown request: {:?}", req); - let resp = lsp_server::Response::new_err( - req.id, - lsp_server::ErrorCode::MethodNotFound as i32, - "unknown request".to_string(), - ); - self.global_state.send(resp.into()); - } + if let Some(req) = self.req.take() { + log::error!("unknown request: {:?}", req); + let response = lsp_server::Response::new_err( + req.id, + lsp_server::ErrorCode::MethodNotFound as i32, + "unknown request".to_string(), + ); + self.global_state.respond(response) } } @@ -99,21 +95,20 @@ impl<'a> RequestDispatcher<'a> { return None; } }; - self.global_state - .req_queue - .incoming - .register(id.clone(), (R::METHOD, self.request_received)); Some((id, params)) } } -fn result_to_task(id: lsp_server::RequestId, result: Result) -> Task +fn result_to_response( + id: lsp_server::RequestId, + result: Result, +) -> lsp_server::Response where R: lsp_types::request::Request + 'static, R::Params: DeserializeOwned + 'static, R::Result: Serialize + 'static, { - let response = match result { + match result { Ok(resp) => lsp_server::Response::new_ok(id, &resp), Err(e) => match e.downcast::() { Ok(lsp_error) => lsp_server::Response::new_err(id, lsp_error.code, lsp_error.message), @@ -133,8 +128,7 @@ where } } }, - }; - Task::Respond(response) + } } pub(crate) struct NotificationDispatcher<'a> { diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 56d50c789..149b1b5f9 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -253,13 +253,19 @@ impl GlobalState { self.analysis_host.collect_garbage() } - pub(crate) fn complete_request(&mut self, request: RequestMetrics) { - self.latest_requests.write().record(request) - } - pub(crate) fn send(&mut self, message: lsp_server::Message) { self.sender.send(message).unwrap() } + pub(crate) fn respond(&mut self, response: lsp_server::Response) { + if let Some((method, start)) = self.req_queue.incoming.complete(response.id.clone()) { + let duration = start.elapsed(); + log::info!("handled req#{} in {:?}", response.id, duration); + let metrics = + RequestMetrics { id: response.id.clone(), method: method.to_string(), duration }; + self.latest_requests.write().record(metrics); + self.send(response.into()); + } + } pub(crate) fn show_message(&mut self, typ: lsp_types::MessageType, message: String) { show_message(typ, message, &self.sender) } diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 94b9c0ca2..76dea3e22 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -23,7 +23,6 @@ use crate::{ lsp_utils::{ apply_document_changes, is_canceled, notification_is, notification_new, show_message, }, - request_metrics::RequestMetrics, Result, }; @@ -147,7 +146,7 @@ impl fmt::Debug for Event { return debug_verbose_not(not, f); } } - Event::Task(Task::Respond(resp)) => { + Event::Task(Task::Response(resp)) => { return f .debug_struct("Response") .field("id", &resp.id) @@ -218,7 +217,13 @@ impl GlobalState { } }, Event::Task(task) => { - self.on_task(task); + match task { + Task::Response(response) => self.respond(response), + Task::Diagnostics(tasks) => { + tasks.into_iter().for_each(|task| on_diagnostic_task(task, self)) + } + Task::Unit => (), + } self.maybe_collect_garbage(); } Event::Vfs(task) => match task { @@ -331,7 +336,9 @@ impl GlobalState { } fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> { - RequestDispatcher { req: Some(req), global_state: self, request_received } + self.req_queue.incoming.register(req.id.clone(), (req.method.clone(), request_received)); + + RequestDispatcher { req: Some(req), global_state: self } .on_sync::(|s, ()| Ok(s.collect_garbage()))? .on_sync::(|s, p| handlers::handle_join_lines(s.snapshot(), p))? .on_sync::(|s, p| handlers::handle_on_enter(s.snapshot(), p))? @@ -492,27 +499,6 @@ impl GlobalState { .finish(); Ok(()) } - pub(crate) fn on_task(&mut self, task: Task) { - match task { - Task::Respond(response) => { - if let Some((method, start)) = self.req_queue.incoming.complete(response.id.clone()) - { - let duration = start.elapsed(); - log::info!("handled req#{} in {:?}", response.id, duration); - self.complete_request(RequestMetrics { - id: response.id.clone(), - method: method.to_string(), - duration, - }); - self.send(response.into()); - } - } - Task::Diagnostics(tasks) => { - tasks.into_iter().for_each(|task| on_diagnostic_task(task, self)) - } - Task::Unit => (), - } - } fn update_file_notifications_on_threadpool(&mut self, subscriptions: Vec) { log::trace!("updating notifications for {:?}", subscriptions); if self.config.publish_diagnostics { @@ -548,13 +534,13 @@ impl GlobalState { #[derive(Debug)] pub(crate) enum Task { - Respond(Response), - Diagnostics(Vec), + Response(Response), + Diagnostics(()), Unit, } pub(crate) type ReqHandler = fn(&mut GlobalState, Response); -pub(crate) type ReqQueue = lsp_server::ReqQueue<(&'static str, Instant), ReqHandler>; +pub(crate) type ReqQueue = lsp_server::ReqQueue<(String, Instant), ReqHandler>; const DO_NOTHING: ReqHandler = |_, _| (); fn on_diagnostic_task(task: DiagnosticTask, global_state: &mut GlobalState) { -- cgit v1.2.3