Lowercase drive letters on windows before sending to extension.

This commit is contained in:
Omer Ben-Amram 2019-12-15 16:51:57 +02:00
parent 1d9b585c62
commit 324cbe839f
2 changed files with 35 additions and 2 deletions

View File

@ -22,6 +22,7 @@ use crate::{
main_loop::pending_requests::{CompletedRequest, LatestRequests}, main_loop::pending_requests::{CompletedRequest, LatestRequests},
LspError, Result, LspError, Result,
}; };
use std::str::FromStr;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Options { pub struct Options {
@ -235,6 +236,9 @@ impl WorldSnapshot {
let path = self.vfs.read().file2path(VfsFile(id.0)); let path = self.vfs.read().file2path(VfsFile(id.0));
let url = Url::from_file_path(&path) let url = Url::from_file_path(&path)
.map_err(|_| format!("can't convert path to url: {}", path.display()))?; .map_err(|_| format!("can't convert path to url: {}", path.display()))?;
#[cfg(target_os = "windows")]
let url = lowercase_drive_letter(&url);
Ok(url) Ok(url)
} }
@ -279,3 +283,33 @@ impl WorldSnapshot {
self.analysis.feature_flags() self.analysis.feature_flags()
} }
} }
#[cfg(target_os = "windows")]
fn lowercase_drive_letter(url: &Url) -> Url {
let s = url.to_string();
let drive_partition: Vec<&str> = s.rsplitn(2, ':').collect::<Vec<&str>>();
if drive_partition.len() == 1 {
return url.clone();
}
let joined = drive_partition[1].to_ascii_lowercase() + ":" + drive_partition[0];
let url = Url::from_str(&joined).expect("This came from a valid `Url`");
url
}
#[test]
fn test_lowercase_drive_letter_with_drive() {
let url = Url::from_file_path("C:\\Test").unwrap();
let url = lowercase_drive_letter(&url);
assert_eq!(url.to_string(), "file:///c:/Test");
}
#[test]
fn test_drive_without_colon_passthrough() {
let url = Url::from_file_path(r#"\\localhost\C$\my_dir"#).expect("Should work");
let url = lowercase_drive_letter(&url);
assert_eq!(url.to_string(), "file:///C$/my_dir");
}

View File

@ -15,8 +15,7 @@ export function handle(params: PublishDecorationsParams) {
// Unescaped URI should be something like: // Unescaped URI should be something like:
// file:///c:/Workspace/ra-test/src/main.rs // file:///c:/Workspace/ra-test/src/main.rs
// RA server might send it with the drive letter uppercased, so we force only the drive letter to lowercase. // RA server might send it with the drive letter uppercased, so we force only the drive letter to lowercase.
const uriWithLowercasedDrive = params.uri.substr(0, 8) + params.uri[8].toLowerCase() + params.uri.substr(9); return unescapedUri === params.uri
return unescapedUri === uriWithLowercasedDrive
} }
); );