diff options
Diffstat (limited to 'crates/ra_project_model/src/cargo_workspace.rs')
-rw-r--r-- | crates/ra_project_model/src/cargo_workspace.rs | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 4b7444039..8ce63ab3c 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -1,14 +1,10 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use std::{ | 3 | use std::{ffi::OsStr, ops, path::Path, process::Command}; |
4 | ffi::OsStr, | ||
5 | ops, | ||
6 | path::{Path, PathBuf}, | ||
7 | process::Command, | ||
8 | }; | ||
9 | 4 | ||
10 | use anyhow::{Context, Result}; | 5 | use anyhow::{Context, Result}; |
11 | use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId}; | 6 | use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId}; |
7 | use paths::{AbsPath, AbsPathBuf}; | ||
12 | use ra_arena::{Arena, Idx}; | 8 | use ra_arena::{Arena, Idx}; |
13 | use ra_db::Edition; | 9 | use ra_db::Edition; |
14 | use rustc_hash::FxHashMap; | 10 | use rustc_hash::FxHashMap; |
@@ -20,11 +16,14 @@ use rustc_hash::FxHashMap; | |||
20 | /// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, | 16 | /// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, |
21 | /// while this knows about `Packages` & `Targets`: purely cargo-related | 17 | /// while this knows about `Packages` & `Targets`: purely cargo-related |
22 | /// concepts. | 18 | /// concepts. |
19 | /// | ||
20 | /// We use absolute paths here, `cargo metadata` guarantees to always produce | ||
21 | /// abs paths. | ||
23 | #[derive(Debug, Clone)] | 22 | #[derive(Debug, Clone)] |
24 | pub struct CargoWorkspace { | 23 | pub struct CargoWorkspace { |
25 | packages: Arena<PackageData>, | 24 | packages: Arena<PackageData>, |
26 | targets: Arena<TargetData>, | 25 | targets: Arena<TargetData>, |
27 | workspace_root: PathBuf, | 26 | workspace_root: AbsPathBuf, |
28 | } | 27 | } |
29 | 28 | ||
30 | impl ops::Index<Package> for CargoWorkspace { | 29 | impl ops::Index<Package> for CargoWorkspace { |
@@ -80,15 +79,15 @@ pub type Target = Idx<TargetData>; | |||
80 | pub struct PackageData { | 79 | pub struct PackageData { |
81 | pub version: String, | 80 | pub version: String, |
82 | pub name: String, | 81 | pub name: String, |
83 | pub manifest: PathBuf, | 82 | pub manifest: AbsPathBuf, |
84 | pub targets: Vec<Target>, | 83 | pub targets: Vec<Target>, |
85 | pub is_member: bool, | 84 | pub is_member: bool, |
86 | pub dependencies: Vec<PackageDependency>, | 85 | pub dependencies: Vec<PackageDependency>, |
87 | pub edition: Edition, | 86 | pub edition: Edition, |
88 | pub features: Vec<String>, | 87 | pub features: Vec<String>, |
89 | pub cfgs: Vec<String>, | 88 | pub cfgs: Vec<String>, |
90 | pub out_dir: Option<PathBuf>, | 89 | pub out_dir: Option<AbsPathBuf>, |
91 | pub proc_macro_dylib_path: Option<PathBuf>, | 90 | pub proc_macro_dylib_path: Option<AbsPathBuf>, |
92 | } | 91 | } |
93 | 92 | ||
94 | #[derive(Debug, Clone)] | 93 | #[derive(Debug, Clone)] |
@@ -101,7 +100,7 @@ pub struct PackageDependency { | |||
101 | pub struct TargetData { | 100 | pub struct TargetData { |
102 | pub package: Package, | 101 | pub package: Package, |
103 | pub name: String, | 102 | pub name: String, |
104 | pub root: PathBuf, | 103 | pub root: AbsPathBuf, |
105 | pub kind: TargetKind, | 104 | pub kind: TargetKind, |
106 | pub is_proc_macro: bool, | 105 | pub is_proc_macro: bool, |
107 | } | 106 | } |
@@ -135,7 +134,7 @@ impl TargetKind { | |||
135 | } | 134 | } |
136 | 135 | ||
137 | impl PackageData { | 136 | impl PackageData { |
138 | pub fn root(&self) -> &Path { | 137 | pub fn root(&self) -> &AbsPath { |
139 | self.manifest.parent().unwrap() | 138 | self.manifest.parent().unwrap() |
140 | } | 139 | } |
141 | } | 140 | } |
@@ -193,7 +192,7 @@ impl CargoWorkspace { | |||
193 | let pkg = packages.alloc(PackageData { | 192 | let pkg = packages.alloc(PackageData { |
194 | name, | 193 | name, |
195 | version: version.to_string(), | 194 | version: version.to_string(), |
196 | manifest: manifest_path, | 195 | manifest: AbsPathBuf::assert(manifest_path), |
197 | targets: Vec::new(), | 196 | targets: Vec::new(), |
198 | is_member, | 197 | is_member, |
199 | edition, | 198 | edition, |
@@ -210,7 +209,7 @@ impl CargoWorkspace { | |||
210 | let tgt = targets.alloc(TargetData { | 209 | let tgt = targets.alloc(TargetData { |
211 | package: pkg, | 210 | package: pkg, |
212 | name: meta_tgt.name, | 211 | name: meta_tgt.name, |
213 | root: meta_tgt.src_path.clone(), | 212 | root: AbsPathBuf::assert(meta_tgt.src_path.clone()), |
214 | kind: TargetKind::new(meta_tgt.kind.as_slice()), | 213 | kind: TargetKind::new(meta_tgt.kind.as_slice()), |
215 | is_proc_macro, | 214 | is_proc_macro, |
216 | }); | 215 | }); |
@@ -246,16 +245,17 @@ impl CargoWorkspace { | |||
246 | packages[source].features.extend(node.features); | 245 | packages[source].features.extend(node.features); |
247 | } | 246 | } |
248 | 247 | ||
249 | Ok(CargoWorkspace { packages, targets, workspace_root: meta.workspace_root }) | 248 | let workspace_root = AbsPathBuf::assert(meta.workspace_root); |
249 | Ok(CargoWorkspace { packages, targets, workspace_root: workspace_root }) | ||
250 | } | 250 | } |
251 | 251 | ||
252 | pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + ExactSizeIterator + 'a { | 252 | pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + ExactSizeIterator + 'a { |
253 | self.packages.iter().map(|(id, _pkg)| id) | 253 | self.packages.iter().map(|(id, _pkg)| id) |
254 | } | 254 | } |
255 | 255 | ||
256 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { | 256 | pub fn target_by_root(&self, root: &AbsPath) -> Option<Target> { |
257 | self.packages() | 257 | self.packages() |
258 | .filter_map(|pkg| self[pkg].targets.iter().find(|&&it| self[it].root == root)) | 258 | .filter_map(|pkg| self[pkg].targets.iter().find(|&&it| &self[it].root == root)) |
259 | .next() | 259 | .next() |
260 | .copied() | 260 | .copied() |
261 | } | 261 | } |
@@ -279,8 +279,8 @@ impl CargoWorkspace { | |||
279 | 279 | ||
280 | #[derive(Debug, Clone, Default)] | 280 | #[derive(Debug, Clone, Default)] |
281 | pub struct ExternResources { | 281 | pub struct ExternResources { |
282 | out_dirs: FxHashMap<PackageId, PathBuf>, | 282 | out_dirs: FxHashMap<PackageId, AbsPathBuf>, |
283 | proc_dylib_paths: FxHashMap<PackageId, PathBuf>, | 283 | proc_dylib_paths: FxHashMap<PackageId, AbsPathBuf>, |
284 | cfgs: FxHashMap<PackageId, Vec<String>>, | 284 | cfgs: FxHashMap<PackageId, Vec<String>>, |
285 | } | 285 | } |
286 | 286 | ||
@@ -308,6 +308,7 @@ pub fn load_extern_resources( | |||
308 | if let Ok(message) = message { | 308 | if let Ok(message) = message { |
309 | match message { | 309 | match message { |
310 | Message::BuildScriptExecuted(BuildScript { package_id, out_dir, cfgs, .. }) => { | 310 | Message::BuildScriptExecuted(BuildScript { package_id, out_dir, cfgs, .. }) => { |
311 | let out_dir = AbsPathBuf::assert(out_dir); | ||
311 | res.out_dirs.insert(package_id.clone(), out_dir); | 312 | res.out_dirs.insert(package_id.clone(), out_dir); |
312 | res.cfgs.insert(package_id, cfgs); | 313 | res.cfgs.insert(package_id, cfgs); |
313 | } | 314 | } |
@@ -317,7 +318,8 @@ pub fn load_extern_resources( | |||
317 | // Skip rmeta file | 318 | // Skip rmeta file |
318 | if let Some(filename) = message.filenames.iter().find(|name| is_dylib(name)) | 319 | if let Some(filename) = message.filenames.iter().find(|name| is_dylib(name)) |
319 | { | 320 | { |
320 | res.proc_dylib_paths.insert(package_id, filename.clone()); | 321 | let filename = AbsPathBuf::assert(filename.clone()); |
322 | res.proc_dylib_paths.insert(package_id, filename); | ||
321 | } | 323 | } |
322 | } | 324 | } |
323 | } | 325 | } |