aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_project_model/src/lib.rs')
-rw-r--r--crates/ra_project_model/src/lib.rs87
1 files changed, 36 insertions, 51 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index b9c5424bf..6da4d7928 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -7,7 +7,6 @@ mod sysroot;
7use std::{ 7use std::{
8 fs::{self, read_dir, ReadDir}, 8 fs::{self, read_dir, ReadDir},
9 io, 9 io,
10 path::Path,
11 process::{Command, Output}, 10 process::{Command, Output},
12}; 11};
13 12
@@ -35,30 +34,12 @@ pub enum ProjectWorkspace {
35/// `PackageRoot` describes a package root folder. 34/// `PackageRoot` describes a package root folder.
36/// Which may be an external dependency, or a member of 35/// Which may be an external dependency, or a member of
37/// the current workspace. 36/// the current workspace.
38#[derive(Debug, Clone)] 37#[derive(Debug, Clone, Eq, PartialEq, Hash)]
39pub struct PackageRoot { 38pub struct PackageRoot {
40 /// Path to the root folder
41 path: AbsPathBuf,
42 /// Is a member of the current workspace 39 /// Is a member of the current workspace
43 is_member: bool, 40 pub is_member: bool,
44 out_dir: Option<AbsPathBuf>, 41 pub include: Vec<AbsPathBuf>,
45} 42 pub exclude: Vec<AbsPathBuf>,
46impl PackageRoot {
47 pub fn new_member(path: AbsPathBuf) -> PackageRoot {
48 Self { path, is_member: true, out_dir: None }
49 }
50 pub fn new_non_member(path: AbsPathBuf) -> PackageRoot {
51 Self { path, is_member: false, out_dir: None }
52 }
53 pub fn path(&self) -> &AbsPath {
54 &self.path
55 }
56 pub fn out_dir(&self) -> Option<&AbsPath> {
57 self.out_dir.as_deref()
58 }
59 pub fn is_member(&self) -> bool {
60 self.is_member
61 }
62} 43}
63 44
64#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] 45#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
@@ -195,18 +176,40 @@ impl ProjectWorkspace {
195 /// the root is a member of the current workspace 176 /// the root is a member of the current workspace
196 pub fn to_roots(&self) -> Vec<PackageRoot> { 177 pub fn to_roots(&self) -> Vec<PackageRoot> {
197 match self { 178 match self {
198 ProjectWorkspace::Json { project } => { 179 ProjectWorkspace::Json { project } => project
199 project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect() 180 .crates
200 } 181 .iter()
182 .map(|krate| PackageRoot {
183 is_member: krate.is_workspace_member,
184 include: krate.include.clone(),
185 exclude: krate.exclude.clone(),
186 })
187 .collect::<FxHashSet<_>>()
188 .into_iter()
189 .collect::<Vec<_>>(),
201 ProjectWorkspace::Cargo { cargo, sysroot } => cargo 190 ProjectWorkspace::Cargo { cargo, sysroot } => cargo
202 .packages() 191 .packages()
203 .map(|pkg| PackageRoot { 192 .map(|pkg| {
204 path: cargo[pkg].root().to_path_buf(), 193 let is_member = cargo[pkg].is_member;
205 is_member: cargo[pkg].is_member, 194 let pkg_root = cargo[pkg].root().to_path_buf();
206 out_dir: cargo[pkg].out_dir.clone(), 195
196 let mut include = vec![pkg_root.clone()];
197 include.extend(cargo[pkg].out_dir.clone());
198
199 let mut exclude = vec![pkg_root.join(".git")];
200 if is_member {
201 exclude.push(pkg_root.join("target"));
202 } else {
203 exclude.push(pkg_root.join("tests"));
204 exclude.push(pkg_root.join("examples"));
205 exclude.push(pkg_root.join("benches"));
206 }
207 PackageRoot { is_member, include, exclude }
207 }) 208 })
208 .chain(sysroot.crates().map(|krate| { 209 .chain(sysroot.crates().map(|krate| PackageRoot {
209 PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf()) 210 is_member: false,
211 include: vec![sysroot[krate].root_dir().to_path_buf()],
212 exclude: Vec::new(),
210 })) 213 }))
211 .collect(), 214 .collect(),
212 } 215 }
@@ -255,13 +258,7 @@ impl ProjectWorkspace {
255 let file_path = &krate.root_module; 258 let file_path = &krate.root_module;
256 let file_id = load(&file_path)?; 259 let file_id = load(&file_path)?;
257 260
258 let mut env = Env::default(); 261 let env = krate.env.clone().into_iter().collect();
259 if let Some(out_dir) = &krate.out_dir {
260 // NOTE: cargo and rustc seem to hide non-UTF-8 strings from env! and option_env!()
261 if let Some(out_dir) = out_dir.to_str().map(|s| s.to_owned()) {
262 env.set("OUT_DIR", out_dir);
263 }
264 }
265 let proc_macro = krate 262 let proc_macro = krate
266 .proc_macro_dylib_path 263 .proc_macro_dylib_path
267 .clone() 264 .clone()
@@ -503,18 +500,6 @@ impl ProjectWorkspace {
503 } 500 }
504 crate_graph 501 crate_graph
505 } 502 }
506
507 pub fn workspace_root_for(&self, path: &Path) -> Option<&AbsPath> {
508 match self {
509 ProjectWorkspace::Cargo { cargo, .. } => {
510 Some(cargo.workspace_root()).filter(|root| path.starts_with(root))
511 }
512 ProjectWorkspace::Json { project: ProjectJson { roots, .. }, .. } => roots
513 .iter()
514 .find(|root| path.starts_with(&root.path))
515 .map(|root| root.path.as_path()),
516 }
517 }
518} 503}
519 504
520fn get_rustc_cfg_options(target: Option<&str>) -> CfgOptions { 505fn get_rustc_cfg_options(target: Option<&str>) -> CfgOptions {