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]) -> Self {14 let mut res = 0u128;15 let mut i = 0;16 while i < kinds.len() {17 res |= mask(kinds[i]);18 i += 1;19 }20 Self(res)21 }2223 #[must_use]24 pub const fn union(self, other: Self) -> Self {25 Self(self.0 | other.0)26 }27 #[must_use]28 pub const fn with(self, kind: SyntaxKind) -> Self {29 Self(self.0 | mask(kind))30 }3132 pub fn contains(&self, kind: SyntaxKind) -> bool {33 if !is_token(kind) {34 return false;35 }36 self.0 & mask(kind) != 037 }38}39impl fmt::Display for SyntaxKindSet {40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {41 let mut v = self.0;42 let mut variants = <Vec<SyntaxKind>>::new();43 for i in 0..128 {44 if v & 1 == 1 {45 variants.push(SyntaxKind::from_raw(i));46 }47 v >>= 1;48 if v == 0 {49 break;50 }51 }52 for (i, v) in variants.iter().enumerate() {53 if i == 0 {54 } else if i == variants.len() - 1 {55 write!(f, " or ")?;56 } else {57 write!(f, ", ")?;58 }59 write!(f, "{v:?}")?;60 }61 Ok(())62 }63}64impl fmt::Debug for SyntaxKindSet {65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {66 let mut v = self.0;67 let mut variants = <Vec<SyntaxKind>>::new();68 for i in 0..128 {69 if v & 1 == 1 {70 variants.push(SyntaxKind::from_raw(i));71 }72 v >>= 1;73 if v == 0 {74 break;75 }76 }77 f.debug_tuple("SyntaxKindSet").field(&variants).finish()78 }79}8081const fn mask(kind: SyntaxKind) -> u128 {82 assert!(kind as u32 <= 128, "mask for not a token kind");83 1u128 << (kind as u128)84}8586#[macro_export]87macro_rules! TS {88 ($($tt:tt)*) => {89 $crate::SyntaxKindSet::new(&[90 $(91 $crate::T![$tt]92 ),*93 ])94 };95}9697#[test]98fn sanity() {99 assert!(100 (SyntaxKind::LEXING_ERROR as u32) < 127,101 "can't keep KindSet as bitset"102 );103}104fn is_token(kind: SyntaxKind) -> bool {105 (kind as u32) < 127106}