1 //! VFS stands for Virtual File System.
3 //! When doing analysis, we don't want to do any IO, we want to keep all source
4 //! code in memory. However, the actual source code is stored on disk, so you
5 //! need to get it into the memory in the first place somehow. VFS is the
6 //! component which does this.
8 //! It also is responsible for watching the disk for changes, and for merging
9 //! editor state (modified, unsaved files) with disk state.
11 //! VFS is based on a concept of roots: a set of directories on the file system
12 //! whihc are watched for changes. Typically, there will be a root for each
20 path::{Path, PathBuf},
25 use relative_path::RelativePathBuf;
26 use thread_worker::{WorkerHandle, Worker};
29 arena::{ArenaId, Arena},
33 /// `RootFilter` is a predicate that checks if a file can belong to a root
36 file_filter: fn(&Path) -> bool,
40 fn new(root: PathBuf) -> RootFilter {
43 file_filter: rs_extension_filter,
46 fn can_contain(&self, path: &Path) -> bool {
47 (self.file_filter)(path) && path.starts_with(&self.root)
51 fn rs_extension_filter(p: &Path) -> bool {
52 p.extension() == Some(OsStr::new("rs"))
55 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
56 pub struct VfsRoot(u32);
58 impl ArenaId for VfsRoot {
59 fn from_u32(idx: u32) -> VfsRoot {
62 fn to_u32(self) -> u32 {
67 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
68 pub struct VfsFile(u32);
70 impl ArenaId for VfsFile {
71 fn from_u32(idx: u32) -> VfsFile {
74 fn to_u32(self) -> u32 {
81 path: RelativePathBuf,
86 roots: Arena<VfsRoot, RootFilter>,
87 files: Arena<VfsFile, VfsFileData>,
88 // pending_changes: Vec<PendingChange>,
89 worker: Worker<PathBuf, (PathBuf, Vec<FileEvent>)>,
90 worker_handle: WorkerHandle,
94 pub fn new(mut roots: Vec<PathBuf>) -> Vfs {
95 let (worker, worker_handle) = io::start();
98 roots: Arena::default(),
99 files: Arena::default(),
104 roots.sort_by_key(|it| Reverse(it.as_os_str().len()));
107 res.roots.alloc(RootFilter::new(path));
112 pub fn add_file_overlay(&mut self, path: &Path, content: String) {}
114 pub fn change_file_overlay(&mut self, path: &Path, new_content: String) {}
116 pub fn remove_file_overlay(&mut self, path: &Path) {}
118 pub fn commit_changes(&mut self) -> Vec<VfsChange> {
122 pub fn shutdown(self) -> thread::Result<()> {
123 let _ = self.worker.shutdown();
124 self.worker_handle.shutdown()
128 #[derive(Debug, Clone)]
132 files: Vec<(VfsFile, RelativePathBuf, Arc<String>)>,
137 path: RelativePathBuf,