From 7509901fa0985f8fc4893a83e0275a063f072dda Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 12:29:14 +0300 Subject: wip --- crates/ra_vfs/src/lib.rs | 128 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 crates/ra_vfs/src/lib.rs (limited to 'crates/ra_vfs/src/lib.rs') diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs new file mode 100644 index 000000000..8f6abadb7 --- /dev/null +++ b/crates/ra_vfs/src/lib.rs @@ -0,0 +1,128 @@ +//! VFS stands for Virtual File System. +//! +//! When doing analysis, we don't want to do any IO, we want to keep all source +//! code in memory. However, the actual source code is stored on disk, so you +//! need to get it into the memory in the first place somehow. VFS is the +//! component which does this. +//! +//! It also is responsible for watching the disk for changes, and for merging +//! editor state (modified, unsaved files) with disk state. +//! +//! VFS is based on a concept of roots: a set of directories on the file system +//! whihc are watched for changes. Typically, there will be a root for each +//! Cargo package. +mod arena; +mod io; + +use std::{ + cmp::Reverse, + path::{Path, PathBuf}, + ffi::OsStr, + sync::Arc, +}; + +use relative_path::RelativePathBuf; +use crate::arena::{ArenaId, Arena}; + +/// `RootFilter` is a predicate that checks if a file can belong to a root +struct RootFilter { + root: PathBuf, + file_filter: fn(&Path) -> bool, +} + +impl RootFilter { + fn new(root: PathBuf) -> RootFilter { + RootFilter { + root, + file_filter: rs_extension_filter, + } + } + fn can_contain(&self, path: &Path) -> bool { + (self.file_filter)(path) && path.starts_with(&self.root) + } +} + +fn rs_extension_filter(p: &Path) -> bool { + p.extension() == Some(OsStr::new("rs")) +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub struct VfsRoot(u32); + +impl ArenaId for VfsRoot { + fn from_u32(idx: u32) -> VfsRoot { + VfsRoot(idx) + } + fn to_u32(self) -> u32 { + self.0 + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub struct VfsFile(u32); + +impl ArenaId for VfsFile { + fn from_u32(idx: u32) -> VfsFile { + VfsFile(idx) + } + fn to_u32(self) -> u32 { + self.0 + } +} + +struct VfsFileData { + root: VfsRoot, + path: RelativePathBuf, + text: Arc, +} + +#[derive(Default)] +struct Vfs { + roots: Arena, + files: Arena, + // pending_changes: Vec, +} + +impl Vfs { + pub fn new(mut roots: Vec) -> Vfs { + let mut res = Vfs::default(); + + roots.sort_by_key(|it| Reverse(it.as_os_str().len())); + + for path in roots { + res.roots.alloc(RootFilter::new(path)); + } + res + } + + pub fn add_file_overlay(&mut self, path: &Path, content: String) {} + + pub fn change_file_overlay(&mut self, path: &Path, new_content: String) {} + + pub fn remove_file_overlay(&mut self, path: &Path) {} + + pub fn commit_changes(&mut self) -> Vec { + unimplemented!() + } +} + +#[derive(Debug, Clone)] +pub enum VfsChange { + AddRoot { + root: VfsRoot, + files: Vec<(VfsFile, RelativePathBuf, Arc)>, + }, + AddFile { + file: VfsFile, + root: VfsRoot, + path: RelativePathBuf, + text: Arc, + }, + RemoveFile { + file: VfsFile, + }, + ChangeFile { + file: VfsFile, + text: Arc, + }, +} -- cgit v1.2.3