aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_cfg
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_cfg')
-rw-r--r--crates/ra_cfg/src/lib.rs26
1 files changed, 17 insertions, 9 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}