mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Implement DNF-based #[cfg]
introspection
This commit is contained in:
parent
2bc4c1ff31
commit
68b17986c7
5 changed files with 622 additions and 2 deletions
|
@ -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<CfgAtom>,
|
||||
disable: Vec<CfgAtom>,
|
||||
}
|
||||
|
||||
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<CfgAtom>,
|
||||
disabled: Vec<CfgAtom>,
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue