mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
extract Roots
struct
This commit is contained in:
parent
cfbf47b002
commit
86fadbd4e5
@ -18,6 +18,7 @@ mod io;
|
|||||||
use std::{
|
use std::{
|
||||||
cmp::Reverse,
|
cmp::Reverse,
|
||||||
fmt, fs, mem,
|
fmt, fs, mem,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
thread,
|
thread,
|
||||||
@ -88,8 +89,38 @@ struct VfsFileData {
|
|||||||
text: Arc<String>,
|
text: Arc<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Vfs {
|
pub(crate) struct Roots {
|
||||||
roots: Arena<VfsRoot, Arc<RootFilter>>,
|
roots: Arena<VfsRoot, Arc<RootFilter>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Roots {
|
||||||
|
pub(crate) fn new() -> Roots {
|
||||||
|
Roots {
|
||||||
|
roots: Arena::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn find(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf)> {
|
||||||
|
self.roots
|
||||||
|
.iter()
|
||||||
|
.find_map(|(root, data)| data.can_contain(path).map(|it| (root, it)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Roots {
|
||||||
|
type Target = Arena<VfsRoot, Arc<RootFilter>>;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.roots
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Roots {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.roots
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Vfs {
|
||||||
|
roots: Arc<Roots>,
|
||||||
files: Arena<VfsFile, VfsFileData>,
|
files: Arena<VfsFile, VfsFileData>,
|
||||||
root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>,
|
root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>,
|
||||||
pending_changes: Vec<VfsChange>,
|
pending_changes: Vec<VfsChange>,
|
||||||
@ -103,26 +134,22 @@ impl fmt::Debug for Vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Vfs {
|
impl Vfs {
|
||||||
pub fn new(mut roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) {
|
pub fn new(roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) {
|
||||||
|
let mut root_paths = roots;
|
||||||
let worker = io::Worker::start();
|
let worker = io::Worker::start();
|
||||||
|
|
||||||
let mut res = Vfs {
|
let mut roots = Roots::new();
|
||||||
roots: Arena::default(),
|
let mut root2files = FxHashMap::default();
|
||||||
files: Arena::default(),
|
|
||||||
root2files: FxHashMap::default(),
|
|
||||||
worker,
|
|
||||||
pending_changes: Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// A hack to make nesting work.
|
// A hack to make nesting work.
|
||||||
roots.sort_by_key(|it| Reverse(it.as_os_str().len()));
|
root_paths.sort_by_key(|it| Reverse(it.as_os_str().len()));
|
||||||
for (i, path) in roots.iter().enumerate() {
|
for (i, path) in root_paths.iter().enumerate() {
|
||||||
let root_filter = Arc::new(RootFilter::new(path.clone()));
|
let root_filter = Arc::new(RootFilter::new(path.clone()));
|
||||||
|
|
||||||
let root = res.roots.alloc(root_filter.clone());
|
let root = roots.alloc(root_filter.clone());
|
||||||
res.root2files.insert(root, Default::default());
|
root2files.insert(root, Default::default());
|
||||||
|
|
||||||
let nested_roots = roots[..i]
|
let nested_roots = root_paths[..i]
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|it| it.starts_with(path))
|
.filter(|it| it.starts_with(path))
|
||||||
.map(|it| it.clone())
|
.map(|it| it.clone())
|
||||||
@ -134,10 +161,17 @@ impl Vfs {
|
|||||||
root_filter,
|
root_filter,
|
||||||
nested_roots,
|
nested_roots,
|
||||||
};
|
};
|
||||||
res.worker.sender().send(task).unwrap();
|
worker.sender().send(task).unwrap();
|
||||||
}
|
}
|
||||||
let roots = res.roots.iter().map(|(id, _)| id).collect();
|
let res = Vfs {
|
||||||
(res, roots)
|
roots: Arc::new(roots),
|
||||||
|
files: Arena::default(),
|
||||||
|
root2files,
|
||||||
|
worker,
|
||||||
|
pending_changes: Vec::new(),
|
||||||
|
};
|
||||||
|
let vfs_roots = res.roots.iter().map(|(id, _)| id).collect();
|
||||||
|
(res, vfs_roots)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root2path(&self, root: VfsRoot) -> PathBuf {
|
pub fn root2path(&self, root: VfsRoot) -> PathBuf {
|
||||||
@ -399,10 +433,7 @@ impl Vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option<VfsFile>)> {
|
fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option<VfsFile>)> {
|
||||||
let (root, path) = self
|
let (root, path) = self.roots.find(&path)?;
|
||||||
.roots
|
|
||||||
.iter()
|
|
||||||
.find_map(|(root, data)| data.can_contain(path).map(|it| (root, it)))?;
|
|
||||||
let file = self.root2files[&root]
|
let file = self.root2files[&root]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&it| it)
|
.map(|&it| it)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user