aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_cfg/src
diff options
context:
space:
mode:
authorZac Pullar-Strecker <[email protected]>2020-07-31 03:12:44 +0100
committerZac Pullar-Strecker <[email protected]>2020-07-31 03:12:44 +0100
commitf05d7b41a719d848844b054a16477b29d0f063c6 (patch)
tree0a8a0946e8aef2ce64d4c13d0035ba41cce2daf3 /crates/ra_cfg/src
parent73ff610e41959e3e7c78a2b4b25b086883132956 (diff)
parent6b7cb8b5ab539fc4333ce34bc29bf77c976f232a (diff)
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Hasn't fixed tests yet.
Diffstat (limited to 'crates/ra_cfg/src')
-rw-r--r--crates/ra_cfg/src/cfg_expr.rs21
-rw-r--r--crates/ra_cfg/src/lib.rs20
2 files changed, 21 insertions, 20 deletions
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 @@
5use std::slice::Iter as SliceIter; 5use std::slice::Iter as SliceIter;
6 6
7use ra_syntax::SmolStr; 7use ra_syntax::SmolStr;
8use tt::{Leaf, Subtree, TokenTree};
9 8
10#[derive(Debug, Clone, PartialEq, Eq)] 9#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum CfgExpr { 10pub enum CfgExpr {
@@ -18,6 +17,9 @@ pub enum CfgExpr {
18} 17}
19 18
20impl CfgExpr { 19impl 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
38pub fn parse_cfg(tt: &Subtree) -> CfgExpr {
39 next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid)
40}
41
42fn next_cfg_expr(it: &mut SliceIter<tt::TokenTree>) -> Option<CfgExpr> { 40fn 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;
5use ra_syntax::SmolStr; 5use ra_syntax::SmolStr;
6use rustc_hash::FxHashSet; 6use rustc_hash::FxHashSet;
7 7
8pub use cfg_expr::{parse_cfg, CfgExpr}; 8pub 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}