From 6b5d90972ae2f288ae7cf57e209c0d5d8c7a1fd2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 17 Feb 2019 19:46:55 +0300 Subject: move roots to a module --- crates/ra_vfs/src/lib.rs | 108 +++++------------------------------------------ 1 file changed, 10 insertions(+), 98 deletions(-) (limited to 'crates/ra_vfs/src/lib.rs') diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index cfdc1275f..a740e82ef 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -15,10 +15,10 @@ //! VFS is based on a concept of roots: a set of directories on the file system //! which are watched for changes. Typically, there will be a root for each //! Cargo package. +mod roots; mod io; use std::{ - cmp::Reverse, fmt, fs, mem, path::{Path, PathBuf}, sync::Arc, @@ -26,106 +26,18 @@ use std::{ use crossbeam_channel::Receiver; use ra_arena::{impl_arena_id, Arena, RawId, map::ArenaMap}; -use relative_path::{Component, RelativePath, RelativePathBuf}; +use relative_path::{RelativePath, RelativePathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; -pub use crate::io::TaskResult as VfsTask; -use io::{TaskResult, Worker}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct VfsRoot(pub RawId); -impl_arena_id!(VfsRoot); - -/// Describes the contents of a single source root. -/// -/// `RootConfig` can be thought of as a glob pattern like `src/**.rs` which -/// specifies the source root or as a function which takes a `PathBuf` and -/// returns `true` iff path belongs to the source root -pub(crate) struct RootConfig { - root: PathBuf, - // result of `root.canonicalize()` if that differs from `root`; `None` otherwise. - canonical_root: Option, - excluded_dirs: Vec, -} - -pub(crate) struct Roots { - roots: Arena>, -} - -impl std::ops::Deref for Roots { - type Target = Arena>; - fn deref(&self) -> &Self::Target { - &self.roots - } -} - -impl RootConfig { - fn new(root: PathBuf, excluded_dirs: Vec) -> RootConfig { - let mut canonical_root = root.canonicalize().ok(); - if Some(&root) == canonical_root.as_ref() { - canonical_root = None; - } - RootConfig { root, canonical_root, excluded_dirs } - } - /// Checks if root contains a path and returns a root-relative path. - pub(crate) fn contains(&self, path: &Path) -> Option { - // First, check excluded dirs - if self.excluded_dirs.iter().any(|it| path.starts_with(it)) { - return None; - } - let rel_path = path - .strip_prefix(&self.root) - .or_else(|err_payload| { - self.canonical_root - .as_ref() - .map_or(Err(err_payload), |canonical_root| path.strip_prefix(canonical_root)) - }) - .ok()?; - let rel_path = RelativePathBuf::from_path(rel_path).ok()?; - - // Ignore some common directories. - // - // FIXME: don't hard-code, specify at source-root creation time using - // gitignore - for (i, c) in rel_path.components().enumerate() { - if let Component::Normal(c) = c { - if (i == 0 && c == "target") || c == ".git" || c == "node_modules" { - return None; - } - } - } - - if path.is_file() && rel_path.extension() != Some("rs") { - return None; - } - - Some(rel_path) - } -} +use crate::{ + io::{TaskResult, Worker}, + roots::{RootConfig, Roots}, +}; -impl Roots { - pub(crate) fn new(mut paths: Vec) -> Roots { - let mut roots = Arena::default(); - // A hack to make nesting work. - paths.sort_by_key(|it| Reverse(it.as_os_str().len())); - paths.dedup(); - for (i, path) in paths.iter().enumerate() { - let nested_roots = paths[..i] - .iter() - .filter(|it| it.starts_with(path)) - .map(|it| it.clone()) - .collect::>(); - - let config = Arc::new(RootConfig::new(path.clone(), nested_roots)); - - roots.alloc(config.clone()); - } - Roots { roots } - } - pub(crate) fn find(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf)> { - self.roots.iter().find_map(|(root, data)| data.contains(path).map(|it| (root, it))) - } -} +pub use crate::{ + io::TaskResult as VfsTask, + roots::VfsRoot, +}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct VfsFile(pub RawId); -- cgit v1.2.3