diff --git a/Cargo.lock b/Cargo.lock index ad9f6970b39..55bef8cb9e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1088,6 +1088,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ra_arena 0.1.0", "ra_db 0.1.0", + "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crates/ra_batch/src/vfs_filter.rs b/crates/ra_batch/src/vfs_filter.rs index 290aec1728e..dd20c12031f 100644 --- a/crates/ra_batch/src/vfs_filter.rs +++ b/crates/ra_batch/src/vfs_filter.rs @@ -2,9 +2,10 @@ use std::path::PathBuf; use ra_project_model::ProjectRoot; use ra_vfs::{RootEntry, Filter, RelativePath}; +/// `IncludeRustFiles` is used to convert +/// from `ProjectRoot` to `RootEntry` for VFS pub struct IncludeRustFiles { - /// Is a member of the current workspace - is_member: bool, + root: ProjectRoot, } impl IncludeRustFiles { @@ -16,44 +17,38 @@ impl IncludeRustFiles { } pub fn from_root(root: ProjectRoot) -> RootEntry { - let is_member = root.is_member(); - IncludeRustFiles::into_entry(root.into_path(), is_member) + IncludeRustFiles::from(root).into() } #[allow(unused)] pub fn external(path: PathBuf) -> RootEntry { - IncludeRustFiles::into_entry(path, false) + IncludeRustFiles::from_root(ProjectRoot::new(path, false)) } pub fn member(path: PathBuf) -> RootEntry { - IncludeRustFiles::into_entry(path, true) - } - - fn into_entry(path: PathBuf, is_member: bool) -> RootEntry { - RootEntry::new(path, Box::new(Self { is_member })) + IncludeRustFiles::from_root(ProjectRoot::new(path, true)) } } impl Filter for IncludeRustFiles { fn include_dir(&self, dir_path: &RelativePath) -> bool { - const COMMON_IGNORED_DIRS: &[&str] = &["node_modules", "target", ".git"]; - const EXTERNAL_IGNORED_DIRS: &[&str] = &["examples", "tests", "benches"]; - - let is_ignored = if self.is_member { - dir_path.components().any(|c| COMMON_IGNORED_DIRS.contains(&c.as_str())) - } else { - dir_path.components().any(|c| { - let path = c.as_str(); - COMMON_IGNORED_DIRS.contains(&path) || EXTERNAL_IGNORED_DIRS.contains(&path) - }) - }; - - let hidden = dir_path.components().any(|c| c.as_str().starts_with(".")); - - !is_ignored && !hidden + self.root.include_dir(dir_path) } fn include_file(&self, file_path: &RelativePath) -> bool { - file_path.extension() == Some("rs") + self.root.include_file(file_path) + } +} + +impl std::convert::From for IncludeRustFiles { + fn from(v: ProjectRoot) -> IncludeRustFiles { + IncludeRustFiles { root: v } + } +} + +impl std::convert::From for RootEntry { + fn from(v: IncludeRustFiles) -> RootEntry { + let path = v.root.path().clone(); + RootEntry::new(path, Box::new(v)) } } diff --git a/crates/ra_lsp_server/src/vfs_filter.rs b/crates/ra_lsp_server/src/vfs_filter.rs index 290aec1728e..dd20c12031f 100644 --- a/crates/ra_lsp_server/src/vfs_filter.rs +++ b/crates/ra_lsp_server/src/vfs_filter.rs @@ -2,9 +2,10 @@ use std::path::PathBuf; use ra_project_model::ProjectRoot; use ra_vfs::{RootEntry, Filter, RelativePath}; +/// `IncludeRustFiles` is used to convert +/// from `ProjectRoot` to `RootEntry` for VFS pub struct IncludeRustFiles { - /// Is a member of the current workspace - is_member: bool, + root: ProjectRoot, } impl IncludeRustFiles { @@ -16,44 +17,38 @@ impl IncludeRustFiles { } pub fn from_root(root: ProjectRoot) -> RootEntry { - let is_member = root.is_member(); - IncludeRustFiles::into_entry(root.into_path(), is_member) + IncludeRustFiles::from(root).into() } #[allow(unused)] pub fn external(path: PathBuf) -> RootEntry { - IncludeRustFiles::into_entry(path, false) + IncludeRustFiles::from_root(ProjectRoot::new(path, false)) } pub fn member(path: PathBuf) -> RootEntry { - IncludeRustFiles::into_entry(path, true) - } - - fn into_entry(path: PathBuf, is_member: bool) -> RootEntry { - RootEntry::new(path, Box::new(Self { is_member })) + IncludeRustFiles::from_root(ProjectRoot::new(path, true)) } } impl Filter for IncludeRustFiles { fn include_dir(&self, dir_path: &RelativePath) -> bool { - const COMMON_IGNORED_DIRS: &[&str] = &["node_modules", "target", ".git"]; - const EXTERNAL_IGNORED_DIRS: &[&str] = &["examples", "tests", "benches"]; - - let is_ignored = if self.is_member { - dir_path.components().any(|c| COMMON_IGNORED_DIRS.contains(&c.as_str())) - } else { - dir_path.components().any(|c| { - let path = c.as_str(); - COMMON_IGNORED_DIRS.contains(&path) || EXTERNAL_IGNORED_DIRS.contains(&path) - }) - }; - - let hidden = dir_path.components().any(|c| c.as_str().starts_with(".")); - - !is_ignored && !hidden + self.root.include_dir(dir_path) } fn include_file(&self, file_path: &RelativePath) -> bool { - file_path.extension() == Some("rs") + self.root.include_file(file_path) + } +} + +impl std::convert::From for IncludeRustFiles { + fn from(v: ProjectRoot) -> IncludeRustFiles { + IncludeRustFiles { root: v } + } +} + +impl std::convert::From for RootEntry { + fn from(v: IncludeRustFiles) -> RootEntry { + let path = v.root.path().clone(); + RootEntry::new(path, Box::new(v)) } } diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index 34d33531eb8..cf4adf35cd5 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml @@ -7,6 +7,7 @@ authors = ["rust-analyzer developers"] [dependencies] log = "0.4.5" rustc-hash = "1.0" +relative-path = "0.4.0" failure = "0.1.4" diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index b27cb55effd..6f46a2d4350 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -15,6 +15,8 @@ use ra_db::{CrateGraph, FileId, Edition}; use serde_json::from_reader; +use relative_path::RelativePath; + pub use crate::{ cargo_workspace::{CargoWorkspace, Package, Target, TargetKind}, json_project::JsonProject, @@ -43,17 +45,39 @@ pub struct ProjectRoot { } impl ProjectRoot { - fn new(path: PathBuf, is_member: bool) -> ProjectRoot { + pub fn new(path: PathBuf, is_member: bool) -> ProjectRoot { ProjectRoot { path, is_member } } - pub fn into_path(self) -> PathBuf { - self.path + pub fn path(&self) -> &PathBuf { + &self.path } pub fn is_member(&self) -> bool { self.is_member } + + pub fn include_dir(&self, dir_path: &RelativePath) -> bool { + const COMMON_IGNORED_DIRS: &[&str] = &["node_modules", "target", ".git"]; + const EXTERNAL_IGNORED_DIRS: &[&str] = &["examples", "tests", "benches"]; + + let is_ignored = if self.is_member { + dir_path.components().any(|c| COMMON_IGNORED_DIRS.contains(&c.as_str())) + } else { + dir_path.components().any(|c| { + let path = c.as_str(); + COMMON_IGNORED_DIRS.contains(&path) || EXTERNAL_IGNORED_DIRS.contains(&path) + }) + }; + + let hidden = dir_path.components().any(|c| c.as_str().starts_with(".")); + + !is_ignored && !hidden + } + + pub fn include_file(&self, file_path: &RelativePath) -> bool { + file_path.extension() == Some("rs") + } } impl ProjectWorkspace {