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.rs57
1 files changed, 54 insertions, 3 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 4fa32dc34..640a5ebd3 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -1,3 +1,5 @@
1//! FIXME: write short doc here
2
1mod cargo_workspace; 3mod cargo_workspace;
2mod json_project; 4mod json_project;
3mod sysroot; 5mod sysroot;
@@ -7,8 +9,10 @@ use std::{
7 fs::File, 9 fs::File,
8 io::BufReader, 10 io::BufReader,
9 path::{Path, PathBuf}, 11 path::{Path, PathBuf},
12 process::Command,
10}; 13};
11 14
15use ra_cfg::CfgOptions;
12use ra_db::{CrateGraph, CrateId, Edition, FileId}; 16use ra_db::{CrateGraph, CrateId, Edition, FileId};
13use rustc_hash::FxHashMap; 17use rustc_hash::FxHashMap;
14use serde_json::from_reader; 18use serde_json::from_reader;
@@ -115,6 +119,7 @@ impl ProjectWorkspace {
115 119
116 pub fn to_crate_graph( 120 pub fn to_crate_graph(
117 &self, 121 &self,
122 default_cfg_options: &CfgOptions,
118 load: &mut dyn FnMut(&Path) -> Option<FileId>, 123 load: &mut dyn FnMut(&Path) -> Option<FileId>,
119 ) -> (CrateGraph, FxHashMap<CrateId, String>) { 124 ) -> (CrateGraph, FxHashMap<CrateId, String>) {
120 let mut crate_graph = CrateGraph::default(); 125 let mut crate_graph = CrateGraph::default();
@@ -129,7 +134,17 @@ impl ProjectWorkspace {
129 json_project::Edition::Edition2015 => Edition::Edition2015, 134 json_project::Edition::Edition2015 => Edition::Edition2015,
130 json_project::Edition::Edition2018 => Edition::Edition2018, 135 json_project::Edition::Edition2018 => Edition::Edition2018,
131 }; 136 };
132 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 );
133 } 148 }
134 } 149 }
135 150
@@ -155,7 +170,10 @@ impl ProjectWorkspace {
155 let mut sysroot_crates = FxHashMap::default(); 170 let mut sysroot_crates = FxHashMap::default();
156 for krate in sysroot.crates() { 171 for krate in sysroot.crates() {
157 if let Some(file_id) = load(krate.root(&sysroot)) { 172 if let Some(file_id) = load(krate.root(&sysroot)) {
158 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);
159 sysroot_crates.insert(krate, crate_id); 177 sysroot_crates.insert(krate, crate_id);
160 names.insert(crate_id, krate.name(&sysroot).to_string()); 178 names.insert(crate_id, krate.name(&sysroot).to_string());
161 } 179 }
@@ -184,7 +202,11 @@ impl ProjectWorkspace {
184 let root = tgt.root(&cargo); 202 let root = tgt.root(&cargo);
185 if let Some(file_id) = load(root) { 203 if let Some(file_id) = load(root) {
186 let edition = pkg.edition(&cargo); 204 let edition = pkg.edition(&cargo);
187 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);
188 names.insert(crate_id, pkg.name(&cargo).to_string()); 210 names.insert(crate_id, pkg.name(&cargo).to_string());
189 if tgt.kind(&cargo) == TargetKind::Lib { 211 if tgt.kind(&cargo) == TargetKind::Lib {
190 lib_tgt = Some(crate_id); 212 lib_tgt = Some(crate_id);
@@ -284,3 +306,32 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
284 } 306 }
285 Err(format!("can't find Cargo.toml at {}", path.display()))? 307 Err(format!("can't find Cargo.toml at {}", path.display()))?
286} 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}