diff options
Diffstat (limited to 'crates/ra_cfg')
-rw-r--r-- | crates/ra_cfg/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_cfg/src/cfg_expr.rs | 21 | ||||
-rw-r--r-- | crates/ra_cfg/src/lib.rs | 20 |
3 files changed, 22 insertions, 20 deletions
diff --git a/crates/ra_cfg/Cargo.toml b/crates/ra_cfg/Cargo.toml index 9165076a5..6425cd6d6 100644 --- a/crates/ra_cfg/Cargo.toml +++ b/crates/ra_cfg/Cargo.toml | |||
@@ -3,6 +3,7 @@ edition = "2018" | |||
3 | name = "ra_cfg" | 3 | name = "ra_cfg" |
4 | version = "0.1.0" | 4 | version = "0.1.0" |
5 | authors = ["rust-analyzer developers"] | 5 | authors = ["rust-analyzer developers"] |
6 | license = "MIT OR Apache-2.0" | ||
6 | 7 | ||
7 | [lib] | 8 | [lib] |
8 | doctest = false | 9 | doctest = false |
diff --git a/crates/ra_cfg/src/cfg_expr.rs b/crates/ra_cfg/src/cfg_expr.rs index 85b100c6a..f48928aee 100644 --- a/crates/ra_cfg/src/cfg_expr.rs +++ b/crates/ra_cfg/src/cfg_expr.rs | |||
@@ -5,7 +5,6 @@ | |||
5 | use std::slice::Iter as SliceIter; | 5 | use std::slice::Iter as SliceIter; |
6 | 6 | ||
7 | use ra_syntax::SmolStr; | 7 | use ra_syntax::SmolStr; |
8 | use tt::{Leaf, Subtree, TokenTree}; | ||
9 | 8 | ||
10 | #[derive(Debug, Clone, PartialEq, Eq)] | 9 | #[derive(Debug, Clone, PartialEq, Eq)] |
11 | pub enum CfgExpr { | 10 | pub enum CfgExpr { |
@@ -18,6 +17,9 @@ pub enum CfgExpr { | |||
18 | } | 17 | } |
19 | 18 | ||
20 | impl CfgExpr { | 19 | impl CfgExpr { |
20 | pub fn parse(tt: &tt::Subtree) -> CfgExpr { | ||
21 | next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid) | ||
22 | } | ||
21 | /// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates. | 23 | /// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates. |
22 | pub fn fold(&self, query: &dyn Fn(&SmolStr, Option<&SmolStr>) -> bool) -> Option<bool> { | 24 | pub fn fold(&self, query: &dyn Fn(&SmolStr, Option<&SmolStr>) -> bool) -> Option<bool> { |
23 | match self { | 25 | match self { |
@@ -35,22 +37,18 @@ impl CfgExpr { | |||
35 | } | 37 | } |
36 | } | 38 | } |
37 | 39 | ||
38 | pub fn parse_cfg(tt: &Subtree) -> CfgExpr { | ||
39 | next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid) | ||
40 | } | ||
41 | |||
42 | fn next_cfg_expr(it: &mut SliceIter<tt::TokenTree>) -> Option<CfgExpr> { | 40 | fn next_cfg_expr(it: &mut SliceIter<tt::TokenTree>) -> Option<CfgExpr> { |
43 | let name = match it.next() { | 41 | let name = match it.next() { |
44 | None => return None, | 42 | None => return None, |
45 | Some(TokenTree::Leaf(Leaf::Ident(ident))) => ident.text.clone(), | 43 | Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.text.clone(), |
46 | Some(_) => return Some(CfgExpr::Invalid), | 44 | Some(_) => return Some(CfgExpr::Invalid), |
47 | }; | 45 | }; |
48 | 46 | ||
49 | // Peek | 47 | // Peek |
50 | let ret = match it.as_slice().first() { | 48 | let ret = match it.as_slice().first() { |
51 | Some(TokenTree::Leaf(Leaf::Punct(punct))) if punct.char == '=' => { | 49 | Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '=' => { |
52 | match it.as_slice().get(1) { | 50 | match it.as_slice().get(1) { |
53 | Some(TokenTree::Leaf(Leaf::Literal(literal))) => { | 51 | Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => { |
54 | it.next(); | 52 | it.next(); |
55 | it.next(); | 53 | it.next(); |
56 | // FIXME: escape? raw string? | 54 | // FIXME: escape? raw string? |
@@ -61,7 +59,7 @@ fn next_cfg_expr(it: &mut SliceIter<tt::TokenTree>) -> Option<CfgExpr> { | |||
61 | _ => return Some(CfgExpr::Invalid), | 59 | _ => return Some(CfgExpr::Invalid), |
62 | } | 60 | } |
63 | } | 61 | } |
64 | Some(TokenTree::Subtree(subtree)) => { | 62 | Some(tt::TokenTree::Subtree(subtree)) => { |
65 | it.next(); | 63 | it.next(); |
66 | let mut sub_it = subtree.token_trees.iter(); | 64 | let mut sub_it = subtree.token_trees.iter(); |
67 | let mut subs = std::iter::from_fn(|| next_cfg_expr(&mut sub_it)).collect(); | 65 | let mut subs = std::iter::from_fn(|| next_cfg_expr(&mut sub_it)).collect(); |
@@ -76,7 +74,7 @@ fn next_cfg_expr(it: &mut SliceIter<tt::TokenTree>) -> Option<CfgExpr> { | |||
76 | }; | 74 | }; |
77 | 75 | ||
78 | // Eat comma separator | 76 | // Eat comma separator |
79 | if let Some(TokenTree::Leaf(Leaf::Punct(punct))) = it.as_slice().first() { | 77 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = it.as_slice().first() { |
80 | if punct.char == ',' { | 78 | if punct.char == ',' { |
81 | it.next(); | 79 | it.next(); |
82 | } | 80 | } |
@@ -99,7 +97,8 @@ mod tests { | |||
99 | 97 | ||
100 | fn assert_parse_result(input: &str, expected: CfgExpr) { | 98 | fn assert_parse_result(input: &str, expected: CfgExpr) { |
101 | let (tt, _) = get_token_tree_generated(input); | 99 | let (tt, _) = get_token_tree_generated(input); |
102 | assert_eq!(parse_cfg(&tt), expected); | 100 | let cfg = CfgExpr::parse(&tt); |
101 | assert_eq!(cfg, expected); | ||
103 | } | 102 | } |
104 | 103 | ||
105 | #[test] | 104 | #[test] |
diff --git a/crates/ra_cfg/src/lib.rs b/crates/ra_cfg/src/lib.rs index 57feabcb2..cd5a0a7b6 100644 --- a/crates/ra_cfg/src/lib.rs +++ b/crates/ra_cfg/src/lib.rs | |||
@@ -5,7 +5,7 @@ mod cfg_expr; | |||
5 | use ra_syntax::SmolStr; | 5 | use ra_syntax::SmolStr; |
6 | use rustc_hash::FxHashSet; | 6 | use rustc_hash::FxHashSet; |
7 | 7 | ||
8 | pub use cfg_expr::{parse_cfg, CfgExpr}; | 8 | pub use cfg_expr::CfgExpr; |
9 | 9 | ||
10 | /// Configuration options used for conditional compilition on items with `cfg` attributes. | 10 | /// Configuration options used for conditional compilition on items with `cfg` attributes. |
11 | /// We have two kind of options in different namespaces: atomic options like `unix`, and | 11 | /// We have two kind of options in different namespaces: atomic options like `unix`, and |
@@ -31,19 +31,21 @@ impl CfgOptions { | |||
31 | }) | 31 | }) |
32 | } | 32 | } |
33 | 33 | ||
34 | pub fn is_cfg_enabled(&self, attr: &tt::Subtree) -> Option<bool> { | ||
35 | self.check(&parse_cfg(attr)) | ||
36 | } | ||
37 | |||
38 | pub fn insert_atom(&mut self, key: SmolStr) { | 34 | pub fn insert_atom(&mut self, key: SmolStr) { |
39 | self.atoms.insert(key); | 35 | self.atoms.insert(key); |
40 | } | 36 | } |
41 | 37 | ||
42 | pub fn remove_atom(&mut self, name: &str) { | ||
43 | self.atoms.remove(name); | ||
44 | } | ||
45 | |||
46 | pub fn insert_key_value(&mut self, key: SmolStr, value: SmolStr) { | 38 | pub fn insert_key_value(&mut self, key: SmolStr, value: SmolStr) { |
47 | self.key_values.insert((key, value)); | 39 | self.key_values.insert((key, value)); |
48 | } | 40 | } |
41 | |||
42 | pub fn append(&mut self, other: &CfgOptions) { | ||
43 | for atom in &other.atoms { | ||
44 | self.atoms.insert(atom.clone()); | ||
45 | } | ||
46 | |||
47 | for (key, value) in &other.key_values { | ||
48 | self.key_values.insert((key.clone(), value.clone())); | ||
49 | } | ||
50 | } | ||
49 | } | 51 | } |