aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-06-25 07:39:33 +0100
committerAleksey Kladov <[email protected]>2020-06-25 07:39:33 +0100
commitdab8808e82b26a45cff00d1f49863562cf4f5ce8 (patch)
tree4c69a79e2c77eff60289f9884a68d73aad7f66cf
parent69e6924dd596cab20333c81b4557008b7a67bad0 (diff)
Abstract over channel
-rw-r--r--crates/ra_flycheck/src/lib.rs56
-rw-r--r--crates/rust-analyzer/src/global_state.rs11
-rw-r--r--crates/rust-analyzer/src/main_loop.rs6
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
58impl FlycheckHandle { 57impl 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
98struct FlycheckActor { 100struct 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
112impl FlycheckActor { 115impl 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
276enum CheckEvent { 286enum 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};
9use lsp_types::Url; 9use lsp_types::Url;
10use parking_lot::RwLock; 10use parking_lot::RwLock;
11use ra_db::{CrateId, SourceRoot, VfsPath}; 11use ra_db::{CrateId, SourceRoot, VfsPath};
12use ra_flycheck::{FlycheckConfig, FlycheckHandle}; 12use ra_flycheck::{CheckTask, FlycheckConfig, FlycheckHandle};
13use ra_ide::{Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId}; 13use ra_ide::{Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId};
14use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; 14use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target};
15use stdx::format_to; 15use stdx::format_to;
@@ -30,12 +30,15 @@ use rustc_hash::{FxHashMap, FxHashSet};
30fn create_flycheck( 30fn 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 }