From 39a2bc5e3cd86876eef6f3a96bef188f88e85114 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 21 Jul 2020 12:52:51 +0200 Subject: Expose package roots more directly --- crates/ra_project_model/src/lib.rs | 62 ++++++++++++++++++++------------------ crates/rust-analyzer/src/reload.rs | 40 +++++++++++------------- crates/vfs/src/loader.rs | 2 +- 3 files changed, 50 insertions(+), 54 deletions(-) diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index b9c5424bf..cf46048e5 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -37,28 +37,10 @@ pub enum ProjectWorkspace { /// the current workspace. #[derive(Debug, Clone)] pub struct PackageRoot { - /// Path to the root folder - path: AbsPathBuf, /// Is a member of the current workspace - is_member: bool, - out_dir: Option, -} -impl PackageRoot { - pub fn new_member(path: AbsPathBuf) -> PackageRoot { - Self { path, is_member: true, out_dir: None } - } - pub fn new_non_member(path: AbsPathBuf) -> PackageRoot { - Self { path, is_member: false, out_dir: None } - } - pub fn path(&self) -> &AbsPath { - &self.path - } - pub fn out_dir(&self) -> Option<&AbsPath> { - self.out_dir.as_deref() - } - pub fn is_member(&self) -> bool { - self.is_member - } + pub is_member: bool, + pub include: Vec, + pub exclude: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] @@ -195,18 +177,38 @@ impl ProjectWorkspace { /// the root is a member of the current workspace pub fn to_roots(&self) -> Vec { match self { - ProjectWorkspace::Json { project } => { - project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect() - } + ProjectWorkspace::Json { project } => project + .roots + .iter() + .map(|r| { + let path = r.path.clone(); + let include = vec![path]; + PackageRoot { is_member: true, include, exclude: Vec::new() } + }) + .collect(), ProjectWorkspace::Cargo { cargo, sysroot } => cargo .packages() - .map(|pkg| PackageRoot { - path: cargo[pkg].root().to_path_buf(), - is_member: cargo[pkg].is_member, - out_dir: cargo[pkg].out_dir.clone(), + .map(|pkg| { + let is_member = cargo[pkg].is_member; + let pkg_root = cargo[pkg].root().to_path_buf(); + + let mut include = vec![pkg_root.clone()]; + include.extend(cargo[pkg].out_dir.clone()); + + let mut exclude = vec![pkg_root.join(".git")]; + if is_member { + exclude.push(pkg_root.join("target")); + } else { + exclude.push(pkg_root.join("tests")); + exclude.push(pkg_root.join("examples")); + exclude.push(pkg_root.join("benches")); + } + PackageRoot { is_member, include, exclude } }) - .chain(sysroot.crates().map(|krate| { - PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf()) + .chain(sysroot.crates().map(|krate| PackageRoot { + is_member: false, + include: vec![sysroot[krate].root_dir().to_path_buf()], + exclude: Vec::new(), })) .collect(), } diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index d7ae00b07..1907f2f13 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -5,7 +5,7 @@ use flycheck::FlycheckHandle; use ra_db::{CrateGraph, SourceRoot, VfsPath}; use ra_ide::AnalysisChange; use ra_prof::profile; -use ra_project_model::{PackageRoot, ProcMacroClient, ProjectWorkspace}; +use ra_project_model::{ProcMacroClient, ProjectWorkspace}; use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; use crate::{ @@ -149,8 +149,10 @@ impl GlobalState { watchers: workspaces .iter() .flat_map(ProjectWorkspace::to_roots) - .filter(PackageRoot::is_member) - .map(|root| format!("{}/**/*.rs", root.path().display())) + .filter(|it| it.is_member) + .flat_map(|root| { + root.include.into_iter().map(|it| format!("{}/**/*.rs", it.display())) + }) .map(|glob_pattern| lsp_types::FileSystemWatcher { glob_pattern, kind: None }) .collect(), }; @@ -261,31 +263,23 @@ impl ProjectFolders { let mut local_filesets = vec![]; for root in workspaces.iter().flat_map(|it| it.to_roots()) { - let path = root.path().to_owned(); - - let mut file_set_roots: Vec = vec![]; + let file_set_roots: Vec = + root.include.iter().cloned().map(VfsPath::from).collect(); - let entry = if root.is_member() { - vfs::loader::Entry::local_cargo_package(path.to_path_buf()) - } else { - vfs::loader::Entry::cargo_package_dependency(path.to_path_buf()) + let entry = { + let mut dirs = vfs::loader::Directories::default(); + dirs.extensions.push("rs".into()); + dirs.include.extend(root.include); + dirs.exclude.extend(root.exclude); + vfs::loader::Entry::Directories(dirs) }; - res.load.push(entry); - if root.is_member() { - res.watch.push(res.load.len() - 1); - } - if let Some(out_dir) = root.out_dir() { - let out_dir = out_dir.to_path_buf(); - res.load.push(vfs::loader::Entry::rs_files_recursively(out_dir.clone())); - if root.is_member() { - res.watch.push(res.load.len() - 1); - } - file_set_roots.push(out_dir.into()); + if root.is_member { + res.watch.push(res.load.len()); } - file_set_roots.push(path.to_path_buf().into()); + res.load.push(entry); - if root.is_member() { + if root.is_member { local_filesets.push(fsc.len()); } fsc.add_file_set(file_set_roots) diff --git a/crates/vfs/src/loader.rs b/crates/vfs/src/loader.rs index 04e257f53..40cf96020 100644 --- a/crates/vfs/src/loader.rs +++ b/crates/vfs/src/loader.rs @@ -17,7 +17,7 @@ pub enum Entry { /// * it is not under `exclude` path /// /// If many include/exclude paths match, the longest one wins. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct Directories { pub extensions: Vec, pub include: Vec, -- cgit v1.2.3