diff options
author | Aleksey Kladov <[email protected]> | 2020-12-09 15:41:35 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-12-09 15:42:07 +0000 |
commit | 5e3891c2559de5a6540d69bc14ded281484479f9 (patch) | |
tree | d0f1fb876c99dea1bbd709a9dda006a7941f1eee /crates/vfs/src | |
parent | 42be522c80cf0cc2d49b60f3c1d66afdc51fcbbb (diff) |
.
Diffstat (limited to 'crates/vfs/src')
-rw-r--r-- | crates/vfs/src/anchored_path.rs | 39 | ||||
-rw-r--r-- | crates/vfs/src/file_set.rs | 8 | ||||
-rw-r--r-- | crates/vfs/src/lib.rs | 6 |
3 files changed, 48 insertions, 5 deletions
diff --git a/crates/vfs/src/anchored_path.rs b/crates/vfs/src/anchored_path.rs new file mode 100644 index 000000000..02720a32e --- /dev/null +++ b/crates/vfs/src/anchored_path.rs | |||
@@ -0,0 +1,39 @@ | |||
1 | //! Analysis-level representation of file-system paths. | ||
2 | //! | ||
3 | //! The primary goal of this is to losslessly represent paths like | ||
4 | //! | ||
5 | //! ``` | ||
6 | //! #[path = "./bar.rs"] | ||
7 | //! mod foo; | ||
8 | //! ``` | ||
9 | //! | ||
10 | //! The first approach one might reach for is to use `PathBuf`. The problem here | ||
11 | //! is that `PathBuf` depends on host target (windows or linux), but | ||
12 | //! rust-analyzer should be capable to process `#[path = r"C:\bar.rs"]` on Unix. | ||
13 | //! | ||
14 | //! The second try is to use a `String`. This also fails, however. Consider a | ||
15 | //! hypothetical scenario, where rust-analyzer operates in a | ||
16 | //! networked/distributed mode. There's one global instance of rust-analyzer, | ||
17 | //! which processes requests from different machines. Now, the semantics of | ||
18 | //! `#[path = "/abs/path.rs"]` actually depends on which file-system we are at! | ||
19 | //! That is, even absolute paths exist relative to a file system! | ||
20 | //! | ||
21 | //! A more realistic scenario here is virtual VFS paths we use for testing. More | ||
22 | //! generally, there can be separate "universes" of VFS paths. | ||
23 | //! | ||
24 | //! That's why we use anchored representation -- each path carries an info about | ||
25 | //! a file this path originates from. We can fetch fs/"universe" information | ||
26 | //! from the anchor than. | ||
27 | use crate::FileId; | ||
28 | |||
29 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
30 | pub struct AnchoredPathBuf { | ||
31 | pub anchor: FileId, | ||
32 | pub path: String, | ||
33 | } | ||
34 | |||
35 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
36 | pub struct AnchoredPath<'a> { | ||
37 | pub anchor: FileId, | ||
38 | pub path: &'a str, | ||
39 | } | ||
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs index 9093fbd97..49ca593ac 100644 --- a/crates/vfs/src/file_set.rs +++ b/crates/vfs/src/file_set.rs | |||
@@ -7,7 +7,7 @@ use std::fmt; | |||
7 | use fst::{IntoStreamer, Streamer}; | 7 | use fst::{IntoStreamer, Streamer}; |
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
9 | 9 | ||
10 | use crate::{FileId, Vfs, VfsPath}; | 10 | use crate::{AnchoredPath, FileId, Vfs, VfsPath}; |
11 | 11 | ||
12 | #[derive(Default, Clone, Eq, PartialEq)] | 12 | #[derive(Default, Clone, Eq, PartialEq)] |
13 | pub struct FileSet { | 13 | pub struct FileSet { |
@@ -19,10 +19,10 @@ impl FileSet { | |||
19 | pub fn len(&self) -> usize { | 19 | pub fn len(&self) -> usize { |
20 | self.files.len() | 20 | self.files.len() |
21 | } | 21 | } |
22 | pub fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> { | 22 | pub fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> { |
23 | let mut base = self.paths[&anchor].clone(); | 23 | let mut base = self.paths[&path.anchor].clone(); |
24 | base.pop(); | 24 | base.pop(); |
25 | let path = base.join(path)?; | 25 | let path = base.join(path.path)?; |
26 | self.files.get(&path).copied() | 26 | self.files.get(&path).copied() |
27 | } | 27 | } |
28 | 28 | ||
diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs index cdf6f1fd0..a3be579a7 100644 --- a/crates/vfs/src/lib.rs +++ b/crates/vfs/src/lib.rs | |||
@@ -36,6 +36,7 @@ | |||
36 | //! have a single `FileSet` which unions the two sources. | 36 | //! have a single `FileSet` which unions the two sources. |
37 | mod vfs_path; | 37 | mod vfs_path; |
38 | mod path_interner; | 38 | mod path_interner; |
39 | mod anchored_path; | ||
39 | pub mod file_set; | 40 | pub mod file_set; |
40 | pub mod loader; | 41 | pub mod loader; |
41 | 42 | ||
@@ -43,7 +44,10 @@ use std::{fmt, mem}; | |||
43 | 44 | ||
44 | use crate::path_interner::PathInterner; | 45 | use crate::path_interner::PathInterner; |
45 | 46 | ||
46 | pub use crate::vfs_path::VfsPath; | 47 | pub use crate::{ |
48 | anchored_path::{AnchoredPath, AnchoredPathBuf}, | ||
49 | vfs_path::VfsPath, | ||
50 | }; | ||
47 | pub use paths::{AbsPath, AbsPathBuf}; | 51 | pub use paths::{AbsPath, AbsPathBuf}; |
48 | 52 | ||
49 | #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)] | 53 | #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)] |