diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-13 13:35:44 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-13 13:35:44 +0100 |
commit | 246c66a7f7fd3f85d7d6e47a36f17bafb0ccb08a (patch) | |
tree | 106b31324ba619413a055a36bd61621b4ac1531a /crates/rust-analyzer/src/diagnostics | |
parent | d64b583e5a67e15db7151a7877871174655729a4 (diff) | |
parent | 50bbf7233dcda8a27255f123622bf57651c9f51c (diff) |
Merge #4867
4867: Cleanup URL handling r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/rust-analyzer/src/diagnostics')
-rw-r--r-- | crates/rust-analyzer/src/diagnostics/to_proto.rs | 73 |
1 files changed, 4 insertions, 69 deletions
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index 257910e09..24ff9b280 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs | |||
@@ -1,10 +1,6 @@ | |||
1 | //! This module provides the functionality needed to convert diagnostics from | 1 | //! This module provides the functionality needed to convert diagnostics from |
2 | //! `cargo check` json format to the LSP diagnostic format. | 2 | //! `cargo check` json format to the LSP diagnostic format. |
3 | use std::{ | 3 | use std::{collections::HashMap, path::Path}; |
4 | collections::HashMap, | ||
5 | path::{Component, Path, Prefix}, | ||
6 | str::FromStr, | ||
7 | }; | ||
8 | 4 | ||
9 | use lsp_types::{ | 5 | use lsp_types::{ |
10 | Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Location, | 6 | Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Location, |
@@ -13,7 +9,7 @@ use lsp_types::{ | |||
13 | use ra_flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan, DiagnosticSpanMacroExpansion}; | 9 | use ra_flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan, DiagnosticSpanMacroExpansion}; |
14 | use stdx::format_to; | 10 | use stdx::format_to; |
15 | 11 | ||
16 | use crate::{lsp_ext, Result}; | 12 | use crate::{lsp_ext, to_proto::url_from_abs_path}; |
17 | 13 | ||
18 | /// Converts a Rust level string to a LSP severity | 14 | /// Converts a Rust level string to a LSP severity |
19 | fn map_level_to_severity(val: DiagnosticLevel) -> Option<DiagnosticSeverity> { | 15 | fn map_level_to_severity(val: DiagnosticLevel) -> Option<DiagnosticSeverity> { |
@@ -65,7 +61,7 @@ fn map_span_to_location(span: &DiagnosticSpan, workspace_root: &Path) -> Locatio | |||
65 | fn map_span_to_location_naive(span: &DiagnosticSpan, workspace_root: &Path) -> Location { | 61 | fn map_span_to_location_naive(span: &DiagnosticSpan, workspace_root: &Path) -> Location { |
66 | let mut file_name = workspace_root.to_path_buf(); | 62 | let mut file_name = workspace_root.to_path_buf(); |
67 | file_name.push(&span.file_name); | 63 | file_name.push(&span.file_name); |
68 | let uri = url_from_path_with_drive_lowercasing(file_name).unwrap(); | 64 | let uri = url_from_abs_path(&file_name); |
69 | 65 | ||
70 | // FIXME: this doesn't handle UTF16 offsets correctly | 66 | // FIXME: this doesn't handle UTF16 offsets correctly |
71 | let range = Range::new( | 67 | let range = Range::new( |
@@ -274,70 +270,16 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
274 | .collect() | 270 | .collect() |
275 | } | 271 | } |
276 | 272 | ||
277 | /// Returns a `Url` object from a given path, will lowercase drive letters if present. | ||
278 | /// This will only happen when processing windows paths. | ||
279 | /// | ||
280 | /// When processing non-windows path, this is essentially the same as `Url::from_file_path`. | ||
281 | pub fn url_from_path_with_drive_lowercasing(path: impl AsRef<Path>) -> Result<Url> { | ||
282 | let component_has_windows_drive = path.as_ref().components().any(|comp| { | ||
283 | if let Component::Prefix(c) = comp { | ||
284 | return matches!(c.kind(), Prefix::Disk(_) | Prefix::VerbatimDisk(_)); | ||
285 | } | ||
286 | false | ||
287 | }); | ||
288 | |||
289 | // VSCode expects drive letters to be lowercased, where rust will uppercase the drive letters. | ||
290 | let res = if component_has_windows_drive { | ||
291 | let url_original = Url::from_file_path(&path) | ||
292 | .map_err(|_| format!("can't convert path to url: {}", path.as_ref().display()))?; | ||
293 | |||
294 | let drive_partition: Vec<&str> = url_original.as_str().rsplitn(2, ':').collect(); | ||
295 | |||
296 | // There is a drive partition, but we never found a colon. | ||
297 | // This should not happen, but in this case we just pass it through. | ||
298 | if drive_partition.len() == 1 { | ||
299 | return Ok(url_original); | ||
300 | } | ||
301 | |||
302 | let joined = drive_partition[1].to_ascii_lowercase() + ":" + drive_partition[0]; | ||
303 | let url = Url::from_str(&joined).expect("This came from a valid `Url`"); | ||
304 | |||
305 | url | ||
306 | } else { | ||
307 | Url::from_file_path(&path) | ||
308 | .map_err(|_| format!("can't convert path to url: {}", path.as_ref().display()))? | ||
309 | }; | ||
310 | Ok(res) | ||
311 | } | ||
312 | |||
313 | #[cfg(test)] | 273 | #[cfg(test)] |
274 | #[cfg(not(windows))] | ||
314 | mod tests { | 275 | mod tests { |
315 | use super::*; | 276 | use super::*; |
316 | 277 | ||
317 | // `Url` is not able to parse windows paths on unix machines. | ||
318 | #[test] | ||
319 | #[cfg(target_os = "windows")] | ||
320 | fn test_lowercase_drive_letter_with_drive() { | ||
321 | let url = url_from_path_with_drive_lowercasing("C:\\Test").unwrap(); | ||
322 | |||
323 | assert_eq!(url.to_string(), "file:///c:/Test"); | ||
324 | } | ||
325 | |||
326 | #[test] | ||
327 | #[cfg(target_os = "windows")] | ||
328 | fn test_drive_without_colon_passthrough() { | ||
329 | let url = url_from_path_with_drive_lowercasing(r#"\\localhost\C$\my_dir"#).unwrap(); | ||
330 | |||
331 | assert_eq!(url.to_string(), "file://localhost/C$/my_dir"); | ||
332 | } | ||
333 | |||
334 | #[cfg(not(windows))] | ||
335 | fn parse_diagnostic(val: &str) -> ra_flycheck::Diagnostic { | 278 | fn parse_diagnostic(val: &str) -> ra_flycheck::Diagnostic { |
336 | serde_json::from_str::<ra_flycheck::Diagnostic>(val).unwrap() | 279 | serde_json::from_str::<ra_flycheck::Diagnostic>(val).unwrap() |
337 | } | 280 | } |
338 | 281 | ||
339 | #[test] | 282 | #[test] |
340 | #[cfg(not(windows))] | ||
341 | fn snap_rustc_incompatible_type_for_trait() { | 283 | fn snap_rustc_incompatible_type_for_trait() { |
342 | let diag = parse_diagnostic( | 284 | let diag = parse_diagnostic( |
343 | r##"{ | 285 | r##"{ |
@@ -391,7 +333,6 @@ mod tests { | |||
391 | } | 333 | } |
392 | 334 | ||
393 | #[test] | 335 | #[test] |
394 | #[cfg(not(windows))] | ||
395 | fn snap_rustc_unused_variable() { | 336 | fn snap_rustc_unused_variable() { |
396 | let diag = parse_diagnostic( | 337 | let diag = parse_diagnostic( |
397 | r##"{ | 338 | r##"{ |
@@ -474,7 +415,6 @@ mod tests { | |||
474 | } | 415 | } |
475 | 416 | ||
476 | #[test] | 417 | #[test] |
477 | #[cfg(not(windows))] | ||
478 | fn snap_rustc_wrong_number_of_parameters() { | 418 | fn snap_rustc_wrong_number_of_parameters() { |
479 | let diag = parse_diagnostic( | 419 | let diag = parse_diagnostic( |
480 | r##"{ | 420 | r##"{ |
@@ -599,7 +539,6 @@ mod tests { | |||
599 | } | 539 | } |
600 | 540 | ||
601 | #[test] | 541 | #[test] |
602 | #[cfg(not(windows))] | ||
603 | fn snap_clippy_pass_by_ref() { | 542 | fn snap_clippy_pass_by_ref() { |
604 | let diag = parse_diagnostic( | 543 | let diag = parse_diagnostic( |
605 | r##"{ | 544 | r##"{ |
@@ -720,7 +659,6 @@ mod tests { | |||
720 | } | 659 | } |
721 | 660 | ||
722 | #[test] | 661 | #[test] |
723 | #[cfg(not(windows))] | ||
724 | fn snap_rustc_mismatched_type() { | 662 | fn snap_rustc_mismatched_type() { |
725 | let diag = parse_diagnostic( | 663 | let diag = parse_diagnostic( |
726 | r##"{ | 664 | r##"{ |
@@ -764,7 +702,6 @@ mod tests { | |||
764 | } | 702 | } |
765 | 703 | ||
766 | #[test] | 704 | #[test] |
767 | #[cfg(not(windows))] | ||
768 | fn snap_handles_macro_location() { | 705 | fn snap_handles_macro_location() { |
769 | let diag = parse_diagnostic( | 706 | let diag = parse_diagnostic( |
770 | r##"{ | 707 | r##"{ |
@@ -1036,7 +973,6 @@ mod tests { | |||
1036 | } | 973 | } |
1037 | 974 | ||
1038 | #[test] | 975 | #[test] |
1039 | #[cfg(not(windows))] | ||
1040 | fn snap_macro_compiler_error() { | 976 | fn snap_macro_compiler_error() { |
1041 | let diag = parse_diagnostic( | 977 | let diag = parse_diagnostic( |
1042 | r##"{ | 978 | r##"{ |
@@ -1266,7 +1202,6 @@ mod tests { | |||
1266 | } | 1202 | } |
1267 | 1203 | ||
1268 | #[test] | 1204 | #[test] |
1269 | #[cfg(not(windows))] | ||
1270 | fn snap_multi_line_fix() { | 1205 | fn snap_multi_line_fix() { |
1271 | let diag = parse_diagnostic( | 1206 | let diag = parse_diagnostic( |
1272 | r##"{ | 1207 | r##"{ |