1use std::fmt;23use crate::SyntaxKind;45#[derive(Clone, Copy, Default)]6pub struct SyntaxKindSet(u128);78impl SyntaxKindSet {9 #[allow(dead_code)]10 pub const EMPTY: Self = Self(0);11 pub const ALL: Self = Self(u128::MAX);1213 pub const fn new(kinds: &[SyntaxKind]) -> SyntaxKindSet {14 let mut res = 0u128;15 let mut i = 0;16 while i < kinds.len() {17 res |= mask(kinds[i]);18 i += 119 }20 SyntaxKindSet(res)21 }2223 pub const fn union(self, other: SyntaxKindSet) -> SyntaxKindSet {24 SyntaxKindSet(self.0 | other.0)25 }26 pub const fn with(self, kind: SyntaxKind) -> SyntaxKindSet {27 SyntaxKindSet(self.0 | mask(kind))28 }2930 pub const fn contains(&self, kind: SyntaxKind) -> bool {31 self.0 & mask(kind) != 032 }33}34impl fmt::Display for SyntaxKindSet {35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {36 let mut v = self.0;37 let mut variants = <Vec<SyntaxKind>>::new();38 for i in 0..128 {39 if v & 1 == 1 {40 variants.push(SyntaxKind::from_raw(i))41 }42 v >>= 1;43 if v == 0 {44 break;45 }46 }47 for (i, v) in variants.iter().enumerate() {48 if i == 0 {49 } else if i == variants.len() - 1 {50 write!(f, " or ")?;51 } else {52 write!(f, ", ")?;53 }54 write!(f, "{v:?}")?;55 }56 Ok(())57 }58}59impl fmt::Debug for SyntaxKindSet {60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {61 let mut v = self.0;62 let mut variants = <Vec<SyntaxKind>>::new();63 for i in 0..128 {64 if v & 1 == 1 {65 variants.push(SyntaxKind::from_raw(i))66 }67 v >>= 1;68 if v == 0 {69 break;70 }71 }72 f.debug_tuple("SyntaxKindSet").field(&variants).finish()73 }74}7576const fn mask(kind: SyntaxKind) -> u128 {77 1u128 << (kind as u128)78}7980#[macro_export]81macro_rules! TS {82 ($($tt:tt)*) => {83 $crate::SyntaxKindSet::new(&[84 $(85 $crate::T![$tt]86 ),*87 ])88 };89}9091#[test]92fn sanity() {93 assert!(94 (SyntaxKind::LEXING_ERROR as u32) < 127,95 "can't keep KindSet as bitset"96 );97}