diff options
Diffstat (limited to 'crates/ra_project_model/src/lib.rs')
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 5d3078598..640a5ebd3 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -9,8 +9,10 @@ use std::{ | |||
9 | fs::File, | 9 | fs::File, |
10 | io::BufReader, | 10 | io::BufReader, |
11 | path::{Path, PathBuf}, | 11 | path::{Path, PathBuf}, |
12 | process::Command, | ||
12 | }; | 13 | }; |
13 | 14 | ||
15 | use ra_cfg::CfgOptions; | ||
14 | use ra_db::{CrateGraph, CrateId, Edition, FileId}; | 16 | use ra_db::{CrateGraph, CrateId, Edition, FileId}; |
15 | use rustc_hash::FxHashMap; | 17 | use rustc_hash::FxHashMap; |
16 | use serde_json::from_reader; | 18 | use serde_json::from_reader; |
@@ -117,6 +119,7 @@ impl ProjectWorkspace { | |||
117 | 119 | ||
118 | pub fn to_crate_graph( | 120 | pub fn to_crate_graph( |
119 | &self, | 121 | &self, |
122 | default_cfg_options: &CfgOptions, | ||
120 | load: &mut dyn FnMut(&Path) -> Option<FileId>, | 123 | load: &mut dyn FnMut(&Path) -> Option<FileId>, |
121 | ) -> (CrateGraph, FxHashMap<CrateId, String>) { | 124 | ) -> (CrateGraph, FxHashMap<CrateId, String>) { |
122 | let mut crate_graph = CrateGraph::default(); | 125 | let mut crate_graph = CrateGraph::default(); |
@@ -131,7 +134,17 @@ impl ProjectWorkspace { | |||
131 | json_project::Edition::Edition2015 => Edition::Edition2015, | 134 | json_project::Edition::Edition2015 => Edition::Edition2015, |
132 | json_project::Edition::Edition2018 => Edition::Edition2018, | 135 | json_project::Edition::Edition2018 => Edition::Edition2018, |
133 | }; | 136 | }; |
134 | crates.insert(crate_id, crate_graph.add_crate_root(file_id, edition)); | 137 | let mut cfg_options = default_cfg_options.clone(); |
138 | for name in &krate.atom_cfgs { | ||
139 | cfg_options = cfg_options.atom(name.into()); | ||
140 | } | ||
141 | for (key, value) in &krate.key_value_cfgs { | ||
142 | cfg_options = cfg_options.key_value(key.into(), value.into()); | ||
143 | } | ||
144 | crates.insert( | ||
145 | crate_id, | ||
146 | crate_graph.add_crate_root(file_id, edition, cfg_options), | ||
147 | ); | ||
135 | } | 148 | } |
136 | } | 149 | } |
137 | 150 | ||
@@ -157,7 +170,10 @@ impl ProjectWorkspace { | |||
157 | let mut sysroot_crates = FxHashMap::default(); | 170 | let mut sysroot_crates = FxHashMap::default(); |
158 | for krate in sysroot.crates() { | 171 | for krate in sysroot.crates() { |
159 | if let Some(file_id) = load(krate.root(&sysroot)) { | 172 | if let Some(file_id) = load(krate.root(&sysroot)) { |
160 | let crate_id = crate_graph.add_crate_root(file_id, Edition::Edition2018); | 173 | // Crates from sysroot have `cfg(test)` disabled |
174 | let cfg_options = default_cfg_options.clone().remove_atom(&"test".into()); | ||
175 | let crate_id = | ||
176 | crate_graph.add_crate_root(file_id, Edition::Edition2018, cfg_options); | ||
161 | sysroot_crates.insert(krate, crate_id); | 177 | sysroot_crates.insert(krate, crate_id); |
162 | names.insert(crate_id, krate.name(&sysroot).to_string()); | 178 | names.insert(crate_id, krate.name(&sysroot).to_string()); |
163 | } | 179 | } |
@@ -186,7 +202,11 @@ impl ProjectWorkspace { | |||
186 | let root = tgt.root(&cargo); | 202 | let root = tgt.root(&cargo); |
187 | if let Some(file_id) = load(root) { | 203 | if let Some(file_id) = load(root) { |
188 | let edition = pkg.edition(&cargo); | 204 | let edition = pkg.edition(&cargo); |
189 | let crate_id = crate_graph.add_crate_root(file_id, edition); | 205 | let cfg_options = default_cfg_options |
206 | .clone() | ||
207 | .features(pkg.features(&cargo).iter().map(Into::into)); | ||
208 | let crate_id = | ||
209 | crate_graph.add_crate_root(file_id, edition, cfg_options); | ||
190 | names.insert(crate_id, pkg.name(&cargo).to_string()); | 210 | names.insert(crate_id, pkg.name(&cargo).to_string()); |
191 | if tgt.kind(&cargo) == TargetKind::Lib { | 211 | if tgt.kind(&cargo) == TargetKind::Lib { |
192 | lib_tgt = Some(crate_id); | 212 | lib_tgt = Some(crate_id); |
@@ -286,3 +306,32 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf> { | |||
286 | } | 306 | } |
287 | Err(format!("can't find Cargo.toml at {}", path.display()))? | 307 | Err(format!("can't find Cargo.toml at {}", path.display()))? |
288 | } | 308 | } |
309 | |||
310 | pub fn get_rustc_cfg_options() -> CfgOptions { | ||
311 | let mut cfg_options = CfgOptions::default(); | ||
312 | |||
313 | match (|| -> Result<_> { | ||
314 | // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. | ||
315 | let output = Command::new("rustc").args(&["--print", "cfg", "-O"]).output()?; | ||
316 | if !output.status.success() { | ||
317 | Err("failed to get rustc cfgs")?; | ||
318 | } | ||
319 | Ok(String::from_utf8(output.stdout)?) | ||
320 | })() { | ||
321 | Ok(rustc_cfgs) => { | ||
322 | for line in rustc_cfgs.lines() { | ||
323 | match line.find('=') { | ||
324 | None => cfg_options = cfg_options.atom(line.into()), | ||
325 | Some(pos) => { | ||
326 | let key = &line[..pos]; | ||
327 | let value = line[pos + 1..].trim_matches('"'); | ||
328 | cfg_options = cfg_options.key_value(key.into(), value.into()); | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | Err(e) => log::error!("failed to get rustc cfgs: {}", e), | ||
334 | } | ||
335 | |||
336 | cfg_options | ||
337 | } | ||