diff options
author | Aleksey Kladov <[email protected]> | 2020-06-25 06:56:47 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-06-25 06:56:47 +0100 |
commit | 76a530242a12f75e2a8456f952cef07e2d564f67 (patch) | |
tree | c172661c9be87bea10b796bffd32f4c32c65ab7a /crates/rust-analyzer | |
parent | 78e94e4570f09c8cbe1f8c6802df9b112ca37f08 (diff) | |
parent | 6e81c9a921b975be7f2efb927dab4f3cfd505ebc (diff) |
Merge branch 'Veetaha-feat/sync-branch'
Diffstat (limited to 'crates/rust-analyzer')
-rw-r--r-- | crates/rust-analyzer/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 23 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lsp_utils.rs | 52 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 36 | ||||
-rw-r--r-- | crates/rust-analyzer/tests/heavy_tests/support.rs | 4 |
5 files changed, 109 insertions, 7 deletions
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 68d04f3e3..2bbed395f 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -48,6 +48,7 @@ hir = { path = "../ra_hir", package = "ra_hir" } | |||
48 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | 48 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } |
49 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } | 49 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } |
50 | ra_proc_macro_srv = { path = "../ra_proc_macro_srv" } | 50 | ra_proc_macro_srv = { path = "../ra_proc_macro_srv" } |
51 | ra_progress = { path = "../ra_progress" } | ||
51 | 52 | ||
52 | [target.'cfg(windows)'.dependencies] | 53 | [target.'cfg(windows)'.dependencies] |
53 | winapi = "0.3.8" | 54 | winapi = "0.3.8" |
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 87f3fe4db..7759c0ae3 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -27,9 +27,13 @@ use crate::{ | |||
27 | }; | 27 | }; |
28 | use rustc_hash::{FxHashMap, FxHashSet}; | 28 | use rustc_hash::{FxHashMap, FxHashSet}; |
29 | 29 | ||
30 | fn create_flycheck(workspaces: &[ProjectWorkspace], config: &FlycheckConfig) -> Option<Flycheck> { | 30 | fn create_flycheck( |
31 | workspaces: &[ProjectWorkspace], | ||
32 | config: &FlycheckConfig, | ||
33 | progress_src: &ProgressSource<(), String>, | ||
34 | ) -> Option<Flycheck> { | ||
31 | // FIXME: Figure out the multi-workspace situation | 35 | // FIXME: Figure out the multi-workspace situation |
32 | workspaces.iter().find_map(|w| match w { | 36 | workspaces.iter().find_map(move |w| match w { |
33 | ProjectWorkspace::Cargo { cargo, .. } => { | 37 | ProjectWorkspace::Cargo { cargo, .. } => { |
34 | let cargo_project_root = cargo.workspace_root().to_path_buf(); | 38 | let cargo_project_root = cargo.workspace_root().to_path_buf(); |
35 | Some(Flycheck::new(config.clone(), cargo_project_root.into())) | 39 | Some(Flycheck::new(config.clone(), cargo_project_root.into())) |
@@ -143,7 +147,12 @@ impl GlobalState { | |||
143 | } | 147 | } |
144 | change.set_crate_graph(crate_graph); | 148 | change.set_crate_graph(crate_graph); |
145 | 149 | ||
146 | let flycheck = config.check.as_ref().and_then(|c| create_flycheck(&workspaces, c)); | 150 | let (flycheck_progress_receiver, flycheck_progress_src) = |
151 | ProgressSource::real_if(config.client_caps.work_done_progress); | ||
152 | let flycheck = config | ||
153 | .check | ||
154 | .as_ref() | ||
155 | .and_then(|c| create_flycheck(&workspaces, c, &flycheck_progress_src)); | ||
147 | 156 | ||
148 | let mut analysis_host = AnalysisHost::new(lru_capacity); | 157 | let mut analysis_host = AnalysisHost::new(lru_capacity); |
149 | analysis_host.apply_change(change); | 158 | analysis_host.apply_change(change); |
@@ -153,6 +162,8 @@ impl GlobalState { | |||
153 | loader, | 162 | loader, |
154 | task_receiver, | 163 | task_receiver, |
155 | flycheck, | 164 | flycheck, |
165 | flycheck_progress_src, | ||
166 | flycheck_progress_receiver, | ||
156 | diagnostics: Default::default(), | 167 | diagnostics: Default::default(), |
157 | mem_docs: FxHashSet::default(), | 168 | mem_docs: FxHashSet::default(), |
158 | vfs: Arc::new(RwLock::new((vfs, FxHashMap::default()))), | 169 | vfs: Arc::new(RwLock::new((vfs, FxHashMap::default()))), |
@@ -170,8 +181,10 @@ impl GlobalState { | |||
170 | pub(crate) fn update_configuration(&mut self, config: Config) { | 181 | pub(crate) fn update_configuration(&mut self, config: Config) { |
171 | self.analysis_host.update_lru_capacity(config.lru_capacity); | 182 | self.analysis_host.update_lru_capacity(config.lru_capacity); |
172 | if config.check != self.config.check { | 183 | if config.check != self.config.check { |
173 | self.flycheck = | 184 | self.flycheck = config |
174 | config.check.as_ref().and_then(|it| create_flycheck(&self.workspaces, it)); | 185 | .check |
186 | .as_ref() | ||
187 | .and_then(|it| create_flycheck(&self.workspaces, it, &self.flycheck_progress_src)); | ||
175 | } | 188 | } |
176 | 189 | ||
177 | self.config = config; | 190 | self.config = config; |
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs new file mode 100644 index 000000000..c79022797 --- /dev/null +++ b/crates/rust-analyzer/src/lsp_utils.rs | |||
@@ -0,0 +1,52 @@ | |||
1 | //! Utilities for LSP-related boilerplate code. | ||
2 | |||
3 | use crossbeam_channel::Sender; | ||
4 | use lsp_server::{Message, Notification, Request, RequestId}; | ||
5 | use ra_db::Canceled; | ||
6 | use serde::{de::DeserializeOwned, Serialize}; | ||
7 | use std::error::Error; | ||
8 | |||
9 | pub fn show_message( | ||
10 | typ: lsp_types::MessageType, | ||
11 | message: impl Into<String>, | ||
12 | sender: &Sender<Message>, | ||
13 | ) { | ||
14 | let message = message.into(); | ||
15 | let params = lsp_types::ShowMessageParams { typ, message }; | ||
16 | let not = notification_new::<lsp_types::notification::ShowMessage>(params); | ||
17 | sender.send(not.into()).unwrap(); | ||
18 | } | ||
19 | |||
20 | pub(crate) fn is_canceled(e: &(dyn Error + 'static)) -> bool { | ||
21 | e.downcast_ref::<Canceled>().is_some() | ||
22 | } | ||
23 | |||
24 | pub(crate) fn notification_is<N: lsp_types::notification::Notification>( | ||
25 | notification: &Notification, | ||
26 | ) -> bool { | ||
27 | notification.method == N::METHOD | ||
28 | } | ||
29 | |||
30 | pub(crate) fn notification_cast<N>(notification: Notification) -> Result<N::Params, Notification> | ||
31 | where | ||
32 | N: lsp_types::notification::Notification, | ||
33 | N::Params: DeserializeOwned, | ||
34 | { | ||
35 | notification.extract(N::METHOD) | ||
36 | } | ||
37 | |||
38 | pub(crate) fn notification_new<N>(params: N::Params) -> Notification | ||
39 | where | ||
40 | N: lsp_types::notification::Notification, | ||
41 | N::Params: Serialize, | ||
42 | { | ||
43 | Notification::new(N::METHOD.to_string(), params) | ||
44 | } | ||
45 | |||
46 | pub(crate) fn request_new<R>(id: RequestId, params: R::Params) -> Request | ||
47 | where | ||
48 | R: lsp_types::request::Request, | ||
49 | R::Params: Serialize, | ||
50 | { | ||
51 | Request::new(id, R::METHOD.to_string(), params) | ||
52 | } | ||
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index eb9e7f913..7ccdbd29c 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -28,6 +28,14 @@ use crate::{ | |||
28 | request_metrics::RequestMetrics, | 28 | request_metrics::RequestMetrics, |
29 | LspError, Result, | 29 | LspError, Result, |
30 | }; | 30 | }; |
31 | pub use lsp_utils::show_message; | ||
32 | use lsp_utils::{is_canceled, notification_cast, notification_is, notification_new, request_new}; | ||
33 | use ra_progress::{ | ||
34 | IsDone, ProgressStatus, U32Progress, U32ProgressReport, U32ProgressSource, U32ProgressStatus, | ||
35 | }; | ||
36 | |||
37 | const FLYCHECK_PROGRESS_TOKEN: &str = "rustAnalyzer/flycheck"; | ||
38 | const ROOTS_SCANNED_PROGRESS_TOKEN: &str = "rustAnalyzer/rootsScanned"; | ||
31 | 39 | ||
32 | pub fn main_loop(config: Config, connection: Connection) -> Result<()> { | 40 | pub fn main_loop(config: Config, connection: Connection) -> Result<()> { |
33 | log::info!("initial config: {:#?}", config); | 41 | log::info!("initial config: {:#?}", config); |
@@ -138,6 +146,18 @@ pub fn main_loop(config: Config, connection: Connection) -> Result<()> { | |||
138 | recv(global_state.flycheck.as_ref().map_or(&never(), |it| &it.task_recv)) -> task => match task { | 146 | recv(global_state.flycheck.as_ref().map_or(&never(), |it| &it.task_recv)) -> task => match task { |
139 | Ok(task) => Event::CheckWatcher(task), | 147 | Ok(task) => Event::CheckWatcher(task), |
140 | Err(RecvError) => return Err("check watcher died".into()), | 148 | Err(RecvError) => return Err("check watcher died".into()), |
149 | }, | ||
150 | recv(global_state.flycheck_progress_receiver) -> status => match status { | ||
151 | Ok(status) => Event::ProgressReport(ProgressReport::Flycheck(status)), | ||
152 | Err(RecvError) => return Err("check watcher died".into()), | ||
153 | }, | ||
154 | recv(roots_scanned_progress_receiver) -> status => match status { | ||
155 | Ok(status) => Event::ProgressReport(ProgressReport::RootsScanned(status)), | ||
156 | Err(RecvError) => { | ||
157 | // Roots analysis has finished, we no longer need this receiver | ||
158 | roots_scanned_progress_receiver = never(); | ||
159 | continue; | ||
160 | } | ||
141 | } | 161 | } |
142 | }; | 162 | }; |
143 | if let Event::Msg(Message::Request(req)) = &event { | 163 | if let Event::Msg(Message::Request(req)) = &event { |
@@ -169,6 +189,7 @@ pub fn main_loop(config: Config, connection: Connection) -> Result<()> { | |||
169 | enum Task { | 189 | enum Task { |
170 | Respond(Response), | 190 | Respond(Response), |
171 | Notify(Notification), | 191 | Notify(Notification), |
192 | SendRequest(Request), | ||
172 | Diagnostic(DiagnosticTask), | 193 | Diagnostic(DiagnosticTask), |
173 | } | 194 | } |
174 | 195 | ||
@@ -177,6 +198,13 @@ enum Event { | |||
177 | Task(Task), | 198 | Task(Task), |
178 | Vfs(vfs::loader::Message), | 199 | Vfs(vfs::loader::Message), |
179 | CheckWatcher(CheckTask), | 200 | CheckWatcher(CheckTask), |
201 | ProgressReport(ProgressReport), | ||
202 | } | ||
203 | |||
204 | #[derive(Debug)] | ||
205 | enum ProgressReport { | ||
206 | Flycheck(ProgressStatus<(), String>), | ||
207 | RootsScanned(U32ProgressStatus), | ||
180 | } | 208 | } |
181 | 209 | ||
182 | impl fmt::Debug for Event { | 210 | impl fmt::Debug for Event { |
@@ -212,6 +240,7 @@ impl fmt::Debug for Event { | |||
212 | Event::Task(it) => fmt::Debug::fmt(it, f), | 240 | Event::Task(it) => fmt::Debug::fmt(it, f), |
213 | Event::Vfs(it) => fmt::Debug::fmt(it, f), | 241 | Event::Vfs(it) => fmt::Debug::fmt(it, f), |
214 | Event::CheckWatcher(it) => fmt::Debug::fmt(it, f), | 242 | Event::CheckWatcher(it) => fmt::Debug::fmt(it, f), |
243 | Event::ProgressReport(it) => fmt::Debug::fmt(it, f), | ||
215 | } | 244 | } |
216 | } | 245 | } |
217 | } | 246 | } |
@@ -262,6 +291,9 @@ fn loop_turn( | |||
262 | } | 291 | } |
263 | }, | 292 | }, |
264 | Event::CheckWatcher(task) => on_check_task(task, global_state, task_sender)?, | 293 | Event::CheckWatcher(task) => on_check_task(task, global_state, task_sender)?, |
294 | Event::ProgressReport(report) => { | ||
295 | on_progress_report(report, task_sender, loop_state, global_state) | ||
296 | } | ||
265 | Event::Msg(msg) => match msg { | 297 | Event::Msg(msg) => match msg { |
266 | Message::Request(req) => { | 298 | Message::Request(req) => { |
267 | on_request(global_state, pool, task_sender, &connection.sender, loop_start, req)? | 299 | on_request(global_state, pool, task_sender, &connection.sender, loop_start, req)? |
@@ -826,7 +858,7 @@ where | |||
826 | Err(e) => match e.downcast::<LspError>() { | 858 | Err(e) => match e.downcast::<LspError>() { |
827 | Ok(lsp_error) => Response::new_err(id, lsp_error.code, lsp_error.message), | 859 | Ok(lsp_error) => Response::new_err(id, lsp_error.code, lsp_error.message), |
828 | Err(e) => { | 860 | Err(e) => { |
829 | if is_canceled(&e) { | 861 | if is_canceled(&*e) { |
830 | Response::new_err( | 862 | Response::new_err( |
831 | id, | 863 | id, |
832 | ErrorCode::ContentModified as i32, | 864 | ErrorCode::ContentModified as i32, |
@@ -853,7 +885,7 @@ fn update_file_notifications_on_threadpool( | |||
853 | for file_id in subscriptions { | 885 | for file_id in subscriptions { |
854 | match handlers::publish_diagnostics(&world, file_id) { | 886 | match handlers::publish_diagnostics(&world, file_id) { |
855 | Err(e) => { | 887 | Err(e) => { |
856 | if !is_canceled(&e) { | 888 | if !is_canceled(&*e) { |
857 | log::error!("failed to compute diagnostics: {:?}", e); | 889 | log::error!("failed to compute diagnostics: {:?}", e); |
858 | } | 890 | } |
859 | } | 891 | } |
diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs index 49f194f7e..15d2a05a4 100644 --- a/crates/rust-analyzer/tests/heavy_tests/support.rs +++ b/crates/rust-analyzer/tests/heavy_tests/support.rs | |||
@@ -202,7 +202,11 @@ impl Server { | |||
202 | ProgressParams { | 202 | ProgressParams { |
203 | token: lsp_types::ProgressToken::String(ref token), | 203 | token: lsp_types::ProgressToken::String(ref token), |
204 | value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(_)), | 204 | value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(_)), |
205 | <<<<<<< HEAD | ||
205 | } if token == "rustAnalyzer/roots scanned" => true, | 206 | } if token == "rustAnalyzer/roots scanned" => true, |
207 | ======= | ||
208 | } if token == "rustAnalyzer/rootsScanned" => true, | ||
209 | >>>>>>> Veetaha-feat/sync-branch | ||
206 | _ => false, | 210 | _ => false, |
207 | } | 211 | } |
208 | } | 212 | } |