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.rs55
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
15use ra_cfg::CfgOptions;
14use ra_db::{CrateGraph, CrateId, Edition, FileId}; 16use ra_db::{CrateGraph, CrateId, Edition, FileId};
15use rustc_hash::FxHashMap; 17use rustc_hash::FxHashMap;
16use serde_json::from_reader; 18use 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
310pub 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}