about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2020-07-21 12:52:51 +0200
committerAleksey Kladov <aleksey.kladov@gmail.com>2020-07-21 12:52:51 +0200
commit39a2bc5e3cd86876eef6f3a96bef188f88e85114 (patch)
tree6e655b139235d23c7640e404a10eb543ef85caac
parent818aeb8a242bba5d8947ce2960e1af27d998f4fc (diff)
downloadrust-39a2bc5e3cd86876eef6f3a96bef188f88e85114.tar.gz
rust-39a2bc5e3cd86876eef6f3a96bef188f88e85114.zip
Expose package roots more directly
-rw-r--r--crates/ra_project_model/src/lib.rs62
-rw-r--r--crates/rust-analyzer/src/reload.rs40
-rw-r--r--crates/vfs/src/loader.rs2
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 b9c5424bf0e..cf46048e50d 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<AbsPathBuf>,
-}
-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<AbsPathBuf>,
+    pub exclude: Vec<AbsPathBuf>,
 }
 
 #[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<PackageRoot> {
         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 d7ae00b073b..1907f2f132d 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<VfsPath> = vec![];
+            let file_set_roots: Vec<VfsPath> =
+                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 04e257f53f8..40cf9602083 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<String>,
     pub include: Vec<AbsPathBuf>,