diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/flycheck/src/lib.rs | 76 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 6 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 35 |
3 files changed, 54 insertions, 63 deletions
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs index af75adbe2..3e73cf6ff 100644 --- a/crates/flycheck/src/lib.rs +++ b/crates/flycheck/src/lib.rs | |||
@@ -10,7 +10,6 @@ use std::{ | |||
10 | time::Instant, | 10 | time::Instant, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | use cargo_metadata::Message; | ||
14 | use crossbeam_channel::{never, select, unbounded, Receiver, RecvError, Sender}; | 13 | use crossbeam_channel::{never, select, unbounded, Receiver, RecvError, Sender}; |
15 | 14 | ||
16 | pub use cargo_metadata::diagnostic::{ | 15 | pub use cargo_metadata::diagnostic::{ |
@@ -50,17 +49,17 @@ impl fmt::Display for FlycheckConfig { | |||
50 | #[derive(Debug)] | 49 | #[derive(Debug)] |
51 | pub struct FlycheckHandle { | 50 | pub struct FlycheckHandle { |
52 | // XXX: drop order is significant | 51 | // XXX: drop order is significant |
53 | cmd_send: Sender<CheckCommand>, | 52 | cmd_send: Sender<Restart>, |
54 | handle: jod_thread::JoinHandle<()>, | 53 | handle: jod_thread::JoinHandle, |
55 | } | 54 | } |
56 | 55 | ||
57 | impl FlycheckHandle { | 56 | impl FlycheckHandle { |
58 | pub fn spawn( | 57 | pub fn spawn( |
59 | sender: Box<dyn Fn(CheckTask) + Send>, | 58 | sender: Box<dyn Fn(Message) + Send>, |
60 | config: FlycheckConfig, | 59 | config: FlycheckConfig, |
61 | workspace_root: PathBuf, | 60 | workspace_root: PathBuf, |
62 | ) -> FlycheckHandle { | 61 | ) -> FlycheckHandle { |
63 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); | 62 | let (cmd_send, cmd_recv) = unbounded::<Restart>(); |
64 | let handle = jod_thread::spawn(move || { | 63 | let handle = jod_thread::spawn(move || { |
65 | FlycheckActor::new(sender, config, workspace_root).run(&cmd_recv); | 64 | FlycheckActor::new(sender, config, workspace_root).run(&cmd_recv); |
66 | }); | 65 | }); |
@@ -69,12 +68,12 @@ impl FlycheckHandle { | |||
69 | 68 | ||
70 | /// Schedule a re-start of the cargo check worker. | 69 | /// Schedule a re-start of the cargo check worker. |
71 | pub fn update(&self) { | 70 | pub fn update(&self) { |
72 | self.cmd_send.send(CheckCommand::Update).unwrap(); | 71 | self.cmd_send.send(Restart).unwrap(); |
73 | } | 72 | } |
74 | } | 73 | } |
75 | 74 | ||
76 | #[derive(Debug)] | 75 | #[derive(Debug)] |
77 | pub enum CheckTask { | 76 | pub enum Message { |
78 | /// Request a clearing of all cached diagnostics from the check watcher | 77 | /// Request a clearing of all cached diagnostics from the check watcher |
79 | ClearDiagnostics, | 78 | ClearDiagnostics, |
80 | 79 | ||
@@ -82,23 +81,20 @@ pub enum CheckTask { | |||
82 | AddDiagnostic { workspace_root: PathBuf, diagnostic: Diagnostic }, | 81 | AddDiagnostic { workspace_root: PathBuf, diagnostic: Diagnostic }, |
83 | 82 | ||
84 | /// Request check progress notification to client | 83 | /// Request check progress notification to client |
85 | Status(Status), | 84 | Progress(Progress), |
86 | } | 85 | } |
87 | 86 | ||
88 | #[derive(Debug)] | 87 | #[derive(Debug)] |
89 | pub enum Status { | 88 | pub enum Progress { |
90 | Being, | 89 | Being, |
91 | Progress(String), | 90 | DidCheckCrate(String), |
92 | End, | 91 | End, |
93 | } | 92 | } |
94 | 93 | ||
95 | pub enum CheckCommand { | 94 | struct Restart; |
96 | /// Request re-start of check thread | ||
97 | Update, | ||
98 | } | ||
99 | 95 | ||
100 | struct FlycheckActor { | 96 | struct FlycheckActor { |
101 | sender: Box<dyn Fn(CheckTask) + Send>, | 97 | sender: Box<dyn Fn(Message) + Send>, |
102 | config: FlycheckConfig, | 98 | config: FlycheckConfig, |
103 | workspace_root: PathBuf, | 99 | workspace_root: PathBuf, |
104 | last_update_req: Option<Instant>, | 100 | last_update_req: Option<Instant>, |
@@ -109,12 +105,12 @@ struct FlycheckActor { | |||
109 | /// doesn't provide a way to read sub-process output without blocking, so we | 105 | /// doesn't provide a way to read sub-process output without blocking, so we |
110 | /// have to wrap sub-processes output handling in a thread and pass messages | 106 | /// have to wrap sub-processes output handling in a thread and pass messages |
111 | /// back over a channel. | 107 | /// back over a channel. |
112 | check_process: Option<jod_thread::JoinHandle<()>>, | 108 | check_process: Option<jod_thread::JoinHandle>, |
113 | } | 109 | } |
114 | 110 | ||
115 | impl FlycheckActor { | 111 | impl FlycheckActor { |
116 | fn new( | 112 | fn new( |
117 | sender: Box<dyn Fn(CheckTask) + Send>, | 113 | sender: Box<dyn Fn(Message) + Send>, |
118 | config: FlycheckConfig, | 114 | config: FlycheckConfig, |
119 | workspace_root: PathBuf, | 115 | workspace_root: PathBuf, |
120 | ) -> FlycheckActor { | 116 | ) -> FlycheckActor { |
@@ -128,14 +124,14 @@ impl FlycheckActor { | |||
128 | } | 124 | } |
129 | } | 125 | } |
130 | 126 | ||
131 | fn run(&mut self, cmd_recv: &Receiver<CheckCommand>) { | 127 | fn run(&mut self, cmd_recv: &Receiver<Restart>) { |
132 | // If we rerun the thread, we need to discard the previous check results first | 128 | // If we rerun the thread, we need to discard the previous check results first |
133 | self.clean_previous_results(); | 129 | self.clean_previous_results(); |
134 | 130 | ||
135 | loop { | 131 | loop { |
136 | select! { | 132 | select! { |
137 | recv(&cmd_recv) -> cmd => match cmd { | 133 | recv(&cmd_recv) -> cmd => match cmd { |
138 | Ok(cmd) => self.handle_command(cmd), | 134 | Ok(Restart) => self.last_update_req = Some(Instant::now()), |
139 | Err(RecvError) => { | 135 | Err(RecvError) => { |
140 | // Command channel has closed, so shut down | 136 | // Command channel has closed, so shut down |
141 | break; | 137 | break; |
@@ -154,15 +150,15 @@ impl FlycheckActor { | |||
154 | 150 | ||
155 | if self.should_recheck() { | 151 | if self.should_recheck() { |
156 | self.last_update_req = None; | 152 | self.last_update_req = None; |
157 | self.send(CheckTask::ClearDiagnostics); | 153 | self.send(Message::ClearDiagnostics); |
158 | self.restart_check_process(); | 154 | self.restart_check_process(); |
159 | } | 155 | } |
160 | } | 156 | } |
161 | } | 157 | } |
162 | 158 | ||
163 | fn clean_previous_results(&self) { | 159 | fn clean_previous_results(&self) { |
164 | self.send(CheckTask::ClearDiagnostics); | 160 | self.send(Message::ClearDiagnostics); |
165 | self.send(CheckTask::Status(Status::End)); | 161 | self.send(Message::Progress(Progress::End)); |
166 | } | 162 | } |
167 | 163 | ||
168 | fn should_recheck(&mut self) -> bool { | 164 | fn should_recheck(&mut self) -> bool { |
@@ -175,37 +171,31 @@ impl FlycheckActor { | |||
175 | false | 171 | false |
176 | } | 172 | } |
177 | 173 | ||
178 | fn handle_command(&mut self, cmd: CheckCommand) { | ||
179 | match cmd { | ||
180 | CheckCommand::Update => self.last_update_req = Some(Instant::now()), | ||
181 | } | ||
182 | } | ||
183 | |||
184 | fn handle_message(&self, msg: CheckEvent) { | 174 | fn handle_message(&self, msg: CheckEvent) { |
185 | match msg { | 175 | match msg { |
186 | CheckEvent::Begin => { | 176 | CheckEvent::Begin => { |
187 | self.send(CheckTask::Status(Status::Being)); | 177 | self.send(Message::Progress(Progress::Being)); |
188 | } | 178 | } |
189 | 179 | ||
190 | CheckEvent::End => { | 180 | CheckEvent::End => { |
191 | self.send(CheckTask::Status(Status::End)); | 181 | self.send(Message::Progress(Progress::End)); |
192 | } | 182 | } |
193 | 183 | ||
194 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { | 184 | CheckEvent::Msg(cargo_metadata::Message::CompilerArtifact(msg)) => { |
195 | self.send(CheckTask::Status(Status::Progress(msg.target.name))); | 185 | self.send(Message::Progress(Progress::DidCheckCrate(msg.target.name))); |
196 | } | 186 | } |
197 | 187 | ||
198 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { | 188 | CheckEvent::Msg(cargo_metadata::Message::CompilerMessage(msg)) => { |
199 | self.send(CheckTask::AddDiagnostic { | 189 | self.send(Message::AddDiagnostic { |
200 | workspace_root: self.workspace_root.clone(), | 190 | workspace_root: self.workspace_root.clone(), |
201 | diagnostic: msg.message, | 191 | diagnostic: msg.message, |
202 | }); | 192 | }); |
203 | } | 193 | } |
204 | 194 | ||
205 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} | 195 | CheckEvent::Msg(cargo_metadata::Message::BuildScriptExecuted(_)) |
206 | CheckEvent::Msg(Message::BuildFinished(_)) => {} | 196 | | CheckEvent::Msg(cargo_metadata::Message::BuildFinished(_)) |
207 | CheckEvent::Msg(Message::TextLine(_)) => {} | 197 | | CheckEvent::Msg(cargo_metadata::Message::TextLine(_)) |
208 | CheckEvent::Msg(Message::Unknown) => {} | 198 | | CheckEvent::Msg(cargo_metadata::Message::Unknown) => {} |
209 | } | 199 | } |
210 | } | 200 | } |
211 | 201 | ||
@@ -256,9 +246,11 @@ impl FlycheckActor { | |||
256 | let res = run_cargo(cmd, &mut |message| { | 246 | let res = run_cargo(cmd, &mut |message| { |
257 | // Skip certain kinds of messages to only spend time on what's useful | 247 | // Skip certain kinds of messages to only spend time on what's useful |
258 | match &message { | 248 | match &message { |
259 | Message::CompilerArtifact(artifact) if artifact.fresh => return true, | 249 | cargo_metadata::Message::CompilerArtifact(artifact) if artifact.fresh => { |
260 | Message::BuildScriptExecuted(_) => return true, | 250 | return true |
261 | Message::Unknown => return true, | 251 | } |
252 | cargo_metadata::Message::BuildScriptExecuted(_) | ||
253 | | cargo_metadata::Message::Unknown => return true, | ||
262 | _ => {} | 254 | _ => {} |
263 | } | 255 | } |
264 | 256 | ||
@@ -278,7 +270,7 @@ impl FlycheckActor { | |||
278 | })) | 270 | })) |
279 | } | 271 | } |
280 | 272 | ||
281 | fn send(&self, check_task: CheckTask) { | 273 | fn send(&self, check_task: Message) { |
282 | (self.sender)(check_task) | 274 | (self.sender)(check_task) |
283 | } | 275 | } |
284 | } | 276 | } |
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 6038bf664..446207e9e 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -6,7 +6,7 @@ | |||
6 | use std::{convert::TryFrom, sync::Arc}; | 6 | use std::{convert::TryFrom, sync::Arc}; |
7 | 7 | ||
8 | use crossbeam_channel::{unbounded, Receiver}; | 8 | use crossbeam_channel::{unbounded, Receiver}; |
9 | use flycheck::{CheckTask, FlycheckConfig, FlycheckHandle}; | 9 | use flycheck::{FlycheckConfig, FlycheckHandle}; |
10 | use lsp_types::Url; | 10 | use lsp_types::Url; |
11 | use parking_lot::RwLock; | 11 | use parking_lot::RwLock; |
12 | use ra_db::{CrateId, SourceRoot, VfsPath}; | 12 | use ra_db::{CrateId, SourceRoot, VfsPath}; |
@@ -30,7 +30,7 @@ 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, Receiver<CheckTask>)> { | 33 | ) -> Option<(FlycheckHandle, Receiver<flycheck::Message>)> { |
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, .. } => { |
@@ -69,7 +69,7 @@ pub(crate) struct GlobalState { | |||
69 | pub(crate) analysis_host: AnalysisHost, | 69 | pub(crate) analysis_host: AnalysisHost, |
70 | pub(crate) loader: Box<dyn vfs::loader::Handle>, | 70 | pub(crate) loader: Box<dyn vfs::loader::Handle>, |
71 | pub(crate) task_receiver: Receiver<vfs::loader::Message>, | 71 | pub(crate) task_receiver: Receiver<vfs::loader::Message>, |
72 | pub(crate) flycheck: Option<(FlycheckHandle, Receiver<CheckTask>)>, | 72 | pub(crate) flycheck: Option<(FlycheckHandle, Receiver<flycheck::Message>)>, |
73 | pub(crate) diagnostics: DiagnosticCollection, | 73 | pub(crate) diagnostics: DiagnosticCollection, |
74 | pub(crate) mem_docs: FxHashSet<VfsPath>, | 74 | pub(crate) mem_docs: FxHashSet<VfsPath>, |
75 | 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 0664e4a5a..200641cd5 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -9,7 +9,6 @@ use std::{ | |||
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crossbeam_channel::{never, select, unbounded, RecvError, Sender}; | 11 | use crossbeam_channel::{never, select, unbounded, RecvError, Sender}; |
12 | use flycheck::CheckTask; | ||
13 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; | 12 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; |
14 | use lsp_types::{request::Request as _, NumberOrString, TextDocumentContentChangeEvent}; | 13 | use lsp_types::{request::Request as _, NumberOrString, TextDocumentContentChangeEvent}; |
15 | use ra_db::VfsPath; | 14 | use ra_db::VfsPath; |
@@ -176,7 +175,7 @@ enum Event { | |||
176 | Msg(Message), | 175 | Msg(Message), |
177 | Task(Task), | 176 | Task(Task), |
178 | Vfs(vfs::loader::Message), | 177 | Vfs(vfs::loader::Message), |
179 | CheckWatcher(CheckTask), | 178 | CheckWatcher(flycheck::Message), |
180 | } | 179 | } |
181 | 180 | ||
182 | impl fmt::Debug for Event { | 181 | impl fmt::Debug for Event { |
@@ -250,14 +249,14 @@ fn loop_turn( | |||
250 | } | 249 | } |
251 | vfs::loader::Message::Progress { n_total, n_done } => { | 250 | vfs::loader::Message::Progress { n_total, n_done } => { |
252 | let state = if n_done == 0 { | 251 | let state = if n_done == 0 { |
253 | ProgressState::Start | 252 | Progress::Begin |
254 | } else if n_done < n_total { | 253 | } else if n_done < n_total { |
255 | ProgressState::Report | 254 | Progress::Report |
256 | } else { | 255 | } else { |
257 | assert_eq!(n_done, n_total); | 256 | assert_eq!(n_done, n_total); |
258 | global_state.status = Status::Ready; | 257 | global_state.status = Status::Ready; |
259 | became_ready = true; | 258 | became_ready = true; |
260 | ProgressState::End | 259 | Progress::End |
261 | }; | 260 | }; |
262 | report_progress( | 261 | report_progress( |
263 | global_state, | 262 | global_state, |
@@ -593,17 +592,17 @@ fn apply_document_changes( | |||
593 | } | 592 | } |
594 | 593 | ||
595 | fn on_check_task( | 594 | fn on_check_task( |
596 | task: CheckTask, | 595 | task: flycheck::Message, |
597 | global_state: &mut GlobalState, | 596 | global_state: &mut GlobalState, |
598 | task_sender: &Sender<Task>, | 597 | task_sender: &Sender<Task>, |
599 | msg_sender: &Sender<Message>, | 598 | msg_sender: &Sender<Message>, |
600 | ) -> Result<()> { | 599 | ) -> Result<()> { |
601 | match task { | 600 | match task { |
602 | CheckTask::ClearDiagnostics => { | 601 | flycheck::Message::ClearDiagnostics => { |
603 | task_sender.send(Task::Diagnostic(DiagnosticTask::ClearCheck))?; | 602 | task_sender.send(Task::Diagnostic(DiagnosticTask::ClearCheck))?; |
604 | } | 603 | } |
605 | 604 | ||
606 | CheckTask::AddDiagnostic { workspace_root, diagnostic } => { | 605 | flycheck::Message::AddDiagnostic { workspace_root, diagnostic } => { |
607 | let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( | 606 | let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( |
608 | &global_state.config.diagnostics, | 607 | &global_state.config.diagnostics, |
609 | &diagnostic, | 608 | &diagnostic, |
@@ -627,11 +626,11 @@ fn on_check_task( | |||
627 | } | 626 | } |
628 | } | 627 | } |
629 | 628 | ||
630 | CheckTask::Status(status) => { | 629 | flycheck::Message::Progress(status) => { |
631 | let (state, message) = match status { | 630 | let (state, message) = match status { |
632 | flycheck::Status::Being => (ProgressState::Start, None), | 631 | flycheck::Progress::Being => (Progress::Begin, None), |
633 | flycheck::Status::Progress(target) => (ProgressState::Report, Some(target)), | 632 | flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), |
634 | flycheck::Status::End => (ProgressState::End, None), | 633 | flycheck::Progress::End => (Progress::End, None), |
635 | }; | 634 | }; |
636 | 635 | ||
637 | report_progress(global_state, msg_sender, "cargo check", state, message, None); | 636 | report_progress(global_state, msg_sender, "cargo check", state, message, None); |
@@ -654,8 +653,8 @@ fn on_diagnostic_task(task: DiagnosticTask, msg_sender: &Sender<Message>, state: | |||
654 | } | 653 | } |
655 | 654 | ||
656 | #[derive(Eq, PartialEq)] | 655 | #[derive(Eq, PartialEq)] |
657 | enum ProgressState { | 656 | enum Progress { |
658 | Start, | 657 | Begin, |
659 | Report, | 658 | Report, |
660 | End, | 659 | End, |
661 | } | 660 | } |
@@ -668,7 +667,7 @@ fn report_progress( | |||
668 | global_state: &mut GlobalState, | 667 | global_state: &mut GlobalState, |
669 | sender: &Sender<Message>, | 668 | sender: &Sender<Message>, |
670 | title: &str, | 669 | title: &str, |
671 | state: ProgressState, | 670 | state: Progress, |
672 | message: Option<String>, | 671 | message: Option<String>, |
673 | percentage: Option<f64>, | 672 | percentage: Option<f64>, |
674 | ) { | 673 | ) { |
@@ -677,7 +676,7 @@ fn report_progress( | |||
677 | } | 676 | } |
678 | let token = lsp_types::ProgressToken::String(format!("rustAnalyzer/{}", title)); | 677 | let token = lsp_types::ProgressToken::String(format!("rustAnalyzer/{}", title)); |
679 | let work_done_progress = match state { | 678 | let work_done_progress = match state { |
680 | ProgressState::Start => { | 679 | Progress::Begin => { |
681 | let work_done_progress_create = global_state.req_queue.outgoing.register( | 680 | let work_done_progress_create = global_state.req_queue.outgoing.register( |
682 | lsp_types::request::WorkDoneProgressCreate::METHOD.to_string(), | 681 | lsp_types::request::WorkDoneProgressCreate::METHOD.to_string(), |
683 | lsp_types::WorkDoneProgressCreateParams { token: token.clone() }, | 682 | lsp_types::WorkDoneProgressCreateParams { token: token.clone() }, |
@@ -692,14 +691,14 @@ fn report_progress( | |||
692 | percentage, | 691 | percentage, |
693 | }) | 692 | }) |
694 | } | 693 | } |
695 | ProgressState::Report => { | 694 | Progress::Report => { |
696 | lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport { | 695 | lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport { |
697 | cancellable: None, | 696 | cancellable: None, |
698 | message, | 697 | message, |
699 | percentage, | 698 | percentage, |
700 | }) | 699 | }) |
701 | } | 700 | } |
702 | ProgressState::End => { | 701 | Progress::End => { |
703 | lsp_types::WorkDoneProgress::End(lsp_types::WorkDoneProgressEnd { message }) | 702 | lsp_types::WorkDoneProgress::End(lsp_types::WorkDoneProgressEnd { message }) |
704 | } | 703 | } |
705 | }; | 704 | }; |