Skip to content

Commit 5e3891c

Browse files
committed
.
1 parent 42be522 commit 5e3891c

File tree

4 files changed

+52
-8
lines changed

4 files changed

+52
-8
lines changed

crates/base_db/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub use crate::{
1818
},
1919
};
2020
pub use salsa;
21-
pub use vfs::{file_set::FileSet, FileId, VfsPath};
21+
pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath};
2222

2323
#[macro_export]
2424
macro_rules! impl_intern_key {
@@ -156,10 +156,11 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
156156
SourceDatabaseExt::file_text(self.0, file_id)
157157
}
158158
fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
159+
let path = AnchoredPath { anchor, path };
159160
// FIXME: this *somehow* should be platform agnostic...
160-
let source_root = self.0.file_source_root(anchor);
161+
let source_root = self.0.file_source_root(path.anchor);
161162
let source_root = self.0.source_root(source_root);
162-
source_root.file_set.resolve_path(anchor, path)
163+
source_root.file_set.resolve_path(path)
163164
}
164165

165166
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {

crates/vfs/src/anchored_path.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

crates/vfs/src/file_set.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::fmt;
77
use fst::{IntoStreamer, Streamer};
88
use rustc_hash::FxHashMap;
99

10-
use crate::{FileId, Vfs, VfsPath};
10+
use crate::{AnchoredPath, FileId, Vfs, VfsPath};
1111

1212
#[derive(Default, Clone, Eq, PartialEq)]
1313
pub struct FileSet {
@@ -19,10 +19,10 @@ impl FileSet {
1919
pub fn len(&self) -> usize {
2020
self.files.len()
2121
}
22-
pub fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
23-
let mut base = self.paths[&anchor].clone();
22+
pub fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
23+
let mut base = self.paths[&path.anchor].clone();
2424
base.pop();
25-
let path = base.join(path)?;
25+
let path = base.join(path.path)?;
2626
self.files.get(&path).copied()
2727
}
2828

crates/vfs/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,18 @@
3636
//! have a single `FileSet` which unions the two sources.
3737
mod vfs_path;
3838
mod path_interner;
39+
mod anchored_path;
3940
pub mod file_set;
4041
pub mod loader;
4142

4243
use std::{fmt, mem};
4344

4445
use crate::path_interner::PathInterner;
4546

46-
pub use crate::vfs_path::VfsPath;
47+
pub use crate::{
48+
anchored_path::{AnchoredPath, AnchoredPathBuf},
49+
vfs_path::VfsPath,
50+
};
4751
pub use paths::{AbsPath, AbsPathBuf};
4852

4953
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]

0 commit comments

Comments
 (0)