Skip to content

Commit 5c55347

Browse files
chore(parser): increase size of TokenSet (#7997)
1 parent 6e8a50e commit 5c55347

File tree

1 file changed

+170
-7
lines changed

1 file changed

+170
-7
lines changed

crates/biome_parser/src/token_set.rs

Lines changed: 170 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,22 @@ use biome_rowan::SyntaxKind;
22
use std::marker::PhantomData;
33

44
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5-
pub struct TokenSet<K: SyntaxKind>([u128; 2], PhantomData<K>);
5+
pub struct TokenSet<K: SyntaxKind>([u128; 3], PhantomData<K>);
66

77
impl<K: SyntaxKind> TokenSet<K> {
8-
pub const EMPTY: Self = Self([0; 2], PhantomData);
8+
pub const EMPTY: Self = Self([0; 3], PhantomData);
99

1010
pub fn singleton(kind: K) -> Self {
1111
unsafe { Self::from_raw(kind.to_raw().0) }
1212
}
1313

1414
pub const fn union(self, other: Self) -> Self {
1515
Self(
16-
[self.0[0] | other.0[0], self.0[1] | other.0[1]],
16+
[
17+
self.0[0] | other.0[0],
18+
self.0[1] | other.0[1],
19+
self.0[2] | other.0[2],
20+
],
1721
PhantomData,
1822
)
1923
}
@@ -23,7 +27,9 @@ impl<K: SyntaxKind> TokenSet<K> {
2327
let num = kind as usize;
2428
match num {
2529
0..=127 => self.0[0] & mask(kind)[0] != 0,
26-
_ => self.0[1] & mask(kind)[1] != 0,
30+
128..=255 => self.0[1] & mask(kind)[1] != 0,
31+
256..=383 => self.0[2] & mask(kind)[2] != 0,
32+
_ => false,
2733
}
2834
}
2935

@@ -39,11 +45,13 @@ impl<K: SyntaxKind> TokenSet<K> {
3945
}
4046
}
4147

42-
const fn mask(kind: u16) -> [u128; 2] {
48+
const fn mask(kind: u16) -> [u128; 3] {
4349
let num = kind as usize;
4450
match num {
45-
0..=127 => [1u128 << num, 0],
46-
_ => [0, 1u128 << (num - 127)],
51+
0..=127 => [1u128 << num, 0, 0],
52+
128..=255 => [0, 1u128 << (num - 128), 0],
53+
256..=383 => [0, 0, 1u128 << (num - 256)],
54+
_ => panic!("TokenKind limit exceeded"),
4755
}
4856
}
4957

@@ -56,3 +64,158 @@ macro_rules! token_set {
5664
}};
5765
($($t:expr),* ,) => { token_set!($($t),*) };
5866
}
67+
68+
#[cfg(test)]
69+
mod tests {
70+
use biome_rowan::RawSyntaxKind;
71+
72+
use super::*;
73+
74+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
75+
enum TestKind {
76+
Kind0 = 0,
77+
Kind127 = 127,
78+
Kind128 = 128,
79+
Kind255 = 255,
80+
Kind256 = 256,
81+
Kind383 = 383,
82+
}
83+
84+
impl SyntaxKind for TestKind {
85+
const TOMBSTONE: Self = Self::Kind0;
86+
const EOF: Self = Self::Kind383;
87+
88+
fn to_raw(&self) -> RawSyntaxKind {
89+
RawSyntaxKind(*self as u16)
90+
}
91+
92+
#[expect(unsafe_code)]
93+
fn from_raw(raw: RawSyntaxKind) -> Self {
94+
unsafe { std::mem::transmute::<u16, Self>(raw.0) }
95+
}
96+
97+
fn is_root(&self) -> bool {
98+
false
99+
}
100+
101+
fn is_list(&self) -> bool {
102+
false
103+
}
104+
105+
fn is_bogus(&self) -> bool {
106+
false
107+
}
108+
109+
fn is_trivia(self) -> bool {
110+
false
111+
}
112+
113+
fn to_string(&self) -> Option<&'static str> {
114+
None
115+
}
116+
117+
fn to_bogus(&self) -> Self {
118+
Self::Kind0
119+
}
120+
121+
fn is_allowed_before_suppressions(&self) -> bool {
122+
false
123+
}
124+
}
125+
126+
#[test]
127+
fn test_mask_first_128() {
128+
// lower limit test
129+
let [a, b, c] = mask(0);
130+
131+
assert!(a.count_ones() == 1);
132+
assert!(a.trailing_zeros() == 0);
133+
assert_eq!(b, 0);
134+
assert_eq!(c, 0);
135+
136+
// upper limit test
137+
let [a, b, c] = mask(127);
138+
139+
assert!(a.count_ones() == 1);
140+
assert!(a.trailing_zeros() == u128::BITS - 1);
141+
assert_eq!(b, 0);
142+
assert_eq!(c, 0);
143+
}
144+
145+
#[test]
146+
fn test_mask_second_128() {
147+
// lower limit test
148+
let [a, b, c] = mask(128);
149+
150+
assert_eq!(a, 0);
151+
assert!(b.count_ones() == 1);
152+
assert!(b.trailing_zeros() == 0);
153+
assert_eq!(c, 0);
154+
155+
// upper limit test
156+
let [a, b, c] = mask(255);
157+
158+
assert_eq!(a, 0);
159+
assert!(b.count_ones() == 1);
160+
assert!(b.trailing_zeros() == u128::BITS - 1);
161+
assert_eq!(c, 0);
162+
}
163+
164+
#[test]
165+
fn test_mask_third_128() {
166+
// lower limit test
167+
let [a, b, c] = mask(256);
168+
169+
assert_eq!(a, 0);
170+
assert_eq!(b, 0);
171+
assert!(c.count_ones() == 1);
172+
assert!(c.trailing_zeros() == 0);
173+
174+
// upper limit test
175+
let [a, b, c] = mask(383);
176+
177+
assert_eq!(a, 0);
178+
assert_eq!(b, 0);
179+
assert!(c.count_ones() == 1);
180+
assert!(c.trailing_zeros() == u128::BITS - 1);
181+
}
182+
183+
#[test]
184+
#[should_panic(expected = "TokenKind limit exceeded")]
185+
fn test_mask_out_of_range() {
186+
mask(384);
187+
}
188+
189+
#[test]
190+
fn test_contains() {
191+
let set: TokenSet<TestKind> = TokenSet::EMPTY;
192+
assert!(!set.contains(TestKind::Kind0));
193+
assert!(!set.contains(TestKind::Kind127));
194+
195+
let set = TokenSet::singleton(TestKind::Kind0)
196+
.union(TokenSet::singleton(TestKind::Kind128))
197+
.union(TokenSet::singleton(TestKind::Kind383));
198+
199+
assert!(set.contains(TestKind::Kind0));
200+
assert!(set.contains(TestKind::Kind128));
201+
assert!(set.contains(TestKind::Kind383));
202+
203+
assert!(!set.contains(TestKind::Kind127));
204+
assert!(!set.contains(TestKind::Kind255));
205+
assert!(!set.contains(TestKind::Kind256));
206+
207+
let set = TokenSet::singleton(TestKind::Kind0)
208+
.union(TokenSet::singleton(TestKind::Kind127))
209+
.union(TokenSet::singleton(TestKind::Kind128))
210+
.union(TokenSet::singleton(TestKind::Kind255))
211+
.union(TokenSet::singleton(TestKind::Kind256))
212+
.union(TokenSet::singleton(TestKind::Kind383));
213+
214+
assert!(set.contains(TestKind::Kind0));
215+
assert!(set.contains(TestKind::Kind127));
216+
assert!(set.contains(TestKind::Kind128));
217+
assert!(set.contains(TestKind::Kind255));
218+
assert!(set.contains(TestKind::Kind256));
219+
assert!(set.contains(TestKind::Kind383));
220+
}
221+
}

0 commit comments

Comments
 (0)