diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 5fd6edd78d1..23148096cb1 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -114,9 +114,8 @@ struct CrateData { } impl CrateData { - fn new(file_id: FileId, edition: Edition) -> CrateData { - // FIXME: cfg options - CrateData { file_id, edition, dependencies: Vec::new(), cfg_options: CfgOptions::default() } + fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions) -> CrateData { + CrateData { file_id, edition, dependencies: Vec::new(), cfg_options } } fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { @@ -137,9 +136,14 @@ impl Dependency { } impl CrateGraph { - pub fn add_crate_root(&mut self, file_id: FileId, edition: Edition) -> CrateId { + pub fn add_crate_root( + &mut self, + file_id: FileId, + edition: Edition, + cfg_options: CfgOptions, + ) -> CrateId { let crate_id = CrateId(self.arena.len() as u32); - let prev = self.arena.insert(crate_id, CrateData::new(file_id, edition)); + let prev = self.arena.insert(crate_id, CrateData::new(file_id, edition, cfg_options)); assert!(prev.is_none()); crate_id } @@ -228,14 +232,14 @@ impl CrateGraph { #[cfg(test)] mod tests { - use super::{CrateGraph, Edition::Edition2018, FileId, SmolStr}; + use super::{CfgOptions, CrateGraph, Edition::Edition2018, FileId, SmolStr}; #[test] fn it_should_panic_because_of_cycle_dependencies() { let mut graph = CrateGraph::default(); - let crate1 = graph.add_crate_root(FileId(1u32), Edition2018); - let crate2 = graph.add_crate_root(FileId(2u32), Edition2018); - let crate3 = graph.add_crate_root(FileId(3u32), Edition2018); + let crate1 = graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default()); + let crate2 = graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default()); + let crate3 = graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default()); assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); @@ -244,9 +248,9 @@ mod tests { #[test] fn it_works() { let mut graph = CrateGraph::default(); - let crate1 = graph.add_crate_root(FileId(1u32), Edition2018); - let crate2 = graph.add_crate_root(FileId(2u32), Edition2018); - let crate3 = graph.add_crate_root(FileId(3u32), Edition2018); + let crate1 = graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default()); + let crate2 = graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default()); + let crate3 = graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default()); assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); } diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 50feb98fb35..f750986b8b3 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs @@ -3,6 +3,7 @@ use std::{panic, sync::Arc}; use parking_lot::Mutex; +use ra_cfg::CfgOptions; use ra_db::{ salsa, CrateGraph, CrateId, Edition, FileId, FilePosition, SourceDatabase, SourceRoot, SourceRootId, @@ -74,13 +75,13 @@ impl MockDatabase { pub fn set_crate_graph_from_fixture(&mut self, graph: CrateGraphFixture) { let mut ids = FxHashMap::default(); let mut crate_graph = CrateGraph::default(); - for (crate_name, (crate_root, edition, _)) in graph.0.iter() { + for (crate_name, (crate_root, edition, cfg_options, _)) in graph.0.iter() { let crate_root = self.file_id_of(&crate_root); - let crate_id = crate_graph.add_crate_root(crate_root, *edition); + let crate_id = crate_graph.add_crate_root(crate_root, *edition, cfg_options.clone()); Arc::make_mut(&mut self.crate_names).insert(crate_id, crate_name.clone()); ids.insert(crate_name, crate_id); } - for (crate_name, (_, _, deps)) in graph.0.iter() { + for (crate_name, (_, _, _, deps)) in graph.0.iter() { let from = ids[crate_name]; for dep in deps { let to = ids[dep]; @@ -184,7 +185,7 @@ impl MockDatabase { if is_crate_root { let mut crate_graph = CrateGraph::default(); - crate_graph.add_crate_root(file_id, Edition::Edition2018); + crate_graph.add_crate_root(file_id, Edition::Edition2018, CfgOptions::default()); self.set_crate_graph(Arc::new(crate_graph)); } file_id @@ -268,19 +269,27 @@ impl MockDatabase { } #[derive(Default)] -pub struct CrateGraphFixture(pub Vec<(String, (String, Edition, Vec))>); +pub struct CrateGraphFixture(pub Vec<(String, (String, Edition, CfgOptions, Vec))>); #[macro_export] macro_rules! crate_graph { - ($($crate_name:literal: ($crate_path:literal, $($edition:literal,)? [$($dep:literal),*]),)*) => {{ + ($( + $crate_name:literal: ( + $crate_path:literal, + $($edition:literal,)? + [$($dep:literal),*] + $(,$cfg:expr)? + ), + )*) => {{ let mut res = $crate::mock::CrateGraphFixture::default(); $( #[allow(unused_mut, unused_assignments)] let mut edition = ra_db::Edition::Edition2018; $(edition = ra_db::Edition::from_string($edition);)? + let cfg_options = { ::ra_cfg::CfgOptions::default() $(; $cfg)? }; res.0.push(( $crate_name.to_string(), - ($crate_path.to_string(), edition, vec![$($dep.to_string()),*]) + ($crate_path.to_string(), edition, cfg_options, vec![$($dep.to_string()),*]) )); )* res diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index bc4b47b704c..f43767e5958 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs @@ -7,6 +7,7 @@ mod mod_resolution; use std::sync::Arc; use insta::assert_snapshot; +use ra_cfg::CfgOptions; use ra_db::SourceDatabase; use test_utils::covers; @@ -507,3 +508,72 @@ fn values_dont_shadow_extern_crates() { ⋮foo: v "###); } + +#[test] +fn cfg_not_test() { + let map = def_map_with_crate_graph( + r#" + //- /main.rs + use {Foo, Bar, Baz}; + //- /lib.rs + #[prelude_import] + pub use self::prelude::*; + mod prelude { + #[cfg(test)] + pub struct Foo; + #[cfg(not(test))] + pub struct Bar; + #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))] + pub struct Baz; + } + "#, + crate_graph! { + "main": ("/main.rs", ["std"]), + "std": ("/lib.rs", []), + }, + ); + + assert_snapshot!(map, @r###" + ⋮crate + ⋮Bar: t v + ⋮Baz: _ + ⋮Foo: _ + "###); +} + +#[test] +fn cfg_test() { + let map = def_map_with_crate_graph( + r#" + //- /main.rs + use {Foo, Bar, Baz}; + //- /lib.rs + #[prelude_import] + pub use self::prelude::*; + mod prelude { + #[cfg(test)] + pub struct Foo; + #[cfg(not(test))] + pub struct Bar; + #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))] + pub struct Baz; + } + "#, + crate_graph! { + "main": ("/main.rs", ["std"]), + "std": ("/lib.rs", [], CfgOptions::default() + .atom("test".into()) + .feature("foo".into()) + .feature("bar".into()) + .option("opt".into(), "42".into()) + ), + }, + ); + + assert_snapshot!(map, @r###" + ⋮crate + ⋮Bar: _ + ⋮Baz: t v + ⋮Foo: t v + "###); +} diff --git a/crates/ra_ide_api/Cargo.toml b/crates/ra_ide_api/Cargo.toml index 6bbf9d5dde0..f919a2d6152 100644 --- a/crates/ra_ide_api/Cargo.toml +++ b/crates/ra_ide_api/Cargo.toml @@ -23,6 +23,7 @@ rand = { version = "0.7.0", features = ["small_rng"] } ra_syntax = { path = "../ra_syntax" } ra_text_edit = { path = "../ra_text_edit" } ra_db = { path = "../ra_db" } +ra_cfg = { path = "../ra_cfg" } ra_fmt = { path = "../ra_fmt" } ra_prof = { path = "../ra_prof" } hir = { path = "../ra_hir", package = "ra_hir" } diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 44d1ec77b0c..24f1b91f68c 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -49,6 +49,7 @@ mod test_utils; use std::sync::Arc; +use ra_cfg::CfgOptions; use ra_db::{ salsa::{self, ParallelDatabase}, CheckCanceled, SourceDatabase, @@ -322,7 +323,10 @@ impl Analysis { change.add_root(source_root, true); let mut crate_graph = CrateGraph::default(); let file_id = FileId(0); - crate_graph.add_crate_root(file_id, Edition::Edition2018); + // FIXME: cfg options + // Default to enable test for single file. + let cfg_options = CfgOptions::default().atom("test".into()); + crate_graph.add_crate_root(file_id, Edition::Edition2018, cfg_options); change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text)); change.set_crate_graph(crate_graph); host.apply_change(change); diff --git a/crates/ra_ide_api/src/mock_analysis.rs b/crates/ra_ide_api/src/mock_analysis.rs index 16870c7ae49..13258b63dd9 100644 --- a/crates/ra_ide_api/src/mock_analysis.rs +++ b/crates/ra_ide_api/src/mock_analysis.rs @@ -2,6 +2,7 @@ use std::sync::Arc; +use ra_cfg::CfgOptions; use relative_path::RelativePathBuf; use test_utils::{extract_offset, extract_range, parse_fixture, CURSOR_MARKER}; @@ -93,10 +94,12 @@ impl MockAnalysis { assert!(path.starts_with('/')); let path = RelativePathBuf::from_path(&path[1..]).unwrap(); let file_id = FileId(i as u32 + 1); + // FIXME: cfg options + let cfg_options = CfgOptions::default(); if path == "/lib.rs" || path == "/main.rs" { - root_crate = Some(crate_graph.add_crate_root(file_id, Edition2018)); + root_crate = Some(crate_graph.add_crate_root(file_id, Edition2018, cfg_options)); } else if path.ends_with("/lib.rs") { - let other_crate = crate_graph.add_crate_root(file_id, Edition2018); + let other_crate = crate_graph.add_crate_root(file_id, Edition2018, cfg_options); let crate_name = path.parent().unwrap().file_name().unwrap(); if let Some(root_crate) = root_crate { crate_graph.add_dep(root_crate, crate_name.into(), other_crate).unwrap(); diff --git a/crates/ra_ide_api/src/parent_module.rs b/crates/ra_ide_api/src/parent_module.rs index c85f1d0d02f..56650984995 100644 --- a/crates/ra_ide_api/src/parent_module.rs +++ b/crates/ra_ide_api/src/parent_module.rs @@ -41,6 +41,7 @@ mod tests { AnalysisChange, CrateGraph, Edition::Edition2018, }; + use ra_cfg::CfgOptions; #[test] fn test_resolve_parent_module() { @@ -88,7 +89,7 @@ mod tests { assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); let mut crate_graph = CrateGraph::default(); - let crate_id = crate_graph.add_crate_root(root_file, Edition2018); + let crate_id = crate_graph.add_crate_root(root_file, Edition2018, CfgOptions::default()); let mut change = AnalysisChange::new(); change.set_crate_graph(crate_graph); host.apply_change(change); diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index ae6b91aa69b..a651000315b 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml @@ -12,6 +12,7 @@ cargo_metadata = "0.8.2" ra_arena = { path = "../ra_arena" } ra_db = { path = "../ra_db" } +ra_cfg = { path = "../ra_cfg" } serde = { version = "1.0.89", features = ["derive"] } serde_json = "1.0.39" diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 5d307859805..5ff3971e064 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -11,6 +11,7 @@ use std::{ path::{Path, PathBuf}, }; +use ra_cfg::CfgOptions; use ra_db::{CrateGraph, CrateId, Edition, FileId}; use rustc_hash::FxHashMap; use serde_json::from_reader; @@ -131,7 +132,13 @@ impl ProjectWorkspace { json_project::Edition::Edition2015 => Edition::Edition2015, json_project::Edition::Edition2018 => Edition::Edition2018, }; - crates.insert(crate_id, crate_graph.add_crate_root(file_id, edition)); + // FIXME: cfg options + // Default to enable test for workspace crates. + let cfg_options = CfgOptions::default().atom("test".into()); + crates.insert( + crate_id, + crate_graph.add_crate_root(file_id, edition, cfg_options), + ); } } @@ -157,7 +164,11 @@ impl ProjectWorkspace { let mut sysroot_crates = FxHashMap::default(); for krate in sysroot.crates() { if let Some(file_id) = load(krate.root(&sysroot)) { - let crate_id = crate_graph.add_crate_root(file_id, Edition::Edition2018); + // FIXME: cfg options + // Crates from sysroot have `cfg(test)` disabled + let cfg_options = CfgOptions::default(); + let crate_id = + crate_graph.add_crate_root(file_id, Edition::Edition2018, cfg_options); sysroot_crates.insert(krate, crate_id); names.insert(crate_id, krate.name(&sysroot).to_string()); } @@ -186,7 +197,11 @@ impl ProjectWorkspace { let root = tgt.root(&cargo); if let Some(file_id) = load(root) { let edition = pkg.edition(&cargo); - let crate_id = crate_graph.add_crate_root(file_id, edition); + // FIXME: cfg options + // Default to enable test for workspace crates. + let cfg_options = CfgOptions::default().atom("test".into()); + let crate_id = + crate_graph.add_crate_root(file_id, edition, cfg_options); names.insert(crate_id, pkg.name(&cargo).to_string()); if tgt.kind(&cargo) == TargetKind::Lib { lib_tgt = Some(crate_id);