aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_vfs/src/lib.rs73
1 files changed, 52 insertions, 21 deletions
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs
index f6b45c18a..cba3a463a 100644
--- a/crates/ra_vfs/src/lib.rs
+++ b/crates/ra_vfs/src/lib.rs
@@ -18,6 +18,7 @@ mod io;
18use std::{ 18use std::{
19 cmp::Reverse, 19 cmp::Reverse,
20 fmt, fs, mem, 20 fmt, fs, mem,
21 ops::{Deref, DerefMut},
21 path::{Path, PathBuf}, 22 path::{Path, PathBuf},
22 sync::Arc, 23 sync::Arc,
23 thread, 24 thread,
@@ -88,8 +89,38 @@ struct VfsFileData {
88 text: Arc<String>, 89 text: Arc<String>,
89} 90}
90 91
91pub struct Vfs { 92pub(crate) struct Roots {
92 roots: Arena<VfsRoot, Arc<RootFilter>>, 93 roots: Arena<VfsRoot, Arc<RootFilter>>,
94}
95
96impl Roots {
97 pub(crate) fn new() -> Roots {
98 Roots {
99 roots: Arena::default(),
100 }
101 }
102 pub(crate) fn find(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf)> {
103 self.roots
104 .iter()
105 .find_map(|(root, data)| data.can_contain(path).map(|it| (root, it)))
106 }
107}
108
109impl Deref for Roots {
110 type Target = Arena<VfsRoot, Arc<RootFilter>>;
111 fn deref(&self) -> &Self::Target {
112 &self.roots
113 }
114}
115
116impl DerefMut for Roots {
117 fn deref_mut(&mut self) -> &mut Self::Target {
118 &mut self.roots
119 }
120}
121
122pub struct Vfs {
123 roots: Arc<Roots>,
93 files: Arena<VfsFile, VfsFileData>, 124 files: Arena<VfsFile, VfsFileData>,
94 root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>, 125 root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>,
95 pending_changes: Vec<VfsChange>, 126 pending_changes: Vec<VfsChange>,
@@ -103,26 +134,22 @@ impl fmt::Debug for Vfs {
103} 134}
104 135
105impl Vfs { 136impl Vfs {
106 pub fn new(mut roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) { 137 pub fn new(roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) {
138 let mut root_paths = roots;
107 let worker = io::Worker::start(); 139 let worker = io::Worker::start();
108 140
109 let mut res = Vfs { 141 let mut roots = Roots::new();
110 roots: Arena::default(), 142 let mut root2files = FxHashMap::default();
111 files: Arena::default(),
112 root2files: FxHashMap::default(),
113 worker,
114 pending_changes: Vec::new(),
115 };
116 143
117 // A hack to make nesting work. 144 // A hack to make nesting work.
118 roots.sort_by_key(|it| Reverse(it.as_os_str().len())); 145 root_paths.sort_by_key(|it| Reverse(it.as_os_str().len()));
119 for (i, path) in roots.iter().enumerate() { 146 for (i, path) in root_paths.iter().enumerate() {
120 let root_filter = Arc::new(RootFilter::new(path.clone())); 147 let root_filter = Arc::new(RootFilter::new(path.clone()));
121 148
122 let root = res.roots.alloc(root_filter.clone()); 149 let root = roots.alloc(root_filter.clone());
123 res.root2files.insert(root, Default::default()); 150 root2files.insert(root, Default::default());
124 151
125 let nested_roots = roots[..i] 152 let nested_roots = root_paths[..i]
126 .iter() 153 .iter()
127 .filter(|it| it.starts_with(path)) 154 .filter(|it| it.starts_with(path))
128 .map(|it| it.clone()) 155 .map(|it| it.clone())
@@ -134,10 +161,17 @@ impl Vfs {
134 root_filter, 161 root_filter,
135 nested_roots, 162 nested_roots,
136 }; 163 };
137 res.worker.sender().send(task).unwrap(); 164 worker.sender().send(task).unwrap();
138 } 165 }
139 let roots = res.roots.iter().map(|(id, _)| id).collect(); 166 let res = Vfs {
140 (res, roots) 167 roots: Arc::new(roots),
168 files: Arena::default(),
169 root2files,
170 worker,
171 pending_changes: Vec::new(),
172 };
173 let vfs_roots = res.roots.iter().map(|(id, _)| id).collect();
174 (res, vfs_roots)
141 } 175 }
142 176
143 pub fn root2path(&self, root: VfsRoot) -> PathBuf { 177 pub fn root2path(&self, root: VfsRoot) -> PathBuf {
@@ -399,10 +433,7 @@ impl Vfs {
399 } 433 }
400 434
401 fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option<VfsFile>)> { 435 fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option<VfsFile>)> {
402 let (root, path) = self 436 let (root, path) = self.roots.find(&path)?;
403 .roots
404 .iter()
405 .find_map(|(root, data)| data.can_contain(path).map(|it| (root, it)))?;
406 let file = self.root2files[&root] 437 let file = self.root2files[&root]
407 .iter() 438 .iter()
408 .map(|&it| it) 439 .map(|&it| it)