mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 14:43:24 +00:00
improved path checking to consider only paths that may contain a windows drive.
This commit is contained in:
parent
75353753cd
commit
2e2fae32df
@ -17,11 +17,13 @@ use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace};
|
||||
use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch};
|
||||
use ra_vfs_glob::{Glob, RustPackageFilterBuilder};
|
||||
use relative_path::RelativePathBuf;
|
||||
use std::path::{Component, Prefix};
|
||||
|
||||
use crate::{
|
||||
main_loop::pending_requests::{CompletedRequest, LatestRequests},
|
||||
LspError, Result,
|
||||
};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Options {
|
||||
@ -233,11 +235,8 @@ impl WorldSnapshot {
|
||||
|
||||
pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> {
|
||||
let path = self.vfs.read().file2path(VfsFile(id.0));
|
||||
let url = Url::from_file_path(&path)
|
||||
.map_err(|_| format!("can't convert path to url: {}", path.display()))?;
|
||||
let url = url_from_path_with_drive_lowercasing(path)?;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let url = lowercase_drive_letter(&url);
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
@ -283,34 +282,59 @@ impl WorldSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn lowercase_drive_letter(url: &Url) -> Url {
|
||||
use std::str::FromStr;
|
||||
/// Returns a `Url` object from a given path, will lowercase drive letters if present.
|
||||
/// This will only happen when processing windows paths.
|
||||
///
|
||||
/// When processing non-windows path, this is essentially the same as `Url::from_file_path`.
|
||||
fn url_from_path_with_drive_lowercasing(path: impl AsRef<Path>) -> Result<Url> {
|
||||
let component_has_windows_drive = path
|
||||
.as_ref()
|
||||
.components()
|
||||
.find(|comp| {
|
||||
if let Component::Prefix(c) = comp {
|
||||
match c.kind() {
|
||||
Prefix::Disk(_) | Prefix::VerbatimDisk(_) => return true,
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
false
|
||||
})
|
||||
.is_some();
|
||||
|
||||
let s = url.to_string();
|
||||
let drive_partition: Vec<&str> = s.rsplitn(2, ':').collect::<Vec<&str>>();
|
||||
// VSCode expects drive letters to be lowercased, where rust will uppercase the drive letters.
|
||||
if component_has_windows_drive {
|
||||
let url_original = Url::from_file_path(&path)
|
||||
.map_err(|_| format!("can't convert path to url: {}", path.as_ref().display()))?;
|
||||
|
||||
if drive_partition.len() == 1 {
|
||||
return url.clone();
|
||||
let drive_partition: Vec<&str> =
|
||||
url_original.as_str().rsplitn(2, ':').collect::<Vec<&str>>();
|
||||
|
||||
// There is a drive partition, but we never found a colon.
|
||||
// This should not happen, but in this case we just pass it through.
|
||||
if drive_partition.len() == 1 {
|
||||
return Ok(url_original);
|
||||
}
|
||||
|
||||
let joined = drive_partition[1].to_ascii_lowercase() + ":" + drive_partition[0];
|
||||
let url = Url::from_str(&joined).expect("This came from a valid `Url`");
|
||||
|
||||
Ok(url)
|
||||
} else {
|
||||
Ok(Url::from_file_path(&path)
|
||||
.map_err(|_| format!("can't convert path to url: {}", path.as_ref().display()))?)
|
||||
}
|
||||
|
||||
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);
|
||||
let url = url_from_path_with_drive_lowercasing("C:\\Test").unwrap();
|
||||
|
||||
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);
|
||||
let url = url_from_path_with_drive_lowercasing(r#"\\localhost\C$\my_dir"#).unwrap();
|
||||
|
||||
assert_eq!(url.to_string(), "file:///C$/my_dir");
|
||||
assert_eq!(url.to_string(), "file://localhost/C$/my_dir");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user