mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
.
This commit is contained in:
parent
42be522c80
commit
5e3891c255
4 changed files with 52 additions and 8 deletions
|
@ -18,7 +18,7 @@ pub use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
pub use salsa;
|
pub use salsa;
|
||||||
pub use vfs::{file_set::FileSet, FileId, VfsPath};
|
pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_intern_key {
|
macro_rules! impl_intern_key {
|
||||||
|
@ -156,10 +156,11 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
|
||||||
SourceDatabaseExt::file_text(self.0, file_id)
|
SourceDatabaseExt::file_text(self.0, file_id)
|
||||||
}
|
}
|
||||||
fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
|
fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
|
||||||
|
let path = AnchoredPath { anchor, path };
|
||||||
// FIXME: this *somehow* should be platform agnostic...
|
// FIXME: this *somehow* should be platform agnostic...
|
||||||
let source_root = self.0.file_source_root(anchor);
|
let source_root = self.0.file_source_root(path.anchor);
|
||||||
let source_root = self.0.source_root(source_root);
|
let source_root = self.0.source_root(source_root);
|
||||||
source_root.file_set.resolve_path(anchor, path)
|
source_root.file_set.resolve_path(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
|
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
|
||||||
|
|
39
crates/vfs/src/anchored_path.rs
Normal file
39
crates/vfs/src/anchored_path.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
//! Analysis-level representation of file-system paths.
|
||||||
|
//!
|
||||||
|
//! The primary goal of this is to losslessly represent paths like
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! #[path = "./bar.rs"]
|
||||||
|
//! mod foo;
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! The first approach one might reach for is to use `PathBuf`. The problem here
|
||||||
|
//! is that `PathBuf` depends on host target (windows or linux), but
|
||||||
|
//! rust-analyzer should be capable to process `#[path = r"C:\bar.rs"]` on Unix.
|
||||||
|
//!
|
||||||
|
//! The second try is to use a `String`. This also fails, however. Consider a
|
||||||
|
//! hypothetical scenario, where rust-analyzer operates in a
|
||||||
|
//! networked/distributed mode. There's one global instance of rust-analyzer,
|
||||||
|
//! which processes requests from different machines. Now, the semantics of
|
||||||
|
//! `#[path = "/abs/path.rs"]` actually depends on which file-system we are at!
|
||||||
|
//! That is, even absolute paths exist relative to a file system!
|
||||||
|
//!
|
||||||
|
//! A more realistic scenario here is virtual VFS paths we use for testing. More
|
||||||
|
//! generally, there can be separate "universes" of VFS paths.
|
||||||
|
//!
|
||||||
|
//! That's why we use anchored representation -- each path carries an info about
|
||||||
|
//! a file this path originates from. We can fetch fs/"universe" information
|
||||||
|
//! from the anchor than.
|
||||||
|
use crate::FileId;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct AnchoredPathBuf {
|
||||||
|
pub anchor: FileId,
|
||||||
|
pub path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
pub struct AnchoredPath<'a> {
|
||||||
|
pub anchor: FileId,
|
||||||
|
pub path: &'a str,
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ use std::fmt;
|
||||||
use fst::{IntoStreamer, Streamer};
|
use fst::{IntoStreamer, Streamer};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::{FileId, Vfs, VfsPath};
|
use crate::{AnchoredPath, FileId, Vfs, VfsPath};
|
||||||
|
|
||||||
#[derive(Default, Clone, Eq, PartialEq)]
|
#[derive(Default, Clone, Eq, PartialEq)]
|
||||||
pub struct FileSet {
|
pub struct FileSet {
|
||||||
|
@ -19,10 +19,10 @@ impl FileSet {
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.files.len()
|
self.files.len()
|
||||||
}
|
}
|
||||||
pub fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
|
pub fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
|
||||||
let mut base = self.paths[&anchor].clone();
|
let mut base = self.paths[&path.anchor].clone();
|
||||||
base.pop();
|
base.pop();
|
||||||
let path = base.join(path)?;
|
let path = base.join(path.path)?;
|
||||||
self.files.get(&path).copied()
|
self.files.get(&path).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
//! have a single `FileSet` which unions the two sources.
|
//! have a single `FileSet` which unions the two sources.
|
||||||
mod vfs_path;
|
mod vfs_path;
|
||||||
mod path_interner;
|
mod path_interner;
|
||||||
|
mod anchored_path;
|
||||||
pub mod file_set;
|
pub mod file_set;
|
||||||
pub mod loader;
|
pub mod loader;
|
||||||
|
|
||||||
|
@ -43,7 +44,10 @@ use std::{fmt, mem};
|
||||||
|
|
||||||
use crate::path_interner::PathInterner;
|
use crate::path_interner::PathInterner;
|
||||||
|
|
||||||
pub use crate::vfs_path::VfsPath;
|
pub use crate::{
|
||||||
|
anchored_path::{AnchoredPath, AnchoredPathBuf},
|
||||||
|
vfs_path::VfsPath,
|
||||||
|
};
|
||||||
pub use paths::{AbsPath, AbsPathBuf};
|
pub use paths::{AbsPath, AbsPathBuf};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
|
|
Loading…
Reference in a new issue