aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_cfg/src/lib.rs26
-rw-r--r--crates/ra_hir/src/nameres/tests.rs6
-rw-r--r--crates/ra_ide_api/src/mock_analysis.rs1
3 files changed, 20 insertions, 13 deletions
diff --git a/crates/ra_cfg/src/lib.rs b/crates/ra_cfg/src/lib.rs
index fa5822d8a..dd81a73f4 100644
--- a/crates/ra_cfg/src/lib.rs
+++ b/crates/ra_cfg/src/lib.rs
@@ -1,24 +1,32 @@
1//! ra_cfg defines conditional compiling options, `cfg` attibute parser and evaluator 1//! ra_cfg defines conditional compiling options, `cfg` attibute parser and evaluator
2use ra_syntax::SmolStr; 2use ra_syntax::SmolStr;
3use rustc_hash::{FxHashMap, FxHashSet}; 3use rustc_hash::FxHashSet;
4 4
5mod cfg_expr; 5mod cfg_expr;
6 6
7pub use cfg_expr::{parse_cfg, CfgExpr}; 7pub use cfg_expr::{parse_cfg, CfgExpr};
8 8
9/// Configuration options used for conditional compilition on items with `cfg` attributes.
10/// We have two kind of options in different namespaces: atomic options like `unix`, and
11/// key-value options like `target_arch="x86"`.
12///
13/// Note that for key-value options, one key can have multiple values (but not none).
14/// `feature` is an example. We have both `feature="foo"` and `feature="bar"` if features
15/// `foo` and `bar` are both enabled. And here, we store key-value options as a set of tuple
16/// of key and value in `key_values`.
17///
18/// See: https://doc.rust-lang.org/reference/conditional-compilation.html#set-configuration-options
9#[derive(Debug, Clone, PartialEq, Eq, Default)] 19#[derive(Debug, Clone, PartialEq, Eq, Default)]
10pub struct CfgOptions { 20pub struct CfgOptions {
11 atoms: FxHashSet<SmolStr>, 21 atoms: FxHashSet<SmolStr>,
12 features: FxHashSet<SmolStr>, 22 key_values: FxHashSet<(SmolStr, SmolStr)>,
13 options: FxHashMap<SmolStr, SmolStr>,
14} 23}
15 24
16impl CfgOptions { 25impl CfgOptions {
17 pub fn check(&self, cfg: &CfgExpr) -> Option<bool> { 26 pub fn check(&self, cfg: &CfgExpr) -> Option<bool> {
18 cfg.fold(&|key, value| match value { 27 cfg.fold(&|key, value| match value {
19 None => self.atoms.contains(key), 28 None => self.atoms.contains(key),
20 Some(value) if key == "feature" => self.features.contains(value), 29 Some(value) => self.key_values.contains(&(key.clone(), value.clone())),
21 Some(value) => self.options.get(key).map_or(false, |v| v == value),
22 }) 30 })
23 } 31 }
24 32
@@ -31,13 +39,13 @@ impl CfgOptions {
31 self 39 self
32 } 40 }
33 41
34 pub fn feature(mut self, name: SmolStr) -> CfgOptions { 42 pub fn key_value(mut self, key: SmolStr, value: SmolStr) -> CfgOptions {
35 self.features.insert(name); 43 self.key_values.insert((key, value));
36 self 44 self
37 } 45 }
38 46
39 pub fn option(mut self, key: SmolStr, value: SmolStr) -> CfgOptions { 47 pub fn remove_atom(mut self, name: &SmolStr) -> CfgOptions {
40 self.options.insert(key, value); 48 self.atoms.remove(name);
41 self 49 self
42 } 50 }
43} 51}
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index f43767e59..34dd79574 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -563,9 +563,9 @@ fn cfg_test() {
563 "main": ("/main.rs", ["std"]), 563 "main": ("/main.rs", ["std"]),
564 "std": ("/lib.rs", [], CfgOptions::default() 564 "std": ("/lib.rs", [], CfgOptions::default()
565 .atom("test".into()) 565 .atom("test".into())
566 .feature("foo".into()) 566 .key_value("feature".into(), "foo".into())
567 .feature("bar".into()) 567 .key_value("feature".into(), "bar".into())
568 .option("opt".into(), "42".into()) 568 .key_value("opt".into(), "42".into())
569 ), 569 ),
570 }, 570 },
571 ); 571 );
diff --git a/crates/ra_ide_api/src/mock_analysis.rs b/crates/ra_ide_api/src/mock_analysis.rs
index 13258b63d..80b71894c 100644
--- a/crates/ra_ide_api/src/mock_analysis.rs
+++ b/crates/ra_ide_api/src/mock_analysis.rs
@@ -94,7 +94,6 @@ impl MockAnalysis {
94 assert!(path.starts_with('/')); 94 assert!(path.starts_with('/'));
95 let path = RelativePathBuf::from_path(&path[1..]).unwrap(); 95 let path = RelativePathBuf::from_path(&path[1..]).unwrap();
96 let file_id = FileId(i as u32 + 1); 96 let file_id = FileId(i as u32 + 1);
97 // FIXME: cfg options
98 let cfg_options = CfgOptions::default(); 97 let cfg_options = CfgOptions::default();
99 if path == "/lib.rs" || path == "/main.rs" { 98 if path == "/lib.rs" || path == "/main.rs" {
100 root_crate = Some(crate_graph.add_crate_root(file_id, Edition2018, cfg_options)); 99 root_crate = Some(crate_graph.add_crate_root(file_id, Edition2018, cfg_options));