diff options
author | Aleksey Kladov <[email protected]> | 2020-05-15 00:51:48 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-05-15 00:52:25 +0100 |
commit | 220813dcb0881ff199619c11eb34a39a6de0f67a (patch) | |
tree | bf2bcdce03889a356b37bfe29253de4228ded6ea /crates/ra_flycheck/src/lib.rs | |
parent | 12d82687cd600ec81bf3027661135e5f0d4ad4bd (diff) |
Move LSP bits from flycheck to rust-analyzer
There should be only one place that knows about LSP, and that place is
right before we spit JSON on stdout.
Diffstat (limited to 'crates/ra_flycheck/src/lib.rs')
-rw-r--r-- | crates/ra_flycheck/src/lib.rs | 90 |
1 files changed, 27 insertions, 63 deletions
diff --git a/crates/ra_flycheck/src/lib.rs b/crates/ra_flycheck/src/lib.rs index d5efb6ab3..178485c9e 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,6 @@ 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 | |||
22 | pub use crate::conv::url_from_path_with_drive_lowercasing; | ||
23 | 14 | ||
24 | #[derive(Clone, Debug, PartialEq, Eq)] | 15 | #[derive(Clone, Debug, PartialEq, Eq)] |
25 | pub enum FlycheckConfig { | 16 | pub enum FlycheckConfig { |
@@ -61,10 +52,17 @@ pub enum CheckTask { | |||
61 | ClearDiagnostics, | 52 | ClearDiagnostics, |
62 | 53 | ||
63 | /// Request adding a diagnostic with fixes included to a file | 54 | /// Request adding a diagnostic with fixes included to a file |
64 | AddDiagnostic { url: Url, diagnostic: Diagnostic, fixes: Vec<CodeActionOrCommand> }, | 55 | AddDiagnostic { workspace_root: PathBuf, diagnostic: cargo_metadata::diagnostic::Diagnostic }, |
65 | 56 | ||
66 | /// Request check progress notification to client | 57 | /// Request check progress notification to client |
67 | Status(WorkDoneProgress), | 58 | Status(Status), |
59 | } | ||
60 | |||
61 | #[derive(Debug)] | ||
62 | pub enum Status { | ||
63 | Being, | ||
64 | Progress(String), | ||
65 | End, | ||
68 | } | 66 | } |
69 | 67 | ||
70 | pub enum CheckCommand { | 68 | pub enum CheckCommand { |
@@ -131,9 +129,7 @@ impl FlycheckThread { | |||
131 | 129 | ||
132 | fn clean_previous_results(&self, task_send: &Sender<CheckTask>) { | 130 | fn clean_previous_results(&self, task_send: &Sender<CheckTask>) { |
133 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); | 131 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); |
134 | task_send | 132 | task_send.send(CheckTask::Status(Status::End)).unwrap(); |
135 | .send(CheckTask::Status(WorkDoneProgress::End(WorkDoneProgressEnd { message: None }))) | ||
136 | .unwrap(); | ||
137 | } | 133 | } |
138 | 134 | ||
139 | fn should_recheck(&mut self) -> bool { | 135 | fn should_recheck(&mut self) -> bool { |
@@ -155,52 +151,24 @@ impl FlycheckThread { | |||
155 | fn handle_message(&self, msg: CheckEvent, task_send: &Sender<CheckTask>) { | 151 | fn handle_message(&self, msg: CheckEvent, task_send: &Sender<CheckTask>) { |
156 | match msg { | 152 | match msg { |
157 | CheckEvent::Begin => { | 153 | CheckEvent::Begin => { |
158 | task_send | 154 | 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 | } | 155 | } |
167 | 156 | ||
168 | CheckEvent::End => { | 157 | CheckEvent::End => { |
169 | task_send | 158 | task_send.send(CheckTask::Status(Status::End)).unwrap(); |
170 | .send(CheckTask::Status(WorkDoneProgress::End(WorkDoneProgressEnd { | ||
171 | message: None, | ||
172 | }))) | ||
173 | .unwrap(); | ||
174 | } | 159 | } |
175 | 160 | ||
176 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { | 161 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { |
177 | task_send | 162 | 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 | } | 163 | } |
185 | 164 | ||
186 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { | 165 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { |
187 | let map_result = map_rust_diagnostic_to_lsp(&msg.message, &self.workspace_root); | 166 | task_send |
188 | if map_result.is_empty() { | 167 | .send(CheckTask::AddDiagnostic { |
189 | return; | 168 | workspace_root: self.workspace_root.clone(), |
190 | } | 169 | diagnostic: msg.message, |
191 | 170 | }) | |
192 | for MappedRustDiagnostic { location, diagnostic, fixes } in map_result { | 171 | .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 | } | 172 | } |
205 | 173 | ||
206 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} | 174 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} |
@@ -271,11 +239,11 @@ impl FlycheckThread { | |||
271 | } | 239 | } |
272 | } | 240 | } |
273 | 241 | ||
274 | #[derive(Debug)] | 242 | // #[derive(Debug)] |
275 | pub struct DiagnosticWithFixes { | 243 | // pub struct DiagnosticWithFixes { |
276 | diagnostic: Diagnostic, | 244 | // diagnostic: Diagnostic, |
277 | fixes: Vec<CodeAction>, | 245 | // fixes: Vec<CodeAction>, |
278 | } | 246 | // } |
279 | 247 | ||
280 | enum CheckEvent { | 248 | enum CheckEvent { |
281 | Begin, | 249 | Begin, |
@@ -300,15 +268,11 @@ fn run_cargo( | |||
300 | // erroneus output. | 268 | // erroneus output. |
301 | let stdout = BufReader::new(child.stdout.take().unwrap()); | 269 | let stdout = BufReader::new(child.stdout.take().unwrap()); |
302 | let mut read_at_least_one_message = false; | 270 | let mut read_at_least_one_message = false; |
303 | 271 | 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 { | 272 | let message = match message { |
309 | Ok(message) => message, | 273 | Ok(message) => message, |
310 | Err(err) => { | 274 | Err(err) => { |
311 | log::error!("Invalid json from cargo check, ignoring ({}): {:?} ", err, line); | 275 | log::error!("Invalid json from cargo check, ignoring ({})", err); |
312 | continue; | 276 | continue; |
313 | } | 277 | } |
314 | }; | 278 | }; |