diff options
Diffstat (limited to 'crates/ra_project_model/src/lib.rs')
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 135 |
1 files changed, 57 insertions, 78 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 444d3bb3f..0ab64a1e0 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -19,7 +19,7 @@ use rustc_hash::FxHashMap; | |||
19 | use serde_json::from_reader; | 19 | use serde_json::from_reader; |
20 | 20 | ||
21 | pub use crate::{ | 21 | pub use crate::{ |
22 | cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, | 22 | cargo_workspace::{CargoConfig, CargoWorkspace, Package, Target, TargetKind}, |
23 | json_project::JsonProject, | 23 | json_project::JsonProject, |
24 | sysroot::Sysroot, | 24 | sysroot::Sysroot, |
25 | }; | 25 | }; |
@@ -62,30 +62,30 @@ pub struct PackageRoot { | |||
62 | /// Is a member of the current workspace | 62 | /// Is a member of the current workspace |
63 | is_member: bool, | 63 | is_member: bool, |
64 | } | 64 | } |
65 | |||
66 | impl PackageRoot { | 65 | impl PackageRoot { |
67 | pub fn new(path: PathBuf, is_member: bool) -> PackageRoot { | 66 | pub fn new_member(path: PathBuf) -> PackageRoot { |
68 | PackageRoot { path, is_member } | 67 | Self { path, is_member: true } |
69 | } | 68 | } |
70 | 69 | pub fn new_non_member(path: PathBuf) -> PackageRoot { | |
71 | pub fn path(&self) -> &PathBuf { | 70 | Self { path, is_member: false } |
71 | } | ||
72 | pub fn path(&self) -> &Path { | ||
72 | &self.path | 73 | &self.path |
73 | } | 74 | } |
74 | |||
75 | pub fn is_member(&self) -> bool { | 75 | pub fn is_member(&self) -> bool { |
76 | self.is_member | 76 | self.is_member |
77 | } | 77 | } |
78 | } | 78 | } |
79 | 79 | ||
80 | impl ProjectWorkspace { | 80 | impl ProjectWorkspace { |
81 | pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result<ProjectWorkspace> { | 81 | pub fn discover(path: &Path, cargo_features: &CargoConfig) -> Result<ProjectWorkspace> { |
82 | ProjectWorkspace::discover_with_sysroot(path, true, cargo_features) | 82 | ProjectWorkspace::discover_with_sysroot(path, true, cargo_features) |
83 | } | 83 | } |
84 | 84 | ||
85 | pub fn discover_with_sysroot( | 85 | pub fn discover_with_sysroot( |
86 | path: &Path, | 86 | path: &Path, |
87 | with_sysroot: bool, | 87 | with_sysroot: bool, |
88 | cargo_features: &CargoFeatures, | 88 | cargo_features: &CargoConfig, |
89 | ) -> Result<ProjectWorkspace> { | 89 | ) -> Result<ProjectWorkspace> { |
90 | match find_rust_project_json(path) { | 90 | match find_rust_project_json(path) { |
91 | Some(json_path) => { | 91 | Some(json_path) => { |
@@ -130,70 +130,45 @@ impl ProjectWorkspace { | |||
130 | pub fn to_roots(&self) -> Vec<PackageRoot> { | 130 | pub fn to_roots(&self) -> Vec<PackageRoot> { |
131 | match self { | 131 | match self { |
132 | ProjectWorkspace::Json { project } => { | 132 | ProjectWorkspace::Json { project } => { |
133 | let mut roots = Vec::with_capacity(project.roots.len()); | 133 | project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect() |
134 | for root in &project.roots { | ||
135 | roots.push(PackageRoot::new(root.path.clone(), true)); | ||
136 | } | ||
137 | roots | ||
138 | } | ||
139 | ProjectWorkspace::Cargo { cargo, sysroot } => { | ||
140 | let mut roots = Vec::with_capacity(cargo.packages().len() + sysroot.crates().len()); | ||
141 | for pkg in cargo.packages() { | ||
142 | let root = cargo[pkg].root().to_path_buf(); | ||
143 | let member = cargo[pkg].is_member; | ||
144 | roots.push(PackageRoot::new(root, member)); | ||
145 | } | ||
146 | for krate in sysroot.crates() { | ||
147 | roots.push(PackageRoot::new(sysroot[krate].root_dir().to_path_buf(), false)) | ||
148 | } | ||
149 | roots | ||
150 | } | 134 | } |
135 | ProjectWorkspace::Cargo { cargo, sysroot } => cargo | ||
136 | .packages() | ||
137 | .map(|pkg| PackageRoot { | ||
138 | path: cargo[pkg].root().to_path_buf(), | ||
139 | is_member: cargo[pkg].is_member, | ||
140 | }) | ||
141 | .chain(sysroot.crates().map(|krate| { | ||
142 | PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf()) | ||
143 | })) | ||
144 | .collect(), | ||
151 | } | 145 | } |
152 | } | 146 | } |
153 | 147 | ||
154 | pub fn out_dirs(&self) -> Vec<PathBuf> { | 148 | pub fn out_dirs(&self) -> Vec<PathBuf> { |
155 | match self { | 149 | match self { |
156 | ProjectWorkspace::Json { project } => { | 150 | ProjectWorkspace::Json { project } => { |
157 | let mut out_dirs = Vec::with_capacity(project.crates.len()); | 151 | project.crates.iter().filter_map(|krate| krate.out_dir.as_ref()).cloned().collect() |
158 | for krate in &project.crates { | ||
159 | if let Some(out_dir) = &krate.out_dir { | ||
160 | out_dirs.push(out_dir.to_path_buf()); | ||
161 | } | ||
162 | } | ||
163 | out_dirs | ||
164 | } | 152 | } |
165 | ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => { | 153 | ProjectWorkspace::Cargo { cargo, sysroot: _ } => { |
166 | let mut out_dirs = Vec::with_capacity(cargo.packages().len()); | 154 | cargo.packages().filter_map(|pkg| cargo[pkg].out_dir.as_ref()).cloned().collect() |
167 | for pkg in cargo.packages() { | ||
168 | if let Some(out_dir) = &cargo[pkg].out_dir { | ||
169 | out_dirs.push(out_dir.to_path_buf()); | ||
170 | } | ||
171 | } | ||
172 | out_dirs | ||
173 | } | 155 | } |
174 | } | 156 | } |
175 | } | 157 | } |
176 | 158 | ||
177 | pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> { | 159 | pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> { |
178 | match self { | 160 | match self { |
179 | ProjectWorkspace::Json { project } => { | 161 | ProjectWorkspace::Json { project } => project |
180 | let mut proc_macro_dylib_paths = Vec::with_capacity(project.crates.len()); | 162 | .crates |
181 | for krate in &project.crates { | 163 | .iter() |
182 | if let Some(out_dir) = &krate.proc_macro_dylib_path { | 164 | .filter_map(|krate| krate.proc_macro_dylib_path.as_ref()) |
183 | proc_macro_dylib_paths.push(out_dir.to_path_buf()); | 165 | .cloned() |
184 | } | 166 | .collect(), |
185 | } | 167 | ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => cargo |
186 | proc_macro_dylib_paths | 168 | .packages() |
187 | } | 169 | .filter_map(|pkg| cargo[pkg].proc_macro_dylib_path.as_ref()) |
188 | ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => { | 170 | .cloned() |
189 | let mut proc_macro_dylib_paths = Vec::with_capacity(cargo.packages().len()); | 171 | .collect(), |
190 | for pkg in cargo.packages() { | ||
191 | if let Some(dylib_path) = &cargo[pkg].proc_macro_dylib_path { | ||
192 | proc_macro_dylib_paths.push(dylib_path.to_path_buf()); | ||
193 | } | ||
194 | } | ||
195 | proc_macro_dylib_paths | ||
196 | } | ||
197 | } | 172 | } |
198 | } | 173 | } |
199 | 174 | ||
@@ -216,10 +191,12 @@ impl ProjectWorkspace { | |||
216 | let mut crate_graph = CrateGraph::default(); | 191 | let mut crate_graph = CrateGraph::default(); |
217 | match self { | 192 | match self { |
218 | ProjectWorkspace::Json { project } => { | 193 | ProjectWorkspace::Json { project } => { |
219 | let mut crates = FxHashMap::default(); | 194 | let crates: FxHashMap<_, _> = project |
220 | for (id, krate) in project.crates.iter().enumerate() { | 195 | .crates |
221 | let crate_id = json_project::CrateId(id); | 196 | .iter() |
222 | if let Some(file_id) = load(&krate.root_module) { | 197 | .enumerate() |
198 | .filter_map(|(seq_index, krate)| { | ||
199 | let file_id = load(&krate.root_module)?; | ||
223 | let edition = match krate.edition { | 200 | let edition = match krate.edition { |
224 | json_project::Edition::Edition2015 => Edition::Edition2015, | 201 | json_project::Edition::Edition2015 => Edition::Edition2015, |
225 | json_project::Edition::Edition2018 => Edition::Edition2018, | 202 | json_project::Edition::Edition2018 => Edition::Edition2018, |
@@ -249,8 +226,8 @@ impl ProjectWorkspace { | |||
249 | .clone() | 226 | .clone() |
250 | .map(|it| proc_macro_client.by_dylib_path(&it)); | 227 | .map(|it| proc_macro_client.by_dylib_path(&it)); |
251 | // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env | 228 | // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env |
252 | crates.insert( | 229 | Some(( |
253 | crate_id, | 230 | json_project::CrateId(seq_index), |
254 | crate_graph.add_crate_root( | 231 | crate_graph.add_crate_root( |
255 | file_id, | 232 | file_id, |
256 | edition, | 233 | edition, |
@@ -261,9 +238,9 @@ impl ProjectWorkspace { | |||
261 | extern_source, | 238 | extern_source, |
262 | proc_macro.unwrap_or_default(), | 239 | proc_macro.unwrap_or_default(), |
263 | ), | 240 | ), |
264 | ); | 241 | )) |
265 | } | 242 | }) |
266 | } | 243 | .collect(); |
267 | 244 | ||
268 | for (id, krate) in project.crates.iter().enumerate() { | 245 | for (id, krate) in project.crates.iter().enumerate() { |
269 | for dep in &krate.deps { | 246 | for dep in &krate.deps { |
@@ -287,9 +264,11 @@ impl ProjectWorkspace { | |||
287 | } | 264 | } |
288 | } | 265 | } |
289 | ProjectWorkspace::Cargo { cargo, sysroot } => { | 266 | ProjectWorkspace::Cargo { cargo, sysroot } => { |
290 | let mut sysroot_crates = FxHashMap::default(); | 267 | let sysroot_crates: FxHashMap<_, _> = sysroot |
291 | for krate in sysroot.crates() { | 268 | .crates() |
292 | if let Some(file_id) = load(&sysroot[krate].root) { | 269 | .filter_map(|krate| { |
270 | let file_id = load(&sysroot[krate].root)?; | ||
271 | |||
293 | // Crates from sysroot have `cfg(test)` disabled | 272 | // Crates from sysroot have `cfg(test)` disabled |
294 | let cfg_options = { | 273 | let cfg_options = { |
295 | let mut opts = default_cfg_options.clone(); | 274 | let mut opts = default_cfg_options.clone(); |
@@ -300,22 +279,22 @@ impl ProjectWorkspace { | |||
300 | let env = Env::default(); | 279 | let env = Env::default(); |
301 | let extern_source = ExternSource::default(); | 280 | let extern_source = ExternSource::default(); |
302 | let proc_macro = vec![]; | 281 | let proc_macro = vec![]; |
282 | let crate_name = CrateName::new(&sysroot[krate].name) | ||
283 | .expect("Sysroot crate names should not contain dashes"); | ||
303 | 284 | ||
304 | let crate_id = crate_graph.add_crate_root( | 285 | let crate_id = crate_graph.add_crate_root( |
305 | file_id, | 286 | file_id, |
306 | Edition::Edition2018, | 287 | Edition::Edition2018, |
307 | Some( | 288 | Some(crate_name), |
308 | CrateName::new(&sysroot[krate].name) | ||
309 | .expect("Sysroot crate names should not contain dashes"), | ||
310 | ), | ||
311 | cfg_options, | 289 | cfg_options, |
312 | env, | 290 | env, |
313 | extern_source, | 291 | extern_source, |
314 | proc_macro, | 292 | proc_macro, |
315 | ); | 293 | ); |
316 | sysroot_crates.insert(krate, crate_id); | 294 | Some((krate, crate_id)) |
317 | } | 295 | }) |
318 | } | 296 | .collect(); |
297 | |||
319 | for from in sysroot.crates() { | 298 | for from in sysroot.crates() { |
320 | for &to in sysroot[from].deps.iter() { | 299 | for &to in sysroot[from].deps.iter() { |
321 | let name = &sysroot[to].name; | 300 | let name = &sysroot[to].name; |