diff options
Diffstat (limited to 'crates/ra_project_model/src/lib.rs')
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index c566ec0fb..6f46a2d43 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}; | |||
15 | 15 | ||
16 | use serde_json::from_reader; | 16 | use serde_json::from_reader; |
17 | 17 | ||
18 | use relative_path::RelativePath; | ||
19 | |||
18 | pub use crate::{ | 20 | pub use crate::{ |
19 | cargo_workspace::{CargoWorkspace, Package, Target, TargetKind}, | 21 | cargo_workspace::{CargoWorkspace, Package, Target, TargetKind}, |
20 | json_project::JsonProject, | 22 | json_project::JsonProject, |
@@ -32,6 +34,52 @@ pub enum ProjectWorkspace { | |||
32 | Json { project: JsonProject }, | 34 | Json { project: JsonProject }, |
33 | } | 35 | } |
34 | 36 | ||
37 | /// `ProjectRoot` describes a workspace root folder. | ||
38 | /// Which may be an external dependency, or a member of | ||
39 | /// the current workspace. | ||
40 | pub struct ProjectRoot { | ||
41 | /// Path to the root folder | ||
42 | path: PathBuf, | ||
43 | /// Is a member of the current workspace | ||
44 | is_member: bool, | ||
45 | } | ||
46 | |||
47 | impl ProjectRoot { | ||
48 | pub fn new(path: PathBuf, is_member: bool) -> ProjectRoot { | ||
49 | ProjectRoot { path, is_member } | ||
50 | } | ||
51 | |||
52 | pub fn path(&self) -> &PathBuf { | ||
53 | &self.path | ||
54 | } | ||
55 | |||
56 | pub fn is_member(&self) -> bool { | ||
57 | self.is_member | ||
58 | } | ||
59 | |||
60 | pub fn include_dir(&self, dir_path: &RelativePath) -> bool { | ||
61 | const COMMON_IGNORED_DIRS: &[&str] = &["node_modules", "target", ".git"]; | ||
62 | const EXTERNAL_IGNORED_DIRS: &[&str] = &["examples", "tests", "benches"]; | ||
63 | |||
64 | let is_ignored = if self.is_member { | ||
65 | dir_path.components().any(|c| COMMON_IGNORED_DIRS.contains(&c.as_str())) | ||
66 | } else { | ||
67 | dir_path.components().any(|c| { | ||
68 | let path = c.as_str(); | ||
69 | COMMON_IGNORED_DIRS.contains(&path) || EXTERNAL_IGNORED_DIRS.contains(&path) | ||
70 | }) | ||
71 | }; | ||
72 | |||
73 | let hidden = dir_path.components().any(|c| c.as_str().starts_with(".")); | ||
74 | |||
75 | !is_ignored && !hidden | ||
76 | } | ||
77 | |||
78 | pub fn include_file(&self, file_path: &RelativePath) -> bool { | ||
79 | file_path.extension() == Some("rs") | ||
80 | } | ||
81 | } | ||
82 | |||
35 | impl ProjectWorkspace { | 83 | impl ProjectWorkspace { |
36 | pub fn discover(path: &Path) -> Result<ProjectWorkspace> { | 84 | pub fn discover(path: &Path) -> Result<ProjectWorkspace> { |
37 | match find_rust_project_json(path) { | 85 | match find_rust_project_json(path) { |
@@ -50,12 +98,15 @@ impl ProjectWorkspace { | |||
50 | } | 98 | } |
51 | } | 99 | } |
52 | 100 | ||
53 | pub fn to_roots(&self) -> Vec<PathBuf> { | 101 | /// Returns the roots for the current ProjectWorkspace |
102 | /// The return type contains the path and whether or not | ||
103 | /// the root is a member of the current workspace | ||
104 | pub fn to_roots(&self) -> Vec<ProjectRoot> { | ||
54 | match self { | 105 | match self { |
55 | ProjectWorkspace::Json { project } => { | 106 | ProjectWorkspace::Json { project } => { |
56 | let mut roots = Vec::with_capacity(project.roots.len()); | 107 | let mut roots = Vec::with_capacity(project.roots.len()); |
57 | for root in &project.roots { | 108 | for root in &project.roots { |
58 | roots.push(root.path.clone()); | 109 | roots.push(ProjectRoot::new(root.path.clone(), true)); |
59 | } | 110 | } |
60 | roots | 111 | roots |
61 | } | 112 | } |
@@ -63,10 +114,12 @@ impl ProjectWorkspace { | |||
63 | let mut roots = | 114 | let mut roots = |
64 | Vec::with_capacity(cargo.packages().count() + sysroot.crates().count()); | 115 | Vec::with_capacity(cargo.packages().count() + sysroot.crates().count()); |
65 | for pkg in cargo.packages() { | 116 | for pkg in cargo.packages() { |
66 | roots.push(pkg.root(&cargo).to_path_buf()); | 117 | let root = pkg.root(&cargo).to_path_buf(); |
118 | let member = pkg.is_member(&cargo); | ||
119 | roots.push(ProjectRoot::new(root, member)); | ||
67 | } | 120 | } |
68 | for krate in sysroot.crates() { | 121 | for krate in sysroot.crates() { |
69 | roots.push(krate.root_dir(&sysroot).to_path_buf()) | 122 | roots.push(ProjectRoot::new(krate.root_dir(&sysroot).to_path_buf(), false)) |
70 | } | 123 | } |
71 | roots | 124 | roots |
72 | } | 125 | } |