diff options
author | Aleksey Kladov <[email protected]> | 2020-06-25 07:39:33 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-06-25 07:39:33 +0100 |
commit | dab8808e82b26a45cff00d1f49863562cf4f5ce8 (patch) | |
tree | 4c69a79e2c77eff60289f9884a68d73aad7f66cf /crates | |
parent | 69e6924dd596cab20333c81b4557008b7a67bad0 (diff) |
Abstract over channel
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_flycheck/src/lib.rs | 56 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 11 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 6 |
3 files changed, 43 insertions, 30 deletions
diff --git a/crates/ra_flycheck/src/lib.rs b/crates/ra_flycheck/src/lib.rs index 6751e5c38..063603b45 100644 --- a/crates/ra_flycheck/src/lib.rs +++ b/crates/ra_flycheck/src/lib.rs | |||
@@ -52,17 +52,19 @@ pub struct FlycheckHandle { | |||
52 | // XXX: drop order is significant | 52 | // XXX: drop order is significant |
53 | cmd_send: Sender<CheckCommand>, | 53 | cmd_send: Sender<CheckCommand>, |
54 | handle: jod_thread::JoinHandle<()>, | 54 | handle: jod_thread::JoinHandle<()>, |
55 | pub task_recv: Receiver<CheckTask>, | ||
56 | } | 55 | } |
57 | 56 | ||
58 | impl FlycheckHandle { | 57 | impl FlycheckHandle { |
59 | pub fn spawn(config: FlycheckConfig, workspace_root: PathBuf) -> FlycheckHandle { | 58 | pub fn spawn( |
60 | let (task_send, task_recv) = unbounded::<CheckTask>(); | 59 | config: FlycheckConfig, |
60 | workspace_root: PathBuf, | ||
61 | sender: Box<dyn Fn(CheckTask) + Send>, | ||
62 | ) -> FlycheckHandle { | ||
61 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); | 63 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); |
62 | let handle = jod_thread::spawn(move || { | 64 | let handle = jod_thread::spawn(move || { |
63 | FlycheckActor::new(config, workspace_root).run(&task_send, &cmd_recv); | 65 | FlycheckActor::new(config, workspace_root, sender).run(&cmd_recv); |
64 | }); | 66 | }); |
65 | FlycheckHandle { task_recv, cmd_send, handle } | 67 | FlycheckHandle { cmd_send, handle } |
66 | } | 68 | } |
67 | 69 | ||
68 | /// Schedule a re-start of the cargo check worker. | 70 | /// Schedule a re-start of the cargo check worker. |
@@ -96,6 +98,7 @@ pub enum CheckCommand { | |||
96 | } | 98 | } |
97 | 99 | ||
98 | struct FlycheckActor { | 100 | struct FlycheckActor { |
101 | sender: Box<dyn Fn(CheckTask) + Send>, | ||
99 | config: FlycheckConfig, | 102 | config: FlycheckConfig, |
100 | workspace_root: PathBuf, | 103 | workspace_root: PathBuf, |
101 | last_update_req: Option<Instant>, | 104 | last_update_req: Option<Instant>, |
@@ -110,8 +113,13 @@ struct FlycheckActor { | |||
110 | } | 113 | } |
111 | 114 | ||
112 | impl FlycheckActor { | 115 | impl FlycheckActor { |
113 | fn new(config: FlycheckConfig, workspace_root: PathBuf) -> FlycheckActor { | 116 | fn new( |
117 | config: FlycheckConfig, | ||
118 | workspace_root: PathBuf, | ||
119 | sender: Box<dyn Fn(CheckTask) + Send>, | ||
120 | ) -> FlycheckActor { | ||
114 | FlycheckActor { | 121 | FlycheckActor { |
122 | sender, | ||
115 | config, | 123 | config, |
116 | workspace_root, | 124 | workspace_root, |
117 | last_update_req: None, | 125 | last_update_req: None, |
@@ -120,9 +128,9 @@ impl FlycheckActor { | |||
120 | } | 128 | } |
121 | } | 129 | } |
122 | 130 | ||
123 | fn run(&mut self, task_send: &Sender<CheckTask>, cmd_recv: &Receiver<CheckCommand>) { | 131 | fn run(&mut self, cmd_recv: &Receiver<CheckCommand>) { |
124 | // If we rerun the thread, we need to discard the previous check results first | 132 | // If we rerun the thread, we need to discard the previous check results first |
125 | self.clean_previous_results(task_send); | 133 | self.clean_previous_results(); |
126 | 134 | ||
127 | loop { | 135 | loop { |
128 | select! { | 136 | select! { |
@@ -134,7 +142,7 @@ impl FlycheckActor { | |||
134 | }, | 142 | }, |
135 | }, | 143 | }, |
136 | recv(self.message_recv) -> msg => match msg { | 144 | recv(self.message_recv) -> msg => match msg { |
137 | Ok(msg) => self.handle_message(msg, task_send), | 145 | Ok(msg) => self.handle_message(msg), |
138 | Err(RecvError) => { | 146 | Err(RecvError) => { |
139 | // Watcher finished, replace it with a never channel to | 147 | // Watcher finished, replace it with a never channel to |
140 | // avoid busy-waiting. | 148 | // avoid busy-waiting. |
@@ -146,15 +154,15 @@ impl FlycheckActor { | |||
146 | 154 | ||
147 | if self.should_recheck() { | 155 | if self.should_recheck() { |
148 | self.last_update_req = None; | 156 | self.last_update_req = None; |
149 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); | 157 | self.send(CheckTask::ClearDiagnostics); |
150 | self.restart_check_process(); | 158 | self.restart_check_process(); |
151 | } | 159 | } |
152 | } | 160 | } |
153 | } | 161 | } |
154 | 162 | ||
155 | fn clean_previous_results(&self, task_send: &Sender<CheckTask>) { | 163 | fn clean_previous_results(&self) { |
156 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); | 164 | self.send(CheckTask::ClearDiagnostics); |
157 | task_send.send(CheckTask::Status(Status::End)).unwrap(); | 165 | self.send(CheckTask::Status(Status::End)); |
158 | } | 166 | } |
159 | 167 | ||
160 | fn should_recheck(&mut self) -> bool { | 168 | fn should_recheck(&mut self) -> bool { |
@@ -173,27 +181,25 @@ impl FlycheckActor { | |||
173 | } | 181 | } |
174 | } | 182 | } |
175 | 183 | ||
176 | fn handle_message(&self, msg: CheckEvent, task_send: &Sender<CheckTask>) { | 184 | fn handle_message(&self, msg: CheckEvent) { |
177 | match msg { | 185 | match msg { |
178 | CheckEvent::Begin => { | 186 | CheckEvent::Begin => { |
179 | task_send.send(CheckTask::Status(Status::Being)).unwrap(); | 187 | self.send(CheckTask::Status(Status::Being)); |
180 | } | 188 | } |
181 | 189 | ||
182 | CheckEvent::End => { | 190 | CheckEvent::End => { |
183 | task_send.send(CheckTask::Status(Status::End)).unwrap(); | 191 | self.send(CheckTask::Status(Status::End)); |
184 | } | 192 | } |
185 | 193 | ||
186 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { | 194 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { |
187 | task_send.send(CheckTask::Status(Status::Progress(msg.target.name))).unwrap(); | 195 | self.send(CheckTask::Status(Status::Progress(msg.target.name))); |
188 | } | 196 | } |
189 | 197 | ||
190 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { | 198 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { |
191 | task_send | 199 | self.send(CheckTask::AddDiagnostic { |
192 | .send(CheckTask::AddDiagnostic { | 200 | workspace_root: self.workspace_root.clone(), |
193 | workspace_root: self.workspace_root.clone(), | 201 | diagnostic: msg.message, |
194 | diagnostic: msg.message, | 202 | }); |
195 | }) | ||
196 | .unwrap(); | ||
197 | } | 203 | } |
198 | 204 | ||
199 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} | 205 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} |
@@ -271,6 +277,10 @@ impl FlycheckActor { | |||
271 | let _ = message_send.send(CheckEvent::End); | 277 | let _ = message_send.send(CheckEvent::End); |
272 | })) | 278 | })) |
273 | } | 279 | } |
280 | |||
281 | fn send(&self, check_task: CheckTask) { | ||
282 | (self.sender)(check_task) | ||
283 | } | ||
274 | } | 284 | } |
275 | 285 | ||
276 | enum CheckEvent { | 286 | enum CheckEvent { |
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 2a7111a88..42edadd70 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -9,7 +9,7 @@ use crossbeam_channel::{unbounded, Receiver}; | |||
9 | use lsp_types::Url; | 9 | use lsp_types::Url; |
10 | use parking_lot::RwLock; | 10 | use parking_lot::RwLock; |
11 | use ra_db::{CrateId, SourceRoot, VfsPath}; | 11 | use ra_db::{CrateId, SourceRoot, VfsPath}; |
12 | use ra_flycheck::{FlycheckConfig, FlycheckHandle}; | 12 | use ra_flycheck::{CheckTask, FlycheckConfig, FlycheckHandle}; |
13 | use ra_ide::{Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId}; | 13 | use ra_ide::{Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId}; |
14 | use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; | 14 | use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; |
15 | use stdx::format_to; | 15 | use stdx::format_to; |
@@ -30,12 +30,15 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
30 | fn create_flycheck( | 30 | fn create_flycheck( |
31 | workspaces: &[ProjectWorkspace], | 31 | workspaces: &[ProjectWorkspace], |
32 | config: &FlycheckConfig, | 32 | config: &FlycheckConfig, |
33 | ) -> Option<FlycheckHandle> { | 33 | ) -> Option<(FlycheckHandle, Receiver<CheckTask>)> { |
34 | // FIXME: Figure out the multi-workspace situation | 34 | // FIXME: Figure out the multi-workspace situation |
35 | workspaces.iter().find_map(move |w| match w { | 35 | workspaces.iter().find_map(move |w| match w { |
36 | ProjectWorkspace::Cargo { cargo, .. } => { | 36 | ProjectWorkspace::Cargo { cargo, .. } => { |
37 | let (sender, receiver) = unbounded(); | ||
38 | let sender = Box::new(move |msg| sender.send(msg).unwrap()); | ||
37 | let cargo_project_root = cargo.workspace_root().to_path_buf(); | 39 | let cargo_project_root = cargo.workspace_root().to_path_buf(); |
38 | Some(FlycheckHandle::spawn(config.clone(), cargo_project_root.into())) | 40 | let flycheck = FlycheckHandle::spawn(config.clone(), cargo_project_root.into(), sender); |
41 | Some((flycheck, receiver)) | ||
39 | } | 42 | } |
40 | ProjectWorkspace::Json { .. } => { | 43 | ProjectWorkspace::Json { .. } => { |
41 | log::warn!("Cargo check watching only supported for cargo workspaces, disabling"); | 44 | log::warn!("Cargo check watching only supported for cargo workspaces, disabling"); |
@@ -66,7 +69,7 @@ pub(crate) struct GlobalState { | |||
66 | pub(crate) analysis_host: AnalysisHost, | 69 | pub(crate) analysis_host: AnalysisHost, |
67 | pub(crate) loader: Box<dyn vfs::loader::Handle>, | 70 | pub(crate) loader: Box<dyn vfs::loader::Handle>, |
68 | pub(crate) task_receiver: Receiver<vfs::loader::Message>, | 71 | pub(crate) task_receiver: Receiver<vfs::loader::Message>, |
69 | pub(crate) flycheck: Option<FlycheckHandle>, | 72 | pub(crate) flycheck: Option<(FlycheckHandle, Receiver<CheckTask>)>, |
70 | pub(crate) diagnostics: DiagnosticCollection, | 73 | pub(crate) diagnostics: DiagnosticCollection, |
71 | pub(crate) mem_docs: FxHashSet<VfsPath>, | 74 | pub(crate) mem_docs: FxHashSet<VfsPath>, |
72 | pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, | 75 | pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, |
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 03569086a..e5f82de5e 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -136,7 +136,7 @@ pub fn main_loop(config: Config, connection: Connection) -> Result<()> { | |||
136 | Ok(task) => Event::Vfs(task), | 136 | Ok(task) => Event::Vfs(task), |
137 | Err(RecvError) => return Err("vfs died".into()), | 137 | Err(RecvError) => return Err("vfs died".into()), |
138 | }, | 138 | }, |
139 | recv(global_state.flycheck.as_ref().map_or(&never(), |it| &it.task_recv)) -> task => match task { | 139 | recv(global_state.flycheck.as_ref().map_or(&never(), |it| &it.1)) -> task => match task { |
140 | Ok(task) => Event::CheckWatcher(task), | 140 | Ok(task) => Event::CheckWatcher(task), |
141 | Err(RecvError) => return Err("check watcher died".into()), | 141 | Err(RecvError) => return Err("check watcher died".into()), |
142 | }, | 142 | }, |
@@ -290,7 +290,7 @@ fn loop_turn( | |||
290 | 290 | ||
291 | if became_ready { | 291 | if became_ready { |
292 | if let Some(flycheck) = &global_state.flycheck { | 292 | if let Some(flycheck) = &global_state.flycheck { |
293 | flycheck.update(); | 293 | flycheck.0.update(); |
294 | } | 294 | } |
295 | } | 295 | } |
296 | 296 | ||
@@ -486,7 +486,7 @@ fn on_notification( | |||
486 | let not = match notification_cast::<lsp_types::notification::DidSaveTextDocument>(not) { | 486 | let not = match notification_cast::<lsp_types::notification::DidSaveTextDocument>(not) { |
487 | Ok(_params) => { | 487 | Ok(_params) => { |
488 | if let Some(flycheck) = &global_state.flycheck { | 488 | if let Some(flycheck) = &global_state.flycheck { |
489 | flycheck.update(); | 489 | flycheck.0.update(); |
490 | } | 490 | } |
491 | return Ok(()); | 491 | return Ok(()); |
492 | } | 492 | } |