From 2bc4c1ff31b6ef0ca1848a7ce12f981b93dcded0 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 21 Oct 2020 13:57:12 +0200 Subject: Simplify cfg representation --- crates/cfg/src/lib.rs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'crates/cfg/src/lib.rs') diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index a9d50e698..35f540ac3 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs @@ -5,7 +5,7 @@ mod cfg_expr; use rustc_hash::FxHashSet; use tt::SmolStr; -pub use cfg_expr::CfgExpr; +pub use cfg_expr::{CfgAtom, CfgExpr}; /// Configuration options used for conditional compilition on items with `cfg` attributes. /// We have two kind of options in different namespaces: atomic options like `unix`, and @@ -19,33 +19,25 @@ pub use cfg_expr::CfgExpr; /// See: https://doc.rust-lang.org/reference/conditional-compilation.html#set-configuration-options #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct CfgOptions { - atoms: FxHashSet, - key_values: FxHashSet<(SmolStr, SmolStr)>, + enabled: FxHashSet, } impl CfgOptions { pub fn check(&self, cfg: &CfgExpr) -> Option { - cfg.fold(&|key, value| match value { - None => self.atoms.contains(key), - Some(value) => self.key_values.contains(&(key.clone(), value.clone())), - }) + cfg.fold(&|atom| self.enabled.contains(atom)) } pub fn insert_atom(&mut self, key: SmolStr) { - self.atoms.insert(key); + self.enabled.insert(CfgAtom::Flag(key)); } pub fn insert_key_value(&mut self, key: SmolStr, value: SmolStr) { - self.key_values.insert((key, value)); + self.enabled.insert(CfgAtom::KeyValue { key, value }); } pub fn append(&mut self, other: &CfgOptions) { - for atom in &other.atoms { - self.atoms.insert(atom.clone()); - } - - for (key, value) in &other.key_values { - self.key_values.insert((key.clone(), value.clone())); + for atom in &other.enabled { + self.enabled.insert(atom.clone()); } } } -- cgit v1.2.3 From 68b17986c7c272d9be8df9a7abb9b162329b9d65 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 21 Oct 2020 19:54:04 +0200 Subject: Implement DNF-based `#[cfg]` introspection --- crates/cfg/src/lib.rs | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) (limited to 'crates/cfg/src/lib.rs') diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index 35f540ac3..0b0734213 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs @@ -1,11 +1,15 @@ //! cfg defines conditional compiling options, `cfg` attibute parser and evaluator mod cfg_expr; +mod dnf; + +use std::fmt; use rustc_hash::FxHashSet; use tt::SmolStr; pub use cfg_expr::{CfgAtom, CfgExpr}; +pub use dnf::DnfExpr; /// Configuration options used for conditional compilition on items with `cfg` attributes. /// We have two kind of options in different namespaces: atomic options like `unix`, and @@ -40,4 +44,110 @@ impl CfgOptions { self.enabled.insert(atom.clone()); } } + + pub fn apply_diff(&mut self, diff: CfgDiff) { + for atom in diff.enable { + self.enabled.insert(atom); + } + + for atom in diff.disable { + self.enabled.remove(&atom); + } + } +} + +pub struct CfgDiff { + // Invariants: No duplicates, no atom that's both in `enable` and `disable`. + enable: Vec, + disable: Vec, +} + +impl CfgDiff { + /// Returns the total number of atoms changed by this diff. + pub fn len(&self) -> usize { + self.enable.len() + self.disable.len() + } +} + +impl fmt::Display for CfgDiff { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if !self.enable.is_empty() { + f.write_str("enable ")?; + for (i, atom) in self.enable.iter().enumerate() { + let sep = match i { + 0 => "", + _ if i == self.enable.len() - 1 => " and ", + _ => ", ", + }; + f.write_str(sep)?; + + write!(f, "{}", atom)?; + } + + if !self.disable.is_empty() { + f.write_str("; ")?; + } + } + + if !self.disable.is_empty() { + f.write_str("disable ")?; + for (i, atom) in self.disable.iter().enumerate() { + let sep = match i { + 0 => "", + _ if i == self.enable.len() - 1 => " and ", + _ => ", ", + }; + f.write_str(sep)?; + + write!(f, "{}", atom)?; + } + } + + Ok(()) + } +} + +pub struct InactiveReason { + enabled: Vec, + disabled: Vec, +} + +impl fmt::Display for InactiveReason { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if !self.enabled.is_empty() { + for (i, atom) in self.enabled.iter().enumerate() { + let sep = match i { + 0 => "", + _ if i == self.enabled.len() - 1 => " and ", + _ => ", ", + }; + f.write_str(sep)?; + + write!(f, "{}", atom)?; + } + let is_are = if self.enabled.len() == 1 { "is" } else { "are" }; + write!(f, " {} enabled", is_are)?; + + if !self.disabled.is_empty() { + f.write_str(" and ")?; + } + } + + if !self.disabled.is_empty() { + for (i, atom) in self.disabled.iter().enumerate() { + let sep = match i { + 0 => "", + _ if i == self.enabled.len() - 1 => " and ", + _ => ", ", + }; + f.write_str(sep)?; + + write!(f, "{}", atom)?; + } + let is_are = if self.disabled.len() == 1 { "is" } else { "are" }; + write!(f, " {} disabled", is_are)?; + } + + Ok(()) + } } -- cgit v1.2.3 From 978cc936491d23bd38ef18aa98ddcc7472ef5f54 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 22 Oct 2020 19:19:05 +0200 Subject: Fix typo --- crates/cfg/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/cfg/src/lib.rs') diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index 0b0734213..28a40a082 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs @@ -137,7 +137,7 @@ impl fmt::Display for InactiveReason { for (i, atom) in self.disabled.iter().enumerate() { let sep = match i { 0 => "", - _ if i == self.enabled.len() - 1 => " and ", + _ if i == self.disabled.len() - 1 => " and ", _ => ", ", }; f.write_str(sep)?; -- cgit v1.2.3 From a246d4f599dcf2612fa99720fb4ca98101ed93fb Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 23 Oct 2020 12:14:58 +0200 Subject: cfg: move tests to separate file that way we don't have to re-check the entire project when a test is changed --- crates/cfg/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'crates/cfg/src/lib.rs') diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index 28a40a082..d0e08cf5f 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs @@ -2,6 +2,8 @@ mod cfg_expr; mod dnf; +#[cfg(test)] +mod tests; use std::fmt; -- cgit v1.2.3