1use cstree::{RawSyntaxKind, Syntax};
11
12pub const TOKEN_START: u32 = 0x0000;
13pub const TOKEN_END: u32 = 0x03ff;
14pub const DIALECT_TOKEN_START: u32 = 0x0400;
15pub const DIALECT_TOKEN_END: u32 = 0x04ff;
16pub const NODE_START: u32 = 0x1000;
17pub const NODE_END: u32 = 0x13ff;
18pub const DIALECT_NODE_START: u32 = 0x1400;
19pub const DIALECT_NODE_END: u32 = 0x14ff;
20pub const BOGUS_START: u32 = 0x2000;
21pub const BOGUS_END: u32 = 0x20ff;
22pub const MARKER_START: u32 = 0x2100;
23pub const MARKER_END: u32 = 0x21ff;
24
25const _: () = {
26 assert!(TOKEN_END < DIALECT_TOKEN_START);
27 assert!(DIALECT_TOKEN_END < NODE_START);
28 assert!(NODE_END < DIALECT_NODE_START);
29 assert!(DIALECT_NODE_END < BOGUS_START);
30 assert!(BOGUS_END < MARKER_START);
31};
32
33pub type SyntaxNode<D = ()> = cstree::syntax::SyntaxNode<SyntaxKind, D>;
34pub type SyntaxToken<D = ()> = cstree::syntax::SyntaxToken<SyntaxKind, D>;
35pub type SyntaxElement<D = ()> = cstree::syntax::SyntaxElement<SyntaxKind, D>;
36pub type SyntaxElementRef<'a, D = ()> = cstree::syntax::SyntaxElementRef<'a, SyntaxKind, D>;
37
38macro_rules! syntax_kinds {
39 ($($name:ident = $value:expr,)+) => {
40 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
41 #[repr(u32)]
42 pub enum SyntaxKind {
43 $($name = $value,)+
44 }
45
46 impl SyntaxKind {
47 pub const ALL: &'static [Self] = &[$(Self::$name,)+];
48
49 pub const fn as_u32(self) -> u32 {
50 self as u32
51 }
52
53 pub fn from_raw_kind(raw: u32) -> Option<Self> {
54 let mut index = 0;
55 while index < Self::ALL.len() {
56 let kind = Self::ALL[index];
57 if kind.as_u32() == raw {
58 return Some(kind);
59 }
60 index += 1;
61 }
62 None
63 }
64
65 pub const fn is_token(self) -> bool {
66 let raw = self.as_u32();
67 (raw >= TOKEN_START && raw <= TOKEN_END)
68 || (raw >= DIALECT_TOKEN_START && raw <= DIALECT_TOKEN_END)
69 }
70
71 pub const fn is_node(self) -> bool {
72 let raw = self.as_u32();
73 (raw >= NODE_START && raw <= NODE_END)
74 || (raw >= DIALECT_NODE_START && raw <= DIALECT_NODE_END)
75 }
76
77 pub const fn is_bogus(self) -> bool {
78 let raw = self.as_u32();
79 raw >= BOGUS_START && raw <= BOGUS_END
80 }
81
82 pub const fn is_marker(self) -> bool {
83 let raw = self.as_u32();
84 raw >= MARKER_START && raw <= MARKER_END
85 }
86
87 pub const fn is_dialect_specific(self) -> bool {
88 let raw = self.as_u32();
89 (raw >= DIALECT_TOKEN_START && raw <= DIALECT_TOKEN_END)
90 || (raw >= DIALECT_NODE_START && raw <= DIALECT_NODE_END)
91 }
92
93 pub const fn is_dialect(self) -> bool {
94 self.is_dialect_specific()
95 }
96
97 pub const fn is_trivia(self) -> bool {
98 matches!(
99 self,
100 Self::Whitespace
101 | Self::LineComment
102 | Self::BlockComment
103 | Self::SassIndentedNewline
104 )
105 }
106 }
107 };
108}
109
110syntax_kinds! {
111 Whitespace = 0x0000,
112 LineComment = 0x0001,
113 BlockComment = 0x0002,
114 Ident = 0x0003,
115 Hash = 0x0004,
116 String = 0x0005,
117 BadString = 0x0006,
118 Url = 0x0007,
119 BadUrl = 0x0008,
120 Number = 0x0009,
121 Percentage = 0x000a,
122 Dimension = 0x000b,
123 UnicodeRange = 0x000c,
124 AtKeyword = 0x000d,
125 Delim = 0x000e,
126 Important = 0x000f,
127 Dot = 0x0010,
128 Comma = 0x0011,
129 Colon = 0x0012,
130 Semicolon = 0x0013,
131 LeftBrace = 0x0014,
132 RightBrace = 0x0015,
133 LeftParen = 0x0016,
134 RightParen = 0x0017,
135 LeftBracket = 0x0018,
136 RightBracket = 0x0019,
137 Plus = 0x001a,
138 Minus = 0x001b,
139 Star = 0x001c,
140 Slash = 0x001d,
141 Percent = 0x001e,
142 Equals = 0x001f,
143 Tilde = 0x0020,
144 Pipe = 0x0021,
145 Caret = 0x0022,
146 Dollar = 0x0023,
147 Ampersand = 0x0024,
148 GreaterThan = 0x0025,
149 LessThan = 0x0026,
150 PlusEquals = 0x0027,
151 MinusEquals = 0x0028,
152 StarEquals = 0x0029,
153 SlashEquals = 0x002a,
154 PipeEquals = 0x002b,
155 TildeEquals = 0x002c,
156 CaretEquals = 0x002d,
157 DollarEquals = 0x002e,
158 DoubleColon = 0x002f,
159 DoublePipe = 0x0030,
160 DoubleAmpersand = 0x0031,
161 Arrow = 0x0032,
162 IncludesMatch = 0x0033,
163 DashMatch = 0x0034,
164 PrefixMatch = 0x0035,
165 SuffixMatch = 0x0036,
166 SubstringMatch = 0x0037,
167 ColumnCombinator = 0x0038,
168 NestingSelector = 0x0039,
169 CustomPropertyName = 0x003a,
170 ClassName = 0x003b,
171 IdName = 0x003c,
172 KeywordAnd = 0x003d,
173 KeywordOr = 0x003e,
174 KeywordNot = 0x003f,
175 KeywordOnly = 0x0040,
176 KeywordFrom = 0x0041,
177 KeywordTo = 0x0042,
178 KeywordThrough = 0x0043,
179 KeywordImportant = 0x0044,
180 KeywordGlobal = 0x0045,
181 KeywordLocal = 0x0046,
182 KeywordExport = 0x0047,
183 KeywordImport = 0x0048,
184 KeywordComposes = 0x0049,
185 KeywordAs = 0x004a,
186 KeywordWith = 0x004b,
187 KeywordLayer = 0x004c,
188 KeywordSupports = 0x004d,
189 KeywordContainer = 0x004e,
190 KeywordScope = 0x004f,
191 KeywordMedia = 0x0050,
192 KeywordKeyframes = 0x0051,
193 KeywordCharset = 0x0052,
194 KeywordNamespace = 0x0053,
195 KeywordPage = 0x0054,
196 KeywordFontFace = 0x0055,
197 KeywordProperty = 0x0056,
198 KeywordStartingStyle = 0x0057,
199 KeywordWhen = 0x0058,
200 KeywordElse = 0x0059,
201 KeywordUse = 0x005a,
202 KeywordForward = 0x005b,
203 KeywordMixin = 0x005c,
204 KeywordInclude = 0x005d,
205 KeywordFunction = 0x005e,
206 KeywordReturn = 0x005f,
207 KeywordIf = 0x0060,
208 KeywordEach = 0x0061,
209 KeywordFor = 0x0062,
210 KeywordWhile = 0x0063,
211 KeywordIn = 0x0064,
212 Cdo = 0x0065,
213 Cdc = 0x0066,
214
215 ScssVariable = 0x0400,
216 ScssInterpolationStart = 0x0401,
217 ScssInterpolationEnd = 0x0402,
218 ScssSilentComment = 0x0403,
219 ScssPlaceholder = 0x0404,
220 ScssModuleNamespace = 0x0405,
221 SassIndentedNewline = 0x0406,
222 SassIndent = 0x0407,
223 SassDedent = 0x0408,
224 SassOptionalSemicolon = 0x0409,
225 LessVariable = 0x0410,
226 LessEscapedString = 0x0411,
227 LessDetachedRuleset = 0x0412,
228 LessMixinGuardWhen = 0x0413,
229 LessExtendKeyword = 0x0414,
230 LessNamespaceSeparator = 0x0415,
231 LessInterpolationStart = 0x0416,
232 LessInterpolationEnd = 0x0417,
233 LessPropertyVariableToken = 0x0418,
234
235 Stylesheet = 0x1000,
236 Rule = 0x1001,
237 QualifiedRule = 0x1002,
238 Declaration = 0x1003,
239 DeclarationList = 0x1004,
240 RuleList = 0x1005,
241 SelectorList = 0x1006,
242 Selector = 0x1007,
243 ComplexSelector = 0x1008,
244 CompoundSelector = 0x1009,
245 ClassSelector = 0x100a,
246 IdSelector = 0x100b,
247 TypeSelector = 0x100c,
248 UniversalSelector = 0x100d,
249 AttributeSelector = 0x100e,
250 AttributeMatcher = 0x100f,
251 PseudoClassSelector = 0x1010,
252 PseudoElementSelector = 0x1011,
253 PseudoSelectorArgument = 0x1012,
254 NestingSelectorNode = 0x1013,
255 Combinator = 0x1014,
256 SelectorValue = 0x1015,
257 PropertyName = 0x1016,
258 CustomPropertyDeclaration = 0x1017,
259 Value = 0x1018,
260 ValueList = 0x1019,
261 FunctionCall = 0x101a,
262 FunctionArguments = 0x101b,
263 BinaryExpression = 0x101c,
264 UnaryExpression = 0x101d,
265 ParenthesizedExpression = 0x101e,
266 Interpolation = 0x101f,
267 DimensionValue = 0x1020,
268 ColorValue = 0x1021,
269 UrlValue = 0x1022,
270 VarFunction = 0x1023,
271 CalcFunction = 0x1024,
272 AtRule = 0x1025,
273 MediaRule = 0x1026,
274 SupportsRule = 0x1027,
275 ContainerRule = 0x1028,
276 LayerRule = 0x1029,
277 ScopeRule = 0x102a,
278 KeyframesRule = 0x102b,
279 KeyframeBlock = 0x102c,
280 FontFaceRule = 0x102d,
281 PageRule = 0x102e,
282 NamespaceRule = 0x102f,
283 ImportRule = 0x1030,
284 CharsetRule = 0x1031,
285 PropertyRule = 0x1032,
286 StartingStyleRule = 0x1033,
287 MediaQueryList = 0x1034,
288 MediaQuery = 0x1035,
289 MediaFeature = 0x1036,
290 SupportsCondition = 0x1037,
291 ContainerCondition = 0x1038,
292 LayerName = 0x1039,
293 ScopeRange = 0x103a,
294 CssModuleLocalBlock = 0x103b,
295 CssModuleGlobalBlock = 0x103c,
296 CssModuleExportBlock = 0x103d,
297 CssModuleImportBlock = 0x103e,
298 CssModuleComposesDeclaration = 0x103f,
299 CssModuleComposesTarget = 0x1040,
300 CssModuleFromClause = 0x1041,
301 TokenDefinition = 0x1042,
302 TokenReference = 0x1043,
303 Comment = 0x1044,
304 ErrorNode = 0x1045,
305 EnvFunction = 0x1046,
306 AttrFunction = 0x1047,
307 MathFunction = 0x1048,
308 PageMarginRule = 0x1049,
309 WhenRule = 0x104a,
310 ElseRule = 0x104b,
311 CounterStyleRule = 0x104c,
312 FontPaletteValuesRule = 0x104d,
313 ColorProfileRule = 0x104e,
314 PositionTryRule = 0x104f,
315 FontFeatureValuesRule = 0x1050,
316 FontFeatureValuesStylisticRule = 0x1051,
317 FontFeatureValuesStylesetRule = 0x1052,
318 FontFeatureValuesCharacterVariantRule = 0x1053,
319 FontFeatureValuesSwashRule = 0x1054,
320 FontFeatureValuesOrnamentsRule = 0x1055,
321 FontFeatureValuesAnnotationRule = 0x1056,
322 FontFeatureValuesHistoricalFormsRule = 0x1057,
323 ViewTransitionRule = 0x1058,
324 GradientFunction = 0x1059,
325 TransformFunction = 0x105a,
326 FilterFunction = 0x105b,
327 ImageFunction = 0x105c,
328 ShapeFunction = 0x105d,
329 AtRulePrelude = 0x105e,
330 NestRule = 0x105f,
331 CustomMediaRule = 0x1060,
332 IdentifierValue = 0x1061,
333 StringValue = 0x1062,
334 UnicodeRangeValue = 0x1063,
335 NumberValue = 0x1064,
336 PercentageValue = 0x1065,
337 BracketedValue = 0x1066,
338 ImportantAnnotation = 0x1067,
339 ComponentValue = 0x1068,
340 SimpleBlock = 0x1069,
341 ComponentValueList = 0x106a,
342 CommaSeparatedComponentValueList = 0x106b,
343 CustomPropertyValue = 0x106c,
344 AttributeName = 0x106d,
345 AttributeValue = 0x106e,
346 AttributeModifier = 0x106f,
347 NthSelectorArgument = 0x1070,
348 NthSelectorFormula = 0x1071,
349 NthSelectorOfSelectorList = 0x1072,
350 RelativeSelectorList = 0x1073,
351 RelativeSelector = 0x1074,
352 LanguageSelectorArgument = 0x1075,
353 LanguageTag = 0x1076,
354 DirectionalitySelectorArgument = 0x1077,
355 NamespacePrefix = 0x1078,
356
357 ScssStylesheet = 0x1400,
358 ScssUseRule = 0x1401,
359 ScssForwardRule = 0x1402,
360 ScssMixinDeclaration = 0x1403,
361 ScssIncludeRule = 0x1404,
362 ScssFunctionDeclaration = 0x1405,
363 ScssReturnRule = 0x1406,
364 ScssVariableDeclaration = 0x1407,
365 ScssVariableReference = 0x1408,
366 ScssPlaceholderSelector = 0x1409,
367 ScssExtendRule = 0x140a,
368 ScssControlIf = 0x140b,
369 ScssControlElse = 0x140c,
370 ScssControlEach = 0x140d,
371 ScssControlFor = 0x140e,
372 ScssControlWhile = 0x140f,
373 ScssNestedProperty = 0x1410,
374 ScssModuleConfig = 0x1411,
375 SassIndentedBlock = 0x1412,
376 SassIndentedRule = 0x1413,
377 ScssAtRootRule = 0x1414,
378 ScssErrorRule = 0x1415,
379 ScssWarnRule = 0x1416,
380 ScssDebugRule = 0x1417,
381 ScssContentRule = 0x1418,
382 ScssVariableFlag = 0x1419,
383 LessStylesheet = 0x1420,
384 LessVariableDeclaration = 0x1421,
385 LessVariableReference = 0x1422,
386 LessMixinDeclaration = 0x1423,
387 LessMixinCall = 0x1424,
388 LessMixinGuard = 0x1425,
389 LessDetachedRulesetNode = 0x1426,
390 LessExtendRule = 0x1427,
391 LessNamespaceAccess = 0x1428,
392 LessPropertyVariable = 0x1429,
393
394 BogusToken = 0x2000,
395 BogusTrivia = 0x2001,
396 BogusRule = 0x2002,
397 BogusSelector = 0x2003,
398 BogusSelectorList = 0x2004,
399 BogusCompoundSelector = 0x2005,
400 BogusCombinator = 0x2006,
401 BogusDeclaration = 0x2007,
402 BogusDeclarationList = 0x2008,
403 BogusPropertyName = 0x2009,
404 BogusValue = 0x200a,
405 BogusValueList = 0x200b,
406 BogusFunctionCall = 0x200c,
407 BogusFunctionArguments = 0x200d,
408 BogusAtRule = 0x200e,
409 BogusMediaQuery = 0x200f,
410 BogusSupportsCondition = 0x2010,
411 BogusContainerCondition = 0x2011,
412 BogusLayerName = 0x2012,
413 BogusScopeRange = 0x2013,
414 BogusKeyframeBlock = 0x2014,
415 BogusCssModuleBlock = 0x2015,
416 BogusComposesDeclaration = 0x2016,
417 BogusComposesTarget = 0x2017,
418 BogusFromClause = 0x2018,
419 BogusInterpolation = 0x2019,
420 BogusScssVariable = 0x201a,
421 BogusScssMixin = 0x201b,
422 BogusScssFunction = 0x201c,
423 BogusScssControl = 0x201d,
424 BogusSassIndentation = 0x201e,
425 BogusLessVariable = 0x201f,
426 BogusLessMixin = 0x2020,
427 BogusLessGuard = 0x2021,
428 BogusLessDetachedRuleset = 0x2022,
429 BogusRecovery = 0x2023,
430 BogusScssModuleConfig = 0x2024,
431 BogusAtRulePrelude = 0x2025,
432 BogusBracketedValue = 0x2026,
433 BogusSimpleBlock = 0x2027,
434
435 Root = 0x2100,
436 Eof = 0x2101,
437 Unknown = 0x21fe,
438 Tombstone = 0x21ff,
439}
440
441impl Syntax for SyntaxKind {
442 fn from_raw(raw: RawSyntaxKind) -> Self {
443 match Self::from_raw_kind(raw.0) {
444 Some(kind) => kind,
445 None => Self::Unknown,
446 }
447 }
448
449 fn into_raw(self) -> RawSyntaxKind {
450 RawSyntaxKind(self.as_u32())
451 }
452
453 fn static_text(self) -> Option<&'static str> {
454 match self {
455 Self::Dot => Some("."),
456 Self::Comma => Some(","),
457 Self::Colon => Some(":"),
458 Self::Semicolon => Some(";"),
459 Self::LeftBrace => Some("{"),
460 Self::RightBrace => Some("}"),
461 Self::LeftParen => Some("("),
462 Self::RightParen => Some(")"),
463 Self::LeftBracket => Some("["),
464 Self::RightBracket => Some("]"),
465 Self::Plus => Some("+"),
466 Self::Minus => Some("-"),
467 Self::Star => Some("*"),
468 Self::Slash => Some("/"),
469 Self::Percent => Some("%"),
470 Self::Equals => Some("="),
471 Self::Tilde => Some("~"),
472 Self::Pipe => Some("|"),
473 Self::Caret => Some("^"),
474 Self::Dollar => Some("$"),
475 Self::Ampersand => Some("&"),
476 Self::GreaterThan => Some(">"),
477 Self::LessThan => Some("<"),
478 Self::PlusEquals => Some("+="),
479 Self::MinusEquals => Some("-="),
480 Self::StarEquals => Some("*="),
481 Self::SlashEquals => Some("/="),
482 Self::PipeEquals => Some("|="),
483 Self::TildeEquals => Some("~="),
484 Self::CaretEquals => Some("^="),
485 Self::DollarEquals => Some("$="),
486 Self::DoubleColon => Some("::"),
487 Self::DoublePipe => Some("||"),
488 Self::DoubleAmpersand => Some("&&"),
489 Self::Arrow => Some("=>"),
490 Self::IncludesMatch => Some("~="),
491 Self::DashMatch => Some("|="),
492 Self::PrefixMatch => Some("^="),
493 Self::SuffixMatch => Some("$="),
494 Self::SubstringMatch => Some("*="),
495 Self::ColumnCombinator => Some("||"),
496 Self::KeywordAnd => Some("and"),
497 Self::KeywordOr => Some("or"),
498 Self::KeywordNot => Some("not"),
499 Self::KeywordOnly => Some("only"),
500 Self::KeywordFrom => Some("from"),
501 Self::KeywordTo => Some("to"),
502 Self::KeywordThrough => Some("through"),
503 Self::KeywordImportant => Some("important"),
504 Self::Cdo => Some("<!--"),
505 Self::Cdc => Some("-->"),
506 Self::KeywordGlobal => Some("global"),
507 Self::KeywordLocal => Some("local"),
508 Self::KeywordExport => Some("export"),
509 Self::KeywordImport => Some("import"),
510 Self::KeywordComposes => Some("composes"),
511 Self::KeywordAs => Some("as"),
512 Self::KeywordWith => Some("with"),
513 Self::KeywordLayer => Some("layer"),
514 Self::KeywordSupports => Some("supports"),
515 Self::KeywordContainer => Some("container"),
516 Self::KeywordScope => Some("scope"),
517 Self::KeywordMedia => Some("media"),
518 Self::KeywordKeyframes => Some("keyframes"),
519 Self::KeywordCharset => Some("charset"),
520 Self::KeywordNamespace => Some("namespace"),
521 Self::KeywordPage => Some("page"),
522 Self::KeywordFontFace => Some("font-face"),
523 Self::KeywordProperty => Some("property"),
524 Self::KeywordStartingStyle => Some("starting-style"),
525 Self::KeywordWhen => Some("when"),
526 Self::KeywordElse => Some("else"),
527 Self::KeywordUse => Some("use"),
528 Self::KeywordForward => Some("forward"),
529 Self::KeywordMixin => Some("mixin"),
530 Self::KeywordInclude => Some("include"),
531 Self::KeywordFunction => Some("function"),
532 Self::KeywordReturn => Some("return"),
533 Self::KeywordIf => Some("if"),
534 Self::KeywordEach => Some("each"),
535 Self::KeywordFor => Some("for"),
536 Self::KeywordWhile => Some("while"),
537 Self::KeywordIn => Some("in"),
538 Self::Eof => Some(""),
539 _ => None,
540 }
541 }
542}
543
544#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
545pub enum StyleDialect {
546 Css,
547 Scss,
548 Sass,
549 Less,
550}
551
552impl StyleDialect {
553 pub const ALL: &'static [Self] = &[Self::Css, Self::Scss, Self::Sass, Self::Less];
554}
555
556#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
557pub enum ModuleMode {
558 Plain,
559 CssModules,
560}
561
562impl ModuleMode {
563 pub const ALL: &'static [Self] = &[Self::Plain, Self::CssModules];
564}
565
566#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
567pub enum SymbolKind {
568 Class,
569 Id,
570 TypeSelector,
571 PlaceholderSelector,
572 Keyframes,
573 CustomProperty,
574 ScssVariable,
575 LessVariable,
576 Mixin,
577 Function,
578 ValueDeclaration,
579 ComposesTarget,
580 Namespace,
581 Layer,
582 Container,
583 Scope,
584 Import,
585 Export,
586 ModuleLocal,
587 ModuleGlobal,
588}
589
590impl SymbolKind {
591 pub const ALL: &'static [Self] = &[
592 Self::Class,
593 Self::Id,
594 Self::TypeSelector,
595 Self::PlaceholderSelector,
596 Self::Keyframes,
597 Self::CustomProperty,
598 Self::ScssVariable,
599 Self::LessVariable,
600 Self::Mixin,
601 Self::Function,
602 Self::ValueDeclaration,
603 Self::ComposesTarget,
604 Self::Namespace,
605 Self::Layer,
606 Self::Container,
607 Self::Scope,
608 Self::Import,
609 Self::Export,
610 Self::ModuleLocal,
611 Self::ModuleGlobal,
612 ];
613}
614
615#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
616pub enum ScopeKind {
617 File,
618 LocalBlock,
619 GlobalBlock,
620 SelectorBlock,
621 MixinBody,
622 FunctionBody,
623 AtRuleScope,
624 NestedRule,
625 ScopeAtRule,
626 MediaQuery,
627 SupportsQuery,
628 ContainerQuery,
629 CascadeLayer,
630 ModuleNamespace,
631 LessMixin,
632 SassControlFlow,
633 CssModuleExport,
634 CssModuleImport,
635}
636
637impl ScopeKind {
638 pub const ALL: &'static [Self] = &[
639 Self::File,
640 Self::LocalBlock,
641 Self::GlobalBlock,
642 Self::SelectorBlock,
643 Self::MixinBody,
644 Self::FunctionBody,
645 Self::AtRuleScope,
646 Self::NestedRule,
647 Self::ScopeAtRule,
648 Self::MediaQuery,
649 Self::SupportsQuery,
650 Self::ContainerQuery,
651 Self::CascadeLayer,
652 Self::ModuleNamespace,
653 Self::LessMixin,
654 Self::SassControlFlow,
655 Self::CssModuleExport,
656 Self::CssModuleImport,
657 ];
658}
659
660#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
661pub enum ReferenceKind {
662 Class,
663 Id,
664 TypeSelector,
665 PlaceholderSelector,
666 Keyframes,
667 ComposesTarget,
668 ComposesFrom,
669 CustomPropertyRead,
670 VarRead,
671 ValueRead,
672 Import,
673 Export,
674 MixinInclude,
675 FunctionCall,
676 NamespaceMember,
677 Layer,
678 Container,
679 SelectorExtends,
680 CssModuleAccess,
681 CssModuleToken,
682}
683
684impl ReferenceKind {
685 pub const ALL: &'static [Self] = &[
686 Self::Class,
687 Self::Id,
688 Self::TypeSelector,
689 Self::PlaceholderSelector,
690 Self::Keyframes,
691 Self::ComposesTarget,
692 Self::ComposesFrom,
693 Self::CustomPropertyRead,
694 Self::VarRead,
695 Self::ValueRead,
696 Self::Import,
697 Self::Export,
698 Self::MixinInclude,
699 Self::FunctionCall,
700 Self::NamespaceMember,
701 Self::Layer,
702 Self::Container,
703 Self::SelectorExtends,
704 Self::CssModuleAccess,
705 Self::CssModuleToken,
706 ];
707}
708
709#[derive(Debug, Clone, PartialEq, Eq)]
710pub struct OmenaSyntaxBoundarySummaryV0 {
711 pub schema_version: &'static str,
712 pub product: &'static str,
713 pub phase: &'static str,
714 pub syntax_kind_owner_crate: &'static str,
715 pub parser_consumer_policy: &'static str,
716 pub syntax_kind_count: usize,
717 pub token_kind_count: usize,
718 pub node_kind_count: usize,
719 pub bogus_kind_count: usize,
720 pub marker_kind_count: usize,
721 pub dialect_kind_count: usize,
722 pub style_dialect_count: usize,
723 pub module_mode_count: usize,
724 pub symbol_kind_count: usize,
725 pub scope_kind_count: usize,
726 pub reference_kind_count: usize,
727 pub cstree_integration_ready: bool,
728 pub ready_surfaces: Vec<&'static str>,
729 pub next_surfaces: Vec<&'static str>,
730}
731
732pub fn summarize_omena_syntax_boundary() -> OmenaSyntaxBoundarySummaryV0 {
733 OmenaSyntaxBoundarySummaryV0 {
734 schema_version: "0",
735 product: "omena-syntax.boundary",
736 phase: "h1-alpha-syntax-substrate",
737 syntax_kind_owner_crate: "omena-syntax",
738 parser_consumer_policy: "parserConsumesOmenaSyntaxKindNoLocalTaxonomy",
739 syntax_kind_count: SyntaxKind::ALL.len(),
740 token_kind_count: SyntaxKind::ALL
741 .iter()
742 .filter(|kind| kind.is_token())
743 .count(),
744 node_kind_count: SyntaxKind::ALL.iter().filter(|kind| kind.is_node()).count(),
745 bogus_kind_count: SyntaxKind::ALL
746 .iter()
747 .filter(|kind| kind.is_bogus())
748 .count(),
749 marker_kind_count: SyntaxKind::ALL
750 .iter()
751 .filter(|kind| kind.is_marker())
752 .count(),
753 dialect_kind_count: SyntaxKind::ALL
754 .iter()
755 .filter(|kind| kind.is_dialect())
756 .count(),
757 style_dialect_count: StyleDialect::ALL.len(),
758 module_mode_count: ModuleMode::ALL.len(),
759 symbol_kind_count: SymbolKind::ALL.len(),
760 scope_kind_count: ScopeKind::ALL.len(),
761 reference_kind_count: ReferenceKind::ALL.len(),
762 cstree_integration_ready: SyntaxKind::Ident.into_raw()
763 == RawSyntaxKind(SyntaxKind::Ident.as_u32())
764 && SyntaxKind::from_raw(RawSyntaxKind(SyntaxKind::Ident.as_u32())) == SyntaxKind::Ident,
765 ready_surfaces: vec![
766 "rangeDividedSyntaxKind",
767 "symbolScopeReferenceVocabulary",
768 "styleDialectAndModuleMode",
769 "cstreeRawKindBridge",
770 "bogusRecoveryKindSuperset",
771 "semanticSoaTables",
772 "parserCstEquivalence",
773 ],
774 next_surfaces: Vec::new(),
775 }
776}
777
778#[cfg(test)]
779mod tests {
780 use super::*;
781
782 #[test]
783 fn syntax_kind_ranges_are_disjoint() {
784 let mut raws: Vec<u32> = SyntaxKind::ALL.iter().map(|kind| kind.as_u32()).collect();
785 raws.sort_unstable();
786
787 for pair in raws.windows(2) {
788 assert_ne!(pair[0], pair[1]);
789 }
790 }
791
792 #[test]
793 fn classifies_token_node_bogus_marker_ranges() {
794 assert!(SyntaxKind::Ident.is_token());
795 assert!(SyntaxKind::ScssVariable.is_token());
796 assert!(SyntaxKind::Selector.is_node());
797 assert!(SyntaxKind::LessMixinCall.is_node());
798 assert!(SyntaxKind::BogusSelector.is_bogus());
799 assert!(SyntaxKind::Root.is_marker());
800 assert!(SyntaxKind::Whitespace.is_trivia());
801 assert!(SyntaxKind::ScssUseRule.is_dialect_specific());
802 }
803
804 #[test]
805 fn declares_four_style_dialects_and_module_modes() {
806 assert_eq!(StyleDialect::ALL.len(), 4);
807 assert_eq!(ModuleMode::ALL.len(), 2);
808 }
809
810 #[test]
811 fn cstree_round_trip_preserves_known_kinds() {
812 for kind in [
813 SyntaxKind::Ident,
814 SyntaxKind::Selector,
815 SyntaxKind::ScssUseRule,
816 SyntaxKind::BogusLessGuard,
817 SyntaxKind::Root,
818 ] {
819 let raw = kind.into_raw();
820 assert_eq!(SyntaxKind::from_raw(raw), kind);
821 }
822 }
823
824 #[test]
825 fn declares_bogus_superset_contract() {
826 let bogus_count = SyntaxKind::ALL
827 .iter()
828 .filter(|kind| kind.is_bogus())
829 .count();
830
831 assert!(bogus_count >= 33);
832 }
833
834 #[test]
835 fn syntax_kind_count_tracks_phase_alpha_contract() {
836 let token_count = SyntaxKind::ALL
837 .iter()
838 .filter(|kind| kind.is_token())
839 .count();
840 let node_count = SyntaxKind::ALL.iter().filter(|kind| kind.is_node()).count();
841
842 assert!(SyntaxKind::ALL.len() >= 160);
843 assert!(token_count >= 80);
844 assert!(node_count >= 80);
845 }
846
847 #[test]
848 fn summarizes_phase_alpha_boundary_contract() {
849 let summary = summarize_omena_syntax_boundary();
850
851 assert_eq!(summary.product, "omena-syntax.boundary");
852 assert_eq!(summary.phase, "h1-alpha-syntax-substrate");
853 assert_eq!(summary.syntax_kind_owner_crate, "omena-syntax");
854 assert_eq!(
855 summary.parser_consumer_policy,
856 "parserConsumesOmenaSyntaxKindNoLocalTaxonomy"
857 );
858 assert!(summary.syntax_kind_count >= 160);
859 assert!(summary.bogus_kind_count >= 33);
860 assert_eq!(summary.style_dialect_count, 4);
861 assert_eq!(summary.module_mode_count, 2);
862 assert_eq!(summary.symbol_kind_count, SymbolKind::ALL.len());
863 assert_eq!(summary.scope_kind_count, ScopeKind::ALL.len());
864 assert_eq!(summary.reference_kind_count, ReferenceKind::ALL.len());
865 assert!(summary.cstree_integration_ready);
866 assert!(SyntaxKind::ScssUseRule.is_dialect());
867 assert!(
868 summary
869 .ready_surfaces
870 .contains(&"symbolScopeReferenceVocabulary")
871 );
872 assert!(summary.ready_surfaces.contains(&"semanticSoaTables"));
873 assert!(summary.ready_surfaces.contains(&"parserCstEquivalence"));
874 assert!(!summary.next_surfaces.contains(&"semanticSoaTables"));
875 assert!(!summary.next_surfaces.contains(&"parserCstEquivalence"));
876 }
877}