diff options
Diffstat (limited to 'crates/ra_flycheck/src/lib.rs')
-rw-r--r-- | crates/ra_flycheck/src/lib.rs | 88 |
1 files changed, 25 insertions, 63 deletions
diff --git a/crates/ra_flycheck/src/lib.rs b/crates/ra_flycheck/src/lib.rs index d5efb6ab3..041e38a9f 100644 --- a/crates/ra_flycheck/src/lib.rs +++ b/crates/ra_flycheck/src/lib.rs | |||
@@ -1,10 +1,9 @@ | |||
1 | //! cargo_check provides the functionality needed to run `cargo check` or | 1 | //! cargo_check provides the functionality needed to run `cargo check` or |
2 | //! another compatible command (f.x. clippy) in a background thread and provide | 2 | //! another compatible command (f.x. clippy) in a background thread and provide |
3 | //! LSP diagnostics based on the output of the command. | 3 | //! LSP diagnostics based on the output of the command. |
4 | mod conv; | ||
5 | 4 | ||
6 | use std::{ | 5 | use std::{ |
7 | io::{self, BufRead, BufReader}, | 6 | io::{self, BufReader}, |
8 | path::PathBuf, | 7 | path::PathBuf, |
9 | process::{Command, Stdio}, | 8 | process::{Command, Stdio}, |
10 | time::Instant, | 9 | time::Instant, |
@@ -12,14 +11,10 @@ use std::{ | |||
12 | 11 | ||
13 | use cargo_metadata::Message; | 12 | 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 | use lsp_types::{ | ||
16 | CodeAction, CodeActionOrCommand, Diagnostic, Url, WorkDoneProgress, WorkDoneProgressBegin, | ||
17 | WorkDoneProgressEnd, WorkDoneProgressReport, | ||
18 | }; | ||
19 | |||
20 | use crate::conv::{map_rust_diagnostic_to_lsp, MappedRustDiagnostic}; | ||
21 | 14 | ||
22 | pub use crate::conv::url_from_path_with_drive_lowercasing; | 15 | pub use cargo_metadata::diagnostic::{ |
16 | Applicability, Diagnostic, DiagnosticLevel, DiagnosticSpan, DiagnosticSpanMacroExpansion, | ||
17 | }; | ||
23 | 18 | ||
24 | #[derive(Clone, Debug, PartialEq, Eq)] | 19 | #[derive(Clone, Debug, PartialEq, Eq)] |
25 | pub enum FlycheckConfig { | 20 | pub enum FlycheckConfig { |
@@ -61,10 +56,17 @@ pub enum CheckTask { | |||
61 | ClearDiagnostics, | 56 | ClearDiagnostics, |
62 | 57 | ||
63 | /// Request adding a diagnostic with fixes included to a file | 58 | /// Request adding a diagnostic with fixes included to a file |
64 | AddDiagnostic { url: Url, diagnostic: Diagnostic, fixes: Vec<CodeActionOrCommand> }, | 59 | AddDiagnostic { workspace_root: PathBuf, diagnostic: Diagnostic }, |
65 | 60 | ||
66 | /// Request check progress notification to client | 61 | /// Request check progress notification to client |
67 | Status(WorkDoneProgress), | 62 | Status(Status), |
63 | } | ||
64 | |||
65 | #[derive(Debug)] | ||
66 | pub enum Status { | ||
67 | Being, | ||
68 | Progress(String), | ||
69 | End, | ||
68 | } | 70 | } |
69 | 71 | ||
70 | pub enum CheckCommand { | 72 | pub enum CheckCommand { |
@@ -131,9 +133,7 @@ impl FlycheckThread { | |||
131 | 133 | ||
132 | fn clean_previous_results(&self, task_send: &Sender<CheckTask>) { | 134 | fn clean_previous_results(&self, task_send: &Sender<CheckTask>) { |
133 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); | 135 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); |
134 | task_send | 136 | task_send.send(CheckTask::Status(Status::End)).unwrap(); |
135 | .send(CheckTask::Status(WorkDoneProgress::End(WorkDoneProgressEnd { message: None }))) | ||
136 | .unwrap(); | ||
137 | } | 137 | } |
138 | 138 | ||
139 | fn should_recheck(&mut self) -> bool { | 139 | fn should_recheck(&mut self) -> bool { |
@@ -155,52 +155,24 @@ impl FlycheckThread { | |||
155 | fn handle_message(&self, msg: CheckEvent, task_send: &Sender<CheckTask>) { | 155 | fn handle_message(&self, msg: CheckEvent, task_send: &Sender<CheckTask>) { |
156 | match msg { | 156 | match msg { |
157 | CheckEvent::Begin => { | 157 | CheckEvent::Begin => { |
158 | task_send | 158 | task_send.send(CheckTask::Status(Status::Being)).unwrap(); |
159 | .send(CheckTask::Status(WorkDoneProgress::Begin(WorkDoneProgressBegin { | ||
160 | title: "Running `cargo check`".to_string(), | ||
161 | cancellable: Some(false), | ||
162 | message: None, | ||
163 | percentage: None, | ||
164 | }))) | ||
165 | .unwrap(); | ||
166 | } | 159 | } |
167 | 160 | ||
168 | CheckEvent::End => { | 161 | CheckEvent::End => { |
169 | task_send | 162 | task_send.send(CheckTask::Status(Status::End)).unwrap(); |
170 | .send(CheckTask::Status(WorkDoneProgress::End(WorkDoneProgressEnd { | ||
171 | message: None, | ||
172 | }))) | ||
173 | .unwrap(); | ||
174 | } | 163 | } |
175 | 164 | ||
176 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { | 165 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { |
177 | task_send | 166 | task_send.send(CheckTask::Status(Status::Progress(msg.target.name))).unwrap(); |
178 | .send(CheckTask::Status(WorkDoneProgress::Report(WorkDoneProgressReport { | ||
179 | cancellable: Some(false), | ||
180 | message: Some(msg.target.name), | ||
181 | percentage: None, | ||
182 | }))) | ||
183 | .unwrap(); | ||
184 | } | 167 | } |
185 | 168 | ||
186 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { | 169 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { |
187 | let map_result = map_rust_diagnostic_to_lsp(&msg.message, &self.workspace_root); | 170 | task_send |
188 | if map_result.is_empty() { | 171 | .send(CheckTask::AddDiagnostic { |
189 | return; | 172 | workspace_root: self.workspace_root.clone(), |
190 | } | 173 | diagnostic: msg.message, |
191 | 174 | }) | |
192 | for MappedRustDiagnostic { location, diagnostic, fixes } in map_result { | 175 | .unwrap(); |
193 | let fixes = fixes | ||
194 | .into_iter() | ||
195 | .map(|fix| { | ||
196 | CodeAction { diagnostics: Some(vec![diagnostic.clone()]), ..fix }.into() | ||
197 | }) | ||
198 | .collect(); | ||
199 | |||
200 | task_send | ||
201 | .send(CheckTask::AddDiagnostic { url: location.uri, diagnostic, fixes }) | ||
202 | .unwrap(); | ||
203 | } | ||
204 | } | 176 | } |
205 | 177 | ||
206 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} | 178 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} |
@@ -271,12 +243,6 @@ impl FlycheckThread { | |||
271 | } | 243 | } |
272 | } | 244 | } |
273 | 245 | ||
274 | #[derive(Debug)] | ||
275 | pub struct DiagnosticWithFixes { | ||
276 | diagnostic: Diagnostic, | ||
277 | fixes: Vec<CodeAction>, | ||
278 | } | ||
279 | |||
280 | enum CheckEvent { | 246 | enum CheckEvent { |
281 | Begin, | 247 | Begin, |
282 | Msg(cargo_metadata::Message), | 248 | Msg(cargo_metadata::Message), |
@@ -300,15 +266,11 @@ fn run_cargo( | |||
300 | // erroneus output. | 266 | // erroneus output. |
301 | let stdout = BufReader::new(child.stdout.take().unwrap()); | 267 | let stdout = BufReader::new(child.stdout.take().unwrap()); |
302 | let mut read_at_least_one_message = false; | 268 | let mut read_at_least_one_message = false; |
303 | 269 | for message in cargo_metadata::Message::parse_stream(stdout) { | |
304 | for line in stdout.lines() { | ||
305 | let line = line?; | ||
306 | |||
307 | let message = serde_json::from_str::<cargo_metadata::Message>(&line); | ||
308 | let message = match message { | 270 | let message = match message { |
309 | Ok(message) => message, | 271 | Ok(message) => message, |
310 | Err(err) => { | 272 | Err(err) => { |
311 | log::error!("Invalid json from cargo check, ignoring ({}): {:?} ", err, line); | 273 | log::error!("Invalid json from cargo check, ignoring ({})", err); |
312 | continue; | 274 | continue; |
313 | } | 275 | } |
314 | }; | 276 | }; |