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.rs54
1 files changed, 25 insertions, 29 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 47fa34ddf..9541362f5 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -29,13 +29,7 @@ pub enum ProjectWorkspace {
29 /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. 29 /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
30 Cargo { cargo: CargoWorkspace, sysroot: Sysroot }, 30 Cargo { cargo: CargoWorkspace, sysroot: Sysroot },
31 /// Project workspace was manually specified using a `rust-project.json` file. 31 /// Project workspace was manually specified using a `rust-project.json` file.
32 Json { project: JsonProject }, 32 Json { project: JsonProject, project_location: PathBuf },
33}
34
35impl From<JsonProject> for ProjectWorkspace {
36 fn from(project: JsonProject) -> ProjectWorkspace {
37 ProjectWorkspace::Json { project }
38 }
39} 33}
40 34
41/// `PackageRoot` describes a package root folder. 35/// `PackageRoot` describes a package root folder.
@@ -47,17 +41,21 @@ pub struct PackageRoot {
47 path: PathBuf, 41 path: PathBuf,
48 /// Is a member of the current workspace 42 /// Is a member of the current workspace
49 is_member: bool, 43 is_member: bool,
44 out_dir: Option<PathBuf>,
50} 45}
51impl PackageRoot { 46impl PackageRoot {
52 pub fn new_member(path: PathBuf) -> PackageRoot { 47 pub fn new_member(path: PathBuf) -> PackageRoot {
53 Self { path, is_member: true } 48 Self { path, is_member: true, out_dir: None }
54 } 49 }
55 pub fn new_non_member(path: PathBuf) -> PackageRoot { 50 pub fn new_non_member(path: PathBuf) -> PackageRoot {
56 Self { path, is_member: false } 51 Self { path, is_member: false, out_dir: None }
57 } 52 }
58 pub fn path(&self) -> &Path { 53 pub fn path(&self) -> &Path {
59 &self.path 54 &self.path
60 } 55 }
56 pub fn out_dir(&self) -> Option<&Path> {
57 self.out_dir.as_deref()
58 }
61 pub fn is_member(&self) -> bool { 59 pub fn is_member(&self) -> bool {
62 self.is_member 60 self.is_member
63 } 61 }
@@ -160,10 +158,15 @@ impl ProjectWorkspace {
160 format!("Failed to open json file {}", project_json.display()) 158 format!("Failed to open json file {}", project_json.display())
161 })?; 159 })?;
162 let reader = BufReader::new(file); 160 let reader = BufReader::new(file);
161 let project_location = match project_json.parent() {
162 Some(parent) => PathBuf::from(parent),
163 None => PathBuf::new(),
164 };
163 ProjectWorkspace::Json { 165 ProjectWorkspace::Json {
164 project: from_reader(reader).with_context(|| { 166 project: from_reader(reader).with_context(|| {
165 format!("Failed to deserialize json file {}", project_json.display()) 167 format!("Failed to deserialize json file {}", project_json.display())
166 })?, 168 })?,
169 project_location: project_location,
167 } 170 }
168 } 171 }
169 ProjectManifest::CargoToml(cargo_toml) => { 172 ProjectManifest::CargoToml(cargo_toml) => {
@@ -196,14 +199,17 @@ impl ProjectWorkspace {
196 /// the root is a member of the current workspace 199 /// the root is a member of the current workspace
197 pub fn to_roots(&self) -> Vec<PackageRoot> { 200 pub fn to_roots(&self) -> Vec<PackageRoot> {
198 match self { 201 match self {
199 ProjectWorkspace::Json { project } => { 202 ProjectWorkspace::Json { project, project_location } => project
200 project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect() 203 .roots
201 } 204 .iter()
205 .map(|r| PackageRoot::new_member(project_location.join(&r.path)))
206 .collect(),
202 ProjectWorkspace::Cargo { cargo, sysroot } => cargo 207 ProjectWorkspace::Cargo { cargo, sysroot } => cargo
203 .packages() 208 .packages()
204 .map(|pkg| PackageRoot { 209 .map(|pkg| PackageRoot {
205 path: cargo[pkg].root().to_path_buf(), 210 path: cargo[pkg].root().to_path_buf(),
206 is_member: cargo[pkg].is_member, 211 is_member: cargo[pkg].is_member,
212 out_dir: cargo[pkg].out_dir.clone(),
207 }) 213 })
208 .chain(sysroot.crates().map(|krate| { 214 .chain(sysroot.crates().map(|krate| {
209 PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf()) 215 PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf())
@@ -212,20 +218,9 @@ impl ProjectWorkspace {
212 } 218 }
213 } 219 }
214 220
215 pub fn out_dirs(&self) -> Vec<PathBuf> {
216 match self {
217 ProjectWorkspace::Json { project } => {
218 project.crates.iter().filter_map(|krate| krate.out_dir.as_ref()).cloned().collect()
219 }
220 ProjectWorkspace::Cargo { cargo, sysroot: _ } => {
221 cargo.packages().filter_map(|pkg| cargo[pkg].out_dir.as_ref()).cloned().collect()
222 }
223 }
224 }
225
226 pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> { 221 pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> {
227 match self { 222 match self {
228 ProjectWorkspace::Json { project } => project 223 ProjectWorkspace::Json { project, .. } => project
229 .crates 224 .crates
230 .iter() 225 .iter()
231 .filter_map(|krate| krate.proc_macro_dylib_path.as_ref()) 226 .filter_map(|krate| krate.proc_macro_dylib_path.as_ref())
@@ -241,7 +236,7 @@ impl ProjectWorkspace {
241 236
242 pub fn n_packages(&self) -> usize { 237 pub fn n_packages(&self) -> usize {
243 match self { 238 match self {
244 ProjectWorkspace::Json { project } => project.crates.len(), 239 ProjectWorkspace::Json { project, .. } => project.crates.len(),
245 ProjectWorkspace::Cargo { cargo, sysroot } => { 240 ProjectWorkspace::Cargo { cargo, sysroot } => {
246 cargo.packages().len() + sysroot.crates().len() 241 cargo.packages().len() + sysroot.crates().len()
247 } 242 }
@@ -257,13 +252,14 @@ impl ProjectWorkspace {
257 ) -> CrateGraph { 252 ) -> CrateGraph {
258 let mut crate_graph = CrateGraph::default(); 253 let mut crate_graph = CrateGraph::default();
259 match self { 254 match self {
260 ProjectWorkspace::Json { project } => { 255 ProjectWorkspace::Json { project, project_location } => {
261 let crates: FxHashMap<_, _> = project 256 let crates: FxHashMap<_, _> = project
262 .crates 257 .crates
263 .iter() 258 .iter()
264 .enumerate() 259 .enumerate()
265 .filter_map(|(seq_index, krate)| { 260 .filter_map(|(seq_index, krate)| {
266 let file_id = load(&krate.root_module)?; 261 let file_path = project_location.join(&krate.root_module);
262 let file_id = load(&file_path)?;
267 let edition = match krate.edition { 263 let edition = match krate.edition {
268 json_project::Edition::Edition2015 => Edition::Edition2015, 264 json_project::Edition::Edition2015 => Edition::Edition2015,
269 json_project::Edition::Edition2018 => Edition::Edition2018, 265 json_project::Edition::Edition2018 => Edition::Edition2018,
@@ -546,7 +542,7 @@ impl ProjectWorkspace {
546 ProjectWorkspace::Cargo { cargo, .. } => { 542 ProjectWorkspace::Cargo { cargo, .. } => {
547 Some(cargo.workspace_root()).filter(|root| path.starts_with(root)) 543 Some(cargo.workspace_root()).filter(|root| path.starts_with(root))
548 } 544 }
549 ProjectWorkspace::Json { project: JsonProject { roots, .. } } => roots 545 ProjectWorkspace::Json { project: JsonProject { roots, .. }, .. } => roots
550 .iter() 546 .iter()
551 .find(|root| path.starts_with(&root.path)) 547 .find(|root| path.starts_with(&root.path))
552 .map(|root| root.path.as_ref()), 548 .map(|root| root.path.as_ref()),
@@ -594,7 +590,7 @@ fn get_rustc_cfg_options(target: Option<&str>) -> CfgOptions {
594 Err(e) => log::error!("failed to get rustc cfgs: {:#}", e), 590 Err(e) => log::error!("failed to get rustc cfgs: {:#}", e),
595 } 591 }
596 592
597 cfg_options.insert_atom("debug_assertion".into()); 593 cfg_options.insert_atom("debug_assertions".into());
598 594
599 cfg_options 595 cfg_options
600} 596}