leo_parser_rowan/syntax_kind.rs
1// Copyright (C) 2019-2026 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17//! Syntax kind definitions for the rowan-based Leo parser.
18//!
19//! This module defines a flat `SyntaxKind` enum containing all token and node
20//! types used in the Leo syntax tree. The enum is `#[repr(u16)]` for
21//! compatibility with rowan's internal representation.
22
23// Re-export the variants to make the `SyntaxKind` helper method implementations
24// a bit less noisey.
25use SyntaxKind::*;
26
27/// All syntax kinds for Leo tokens and nodes.
28///
29/// This enum is intentionally flat (not nested) to satisfy rowan's requirement
30/// for a `#[repr(u16)]` type. Categories are indicated by comments and helper
31/// methods like `is_trivia()` and `is_keyword()`.
32#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
33#[repr(u16)]
34#[allow(non_camel_case_types)]
35pub enum SyntaxKind {
36 // ==========================================================================
37 // Special
38 // ==========================================================================
39 /// Error node for wrapping parse errors and invalid tokens.
40 ERROR = 0,
41 /// End of file marker.
42 EOF,
43
44 // ==========================================================================
45 // Trivia (whitespace and comments)
46 // ==========================================================================
47 /// Horizontal whitespace: spaces, tabs, form feeds.
48 WHITESPACE,
49 /// Line breaks: \n or \r\n.
50 LINEBREAK,
51 /// Line comment: // ...
52 COMMENT_LINE,
53 /// Block comment: /* ... */
54 COMMENT_BLOCK,
55
56 // ==========================================================================
57 // Literals
58 // ==========================================================================
59 /// Integer literal: 123, 0xFF, 0b101, 0o77
60 INTEGER,
61 /// String literal: "..."
62 STRING,
63 /// Address literal: aleo1...
64 ADDRESS_LIT,
65
66 // ==========================================================================
67 // Identifiers
68 // ==========================================================================
69 /// Identifier: foo, Bar, _baz
70 /// Note: Complex identifiers (paths, program IDs, locators) are deferred
71 /// to Phase 2. The lexer produces simple IDENT tokens; the parser handles
72 /// disambiguation of foo::bar, foo.aleo, foo.aleo/bar patterns.
73 IDENT,
74
75 // ==========================================================================
76 // Keywords - Literals
77 // ==========================================================================
78 /// `true`
79 KW_TRUE,
80 /// `false`
81 KW_FALSE,
82 /// `none`
83 KW_NONE,
84
85 // ==========================================================================
86 // Keywords - Types
87 // ==========================================================================
88 /// `address`
89 KW_ADDRESS,
90 /// `bool`
91 KW_BOOL,
92 /// `field`
93 KW_FIELD,
94 /// `group`
95 KW_GROUP,
96 /// `scalar`
97 KW_SCALAR,
98 /// `signature`
99 KW_SIGNATURE,
100 /// `string`
101 KW_STRING,
102 /// `record`
103 KW_RECORD,
104 /// `Future`
105 KW_FUTURE,
106 /// `i8`
107 KW_I8,
108 /// `i16`
109 KW_I16,
110 /// `i32`
111 KW_I32,
112 /// `i64`
113 KW_I64,
114 /// `i128`
115 KW_I128,
116 /// `u8`
117 KW_U8,
118 /// `u16`
119 KW_U16,
120 /// `u32`
121 KW_U32,
122 /// `u64`
123 KW_U64,
124 /// `u128`
125 KW_U128,
126
127 // ==========================================================================
128 // Keywords - Control Flow
129 // ==========================================================================
130 /// `if`
131 KW_IF,
132 /// `else`
133 KW_ELSE,
134 /// `for`
135 KW_FOR,
136 /// `in`
137 KW_IN,
138 /// `return`
139 KW_RETURN,
140
141 // ==========================================================================
142 // Keywords - Declarations
143 // ==========================================================================
144 /// `let`
145 KW_LET,
146 /// `const`
147 KW_CONST,
148 /// `constant`
149 KW_CONSTANT,
150 /// `function`
151 KW_FUNCTION,
152 /// `transition`
153 KW_TRANSITION,
154 /// `inline`
155 KW_INLINE,
156 /// `async`
157 KW_ASYNC,
158 /// `Fn`
159 KW_FN,
160 /// `struct`
161 KW_STRUCT,
162 /// `constructor`
163 KW_CONSTRUCTOR,
164
165 // ==========================================================================
166 // Keywords - Program Structure
167 // ==========================================================================
168 /// `program`
169 KW_PROGRAM,
170 /// `import`
171 KW_IMPORT,
172 /// `mapping`
173 KW_MAPPING,
174 /// `storage`
175 KW_STORAGE,
176 /// `network`
177 KW_NETWORK,
178 /// `aleo`
179 KW_ALEO,
180 /// `script`
181 KW_SCRIPT,
182 /// `block`
183 KW_BLOCK,
184
185 // ==========================================================================
186 // Keywords - Visibility & Assertions
187 // ==========================================================================
188 /// `public`
189 KW_PUBLIC,
190 /// `private`
191 KW_PRIVATE,
192 /// `as`
193 KW_AS,
194 /// `self`
195 KW_SELF,
196 /// `assert`
197 KW_ASSERT,
198 /// `assert_eq`
199 KW_ASSERT_EQ,
200 /// `assert_neq`
201 KW_ASSERT_NEQ,
202
203 // ==========================================================================
204 // Punctuation - Delimiters
205 // ==========================================================================
206 /// `(`
207 L_PAREN,
208 /// `)`
209 R_PAREN,
210 /// `[`
211 L_BRACKET,
212 /// `]`
213 R_BRACKET,
214 /// `{`
215 L_BRACE,
216 /// `}`
217 R_BRACE,
218
219 // ==========================================================================
220 // Punctuation - Separators
221 // ==========================================================================
222 /// `,`
223 COMMA,
224 /// `.`
225 DOT,
226 /// `..`
227 DOT_DOT,
228 /// `;`
229 SEMICOLON,
230 /// `:`
231 COLON,
232 /// `::`
233 COLON_COLON,
234 /// `?`
235 QUESTION,
236 /// `->`
237 ARROW,
238 /// `=>`
239 FAT_ARROW,
240 /// `_`
241 UNDERSCORE,
242 /// `@`
243 AT,
244
245 // ==========================================================================
246 // Operators - Assignment
247 // ==========================================================================
248 /// `=`
249 EQ,
250 /// `+=`
251 PLUS_EQ,
252 /// `-=`
253 MINUS_EQ,
254 /// `*=`
255 STAR_EQ,
256 /// `/=`
257 SLASH_EQ,
258 /// `%=`
259 PERCENT_EQ,
260 /// `**=`
261 STAR2_EQ,
262 /// `&&=`
263 AMP2_EQ,
264 /// `||=`
265 PIPE2_EQ,
266 /// `&=`
267 AMP_EQ,
268 /// `|=`
269 PIPE_EQ,
270 /// `^=`
271 CARET_EQ,
272 /// `<<=`
273 SHL_EQ,
274 /// `>>=`
275 SHR_EQ,
276
277 // ==========================================================================
278 // Operators - Arithmetic
279 // ==========================================================================
280 /// `+`
281 PLUS,
282 /// `-`
283 MINUS,
284 /// `*`
285 STAR,
286 /// `/`
287 SLASH,
288 /// `%`
289 PERCENT,
290 /// `**`
291 STAR2,
292
293 // ==========================================================================
294 // Operators - Comparison
295 // ==========================================================================
296 /// `==`
297 EQ2,
298 /// `!=`
299 BANG_EQ,
300 /// `<`
301 LT,
302 /// `<=`
303 LT_EQ,
304 /// `>`
305 GT,
306 /// `>=`
307 GT_EQ,
308
309 // ==========================================================================
310 // Operators - Logical
311 // ==========================================================================
312 /// `&&`
313 AMP2,
314 /// `||`
315 PIPE2,
316 /// `!`
317 BANG,
318
319 // ==========================================================================
320 // Operators - Bitwise
321 // ==========================================================================
322 /// `&`
323 AMP,
324 /// `|`
325 PIPE,
326 /// `^`
327 CARET,
328 /// `<<`
329 SHL,
330 /// `>>`
331 SHR,
332
333 // ==========================================================================
334 // Composite Nodes - Top Level
335 // ==========================================================================
336 /// Root node of the syntax tree.
337 ROOT,
338 /// Program declaration: `program foo.aleo { ... }`
339 PROGRAM_DECL,
340 /// Import statement: `import foo.aleo;`
341 IMPORT,
342 /// Main file contents.
343 MAIN_CONTENTS,
344 /// Module file contents.
345 MODULE_CONTENTS,
346
347 // ==========================================================================
348 // Composite Nodes - Declarations
349 // ==========================================================================
350 /// Function definition.
351 FUNCTION_DEF,
352 /// Constructor definition.
353 CONSTRUCTOR_DEF,
354 /// Struct definition.
355 STRUCT_DEF,
356 /// Record definition.
357 RECORD_DEF,
358 /// Struct member declaration.
359 STRUCT_MEMBER,
360 /// Mapping definition.
361 MAPPING_DEF,
362 /// Storage definition.
363 STORAGE_DEF,
364 /// Global constant definition.
365 GLOBAL_CONST,
366
367 // ==========================================================================
368 // Composite Nodes - Function Parts
369 // ==========================================================================
370 /// Annotation: `@foo`
371 ANNOTATION,
372 /// Parameter in a function signature.
373 PARAM,
374 /// Parameter list: `(a: u32, b: u32)`
375 PARAM_LIST,
376 /// Function output type.
377 RETURN_TYPE,
378 /// Const generic parameter.
379 CONST_PARAM,
380 /// Const generic parameter list.
381 CONST_PARAM_LIST,
382 /// Const generic argument list.
383 CONST_ARG_LIST,
384
385 // ==========================================================================
386 // Composite Nodes - Statements
387 // ==========================================================================
388 /// Let statement: `let x = ...;`
389 LET_STMT,
390 /// Const statement: `const x = ...;`
391 CONST_STMT,
392 /// Return statement: `return ...;`
393 RETURN_STMT,
394 /// Expression statement: `foo();`
395 EXPR_STMT,
396 /// Assignment statement: `x = ...;`
397 ASSIGN_STMT,
398 /// If statement: `if ... { } else { }`
399 IF_STMT,
400 /// For loop: `for i in 0..10 { }`
401 FOR_STMT,
402 /// Block: `{ ... }`
403 BLOCK,
404 /// Assert statement: `assert(...);`
405 ASSERT_STMT,
406 /// Assert equals statement: `assert_eq(...);`
407 ASSERT_EQ_STMT,
408 /// Assert not equals statement: `assert_neq(...);`
409 ASSERT_NEQ_STMT,
410
411 // ==========================================================================
412 // Composite Nodes - Patterns
413 // ==========================================================================
414 /// Identifier pattern: `x`
415 IDENT_PATTERN,
416 /// Tuple pattern: `(a, b, c)`
417 TUPLE_PATTERN,
418 /// Wildcard pattern: `_`
419 WILDCARD_PATTERN,
420
421 // ==========================================================================
422 // Composite Nodes - Expressions
423 // ==========================================================================
424 /// Binary expression: `a + b`
425 BINARY_EXPR,
426 /// Unary expression: `!a`, `-a`
427 UNARY_EXPR,
428 /// Function call: `foo(a, b)`
429 CALL_EXPR,
430 /// Method call: `a.foo(b)`
431 METHOD_CALL_EXPR,
432 /// Member access: `a.b`
433 FIELD_EXPR,
434 /// Array/tuple index: `a[0]`
435 INDEX_EXPR,
436 /// Cast expression: `a as u32`
437 CAST_EXPR,
438 /// Ternary expression: `a ? b : c`
439 TERNARY_EXPR,
440 /// Array literal: `[1, 2, 3]`
441 ARRAY_EXPR,
442 /// Tuple literal: `(1, 2, 3)`
443 TUPLE_EXPR,
444 /// Struct literal: `Foo { a: 1, b: 2 }`
445 STRUCT_EXPR,
446 /// Struct field initializer: `a: 1`
447 STRUCT_FIELD_INIT,
448 /// Path expression: `foo::bar`
449 PATH_EXPR,
450 /// Parenthesized expression: `(a + b)`
451 PAREN_EXPR,
452 /// Literal expression (wraps INTEGER, STRING, ADDRESS_LIT, or keywords).
453 LITERAL,
454 /// Repeat expression: `[0u8; 32]`
455 REPEAT_EXPR,
456 /// Async expression: `async foo()`
457 ASYNC_EXPR,
458 /// Associated function call: `Foo::bar()`
459 ASSOC_FN_EXPR,
460 /// Associated constant: `Foo::BAR`
461 ASSOC_CONST_EXPR,
462 /// Locator expression: `foo.aleo/bar`
463 LOCATOR_EXPR,
464 /// Tuple access: `a.0`
465 TUPLE_ACCESS_EXPR,
466 /// Intrinsic expression: `_foo()`
467 INTRINSIC_EXPR,
468 /// Unit expression: `()`
469 UNIT_EXPR,
470
471 // ==========================================================================
472 // Composite Nodes - Types
473 // ==========================================================================
474 /// Named/path type: `u32`, `Foo`, `foo::Bar`
475 TYPE_PATH,
476 /// Array type: `[u32; 10]`
477 TYPE_ARRAY,
478 /// Tuple type: `(u32, u32)`
479 TYPE_TUPLE,
480 /// Optional type: `u32?` (Future feature)
481 TYPE_OPTIONAL,
482 /// Future type: `Future<Foo>`
483 TYPE_FUTURE,
484 /// Mapping type in storage.
485 TYPE_MAPPING,
486
487 // ==========================================================================
488 // Composite Nodes - Other
489 // ==========================================================================
490 /// Argument list: `(a, b, c)`
491 ARG_LIST,
492 /// Name reference (identifier in expression context).
493 NAME_REF,
494 /// Name definition (identifier in binding context).
495 NAME,
496 /// Visibility modifier: `public`, `private`
497 VISIBILITY,
498
499 // Sentinel for bounds checking (must be last)
500 #[doc(hidden)]
501 __LAST,
502}
503
504impl SyntaxKind {
505 /// Check if this is a trivia token (whitespace or comment).
506 pub fn is_trivia(self) -> bool {
507 matches!(self, WHITESPACE | LINEBREAK | COMMENT_LINE | COMMENT_BLOCK)
508 }
509
510 /// Check if this is a keyword.
511 pub fn is_keyword(self) -> bool {
512 matches!(
513 self,
514 KW_TRUE
515 | KW_FALSE
516 | KW_NONE
517 | KW_ADDRESS
518 | KW_BOOL
519 | KW_FIELD
520 | KW_GROUP
521 | KW_SCALAR
522 | KW_SIGNATURE
523 | KW_STRING
524 | KW_RECORD
525 | KW_FUTURE
526 | KW_I8
527 | KW_I16
528 | KW_I32
529 | KW_I64
530 | KW_I128
531 | KW_U8
532 | KW_U16
533 | KW_U32
534 | KW_U64
535 | KW_U128
536 | KW_IF
537 | KW_ELSE
538 | KW_FOR
539 | KW_IN
540 | KW_RETURN
541 | KW_LET
542 | KW_CONST
543 | KW_CONSTANT
544 | KW_FUNCTION
545 | KW_TRANSITION
546 | KW_INLINE
547 | KW_ASYNC
548 | KW_FN
549 | KW_STRUCT
550 | KW_CONSTRUCTOR
551 | KW_PROGRAM
552 | KW_IMPORT
553 | KW_MAPPING
554 | KW_STORAGE
555 | KW_NETWORK
556 | KW_ALEO
557 | KW_SCRIPT
558 | KW_BLOCK
559 | KW_PUBLIC
560 | KW_PRIVATE
561 | KW_AS
562 | KW_SELF
563 | KW_ASSERT
564 | KW_ASSERT_EQ
565 | KW_ASSERT_NEQ
566 )
567 }
568
569 /// Check if this is a type keyword.
570 pub fn is_type_keyword(self) -> bool {
571 matches!(
572 self,
573 KW_ADDRESS
574 | KW_BOOL
575 | KW_FIELD
576 | KW_GROUP
577 | KW_SCALAR
578 | KW_SIGNATURE
579 | KW_STRING
580 | KW_FUTURE
581 | KW_I8
582 | KW_I16
583 | KW_I32
584 | KW_I64
585 | KW_I128
586 | KW_U8
587 | KW_U16
588 | KW_U32
589 | KW_U64
590 | KW_U128
591 )
592 }
593
594 /// Check if this is a literal token.
595 pub fn is_literal(self) -> bool {
596 matches!(self, INTEGER | STRING | ADDRESS_LIT | KW_TRUE | KW_FALSE | KW_NONE)
597 }
598
599 /// Check if this is a punctuation token.
600 pub fn is_punctuation(self) -> bool {
601 matches!(
602 self,
603 L_PAREN
604 | R_PAREN
605 | L_BRACKET
606 | R_BRACKET
607 | L_BRACE
608 | R_BRACE
609 | COMMA
610 | DOT
611 | DOT_DOT
612 | SEMICOLON
613 | COLON
614 | COLON_COLON
615 | QUESTION
616 | ARROW
617 | FAT_ARROW
618 | UNDERSCORE
619 | AT
620 )
621 }
622
623 /// Check if this is an operator token.
624 pub fn is_operator(self) -> bool {
625 matches!(
626 self,
627 EQ | PLUS_EQ
628 | MINUS_EQ
629 | STAR_EQ
630 | SLASH_EQ
631 | PERCENT_EQ
632 | STAR2_EQ
633 | AMP2_EQ
634 | PIPE2_EQ
635 | AMP_EQ
636 | PIPE_EQ
637 | CARET_EQ
638 | SHL_EQ
639 | SHR_EQ
640 | PLUS
641 | MINUS
642 | STAR
643 | SLASH
644 | PERCENT
645 | STAR2
646 | EQ2
647 | BANG_EQ
648 | LT
649 | LT_EQ
650 | GT
651 | GT_EQ
652 | AMP2
653 | PIPE2
654 | BANG
655 | AMP
656 | PIPE
657 | CARET
658 | SHL
659 | SHR
660 )
661 }
662}
663
664impl From<SyntaxKind> for rowan::SyntaxKind {
665 fn from(kind: SyntaxKind) -> Self {
666 Self(kind as u16)
667 }
668}
669
670/// Lookup table for converting raw u16 values back to SyntaxKind.
671/// This avoids unsafe transmute by using an explicit array.
672const SYNTAX_KIND_TABLE: &[SyntaxKind] = &[
673 ERROR,
674 EOF,
675 WHITESPACE,
676 LINEBREAK,
677 COMMENT_LINE,
678 COMMENT_BLOCK,
679 INTEGER,
680 STRING,
681 ADDRESS_LIT,
682 IDENT,
683 KW_TRUE,
684 KW_FALSE,
685 KW_NONE,
686 KW_ADDRESS,
687 KW_BOOL,
688 KW_FIELD,
689 KW_GROUP,
690 KW_SCALAR,
691 KW_SIGNATURE,
692 KW_STRING,
693 KW_RECORD,
694 KW_FUTURE,
695 KW_I8,
696 KW_I16,
697 KW_I32,
698 KW_I64,
699 KW_I128,
700 KW_U8,
701 KW_U16,
702 KW_U32,
703 KW_U64,
704 KW_U128,
705 KW_IF,
706 KW_ELSE,
707 KW_FOR,
708 KW_IN,
709 KW_RETURN,
710 KW_LET,
711 KW_CONST,
712 KW_CONSTANT,
713 KW_FUNCTION,
714 KW_TRANSITION,
715 KW_INLINE,
716 KW_ASYNC,
717 KW_FN,
718 KW_STRUCT,
719 KW_CONSTRUCTOR,
720 KW_PROGRAM,
721 KW_IMPORT,
722 KW_MAPPING,
723 KW_STORAGE,
724 KW_NETWORK,
725 KW_ALEO,
726 KW_SCRIPT,
727 KW_BLOCK,
728 KW_PUBLIC,
729 KW_PRIVATE,
730 KW_AS,
731 KW_SELF,
732 KW_ASSERT,
733 KW_ASSERT_EQ,
734 KW_ASSERT_NEQ,
735 L_PAREN,
736 R_PAREN,
737 L_BRACKET,
738 R_BRACKET,
739 L_BRACE,
740 R_BRACE,
741 COMMA,
742 DOT,
743 DOT_DOT,
744 SEMICOLON,
745 COLON,
746 COLON_COLON,
747 QUESTION,
748 ARROW,
749 FAT_ARROW,
750 UNDERSCORE,
751 AT,
752 EQ,
753 PLUS_EQ,
754 MINUS_EQ,
755 STAR_EQ,
756 SLASH_EQ,
757 PERCENT_EQ,
758 STAR2_EQ,
759 AMP2_EQ,
760 PIPE2_EQ,
761 AMP_EQ,
762 PIPE_EQ,
763 CARET_EQ,
764 SHL_EQ,
765 SHR_EQ,
766 PLUS,
767 MINUS,
768 STAR,
769 SLASH,
770 PERCENT,
771 STAR2,
772 EQ2,
773 BANG_EQ,
774 LT,
775 LT_EQ,
776 GT,
777 GT_EQ,
778 AMP2,
779 PIPE2,
780 BANG,
781 AMP,
782 PIPE,
783 CARET,
784 SHL,
785 SHR,
786 ROOT,
787 PROGRAM_DECL,
788 IMPORT,
789 MAIN_CONTENTS,
790 MODULE_CONTENTS,
791 FUNCTION_DEF,
792 CONSTRUCTOR_DEF,
793 STRUCT_DEF,
794 RECORD_DEF,
795 STRUCT_MEMBER,
796 MAPPING_DEF,
797 STORAGE_DEF,
798 GLOBAL_CONST,
799 ANNOTATION,
800 PARAM,
801 PARAM_LIST,
802 RETURN_TYPE,
803 CONST_PARAM,
804 CONST_PARAM_LIST,
805 CONST_ARG_LIST,
806 LET_STMT,
807 CONST_STMT,
808 RETURN_STMT,
809 EXPR_STMT,
810 ASSIGN_STMT,
811 IF_STMT,
812 FOR_STMT,
813 BLOCK,
814 ASSERT_STMT,
815 ASSERT_EQ_STMT,
816 ASSERT_NEQ_STMT,
817 IDENT_PATTERN,
818 TUPLE_PATTERN,
819 WILDCARD_PATTERN,
820 BINARY_EXPR,
821 UNARY_EXPR,
822 CALL_EXPR,
823 METHOD_CALL_EXPR,
824 FIELD_EXPR,
825 INDEX_EXPR,
826 CAST_EXPR,
827 TERNARY_EXPR,
828 ARRAY_EXPR,
829 TUPLE_EXPR,
830 STRUCT_EXPR,
831 STRUCT_FIELD_INIT,
832 PATH_EXPR,
833 PAREN_EXPR,
834 LITERAL,
835 REPEAT_EXPR,
836 ASYNC_EXPR,
837 ASSOC_FN_EXPR,
838 ASSOC_CONST_EXPR,
839 LOCATOR_EXPR,
840 TUPLE_ACCESS_EXPR,
841 INTRINSIC_EXPR,
842 UNIT_EXPR,
843 TYPE_PATH,
844 TYPE_ARRAY,
845 TYPE_TUPLE,
846 TYPE_OPTIONAL,
847 TYPE_FUTURE,
848 TYPE_MAPPING,
849 ARG_LIST,
850 NAME_REF,
851 NAME,
852 VISIBILITY,
853 __LAST,
854];
855
856/// Convert a raw rowan SyntaxKind to our SyntaxKind.
857///
858/// # Panics
859/// Panics if the raw value is out of range.
860pub fn syntax_kind_from_raw(raw: rowan::SyntaxKind) -> SyntaxKind {
861 SYNTAX_KIND_TABLE.get(raw.0 as usize).copied().unwrap_or_else(|| panic!("invalid SyntaxKind: {}", raw.0))
862}
863
864#[cfg(test)]
865mod tests {
866 use super::*;
867
868 #[test]
869 fn syntax_kind_table_is_correct() {
870 // Verify that the table matches the enum discriminants
871 for (i, &kind) in SYNTAX_KIND_TABLE.iter().enumerate() {
872 assert_eq!(
873 kind as u16, i as u16,
874 "SYNTAX_KIND_TABLE[{i}] = {:?} has discriminant {}, expected {i}",
875 kind, kind as u16
876 );
877 }
878 }
879
880 #[test]
881 fn syntax_kind_roundtrip() {
882 // Test that we can convert to rowan::SyntaxKind and back
883 for &kind in SYNTAX_KIND_TABLE.iter() {
884 if kind == __LAST {
885 continue;
886 }
887 let raw: rowan::SyntaxKind = kind.into();
888 let back = syntax_kind_from_raw(raw);
889 assert_eq!(kind, back);
890 }
891 }
892
893 #[test]
894 fn is_trivia() {
895 assert!(WHITESPACE.is_trivia());
896 assert!(LINEBREAK.is_trivia());
897 assert!(COMMENT_LINE.is_trivia());
898 assert!(COMMENT_BLOCK.is_trivia());
899 assert!(!IDENT.is_trivia());
900 assert!(!KW_LET.is_trivia());
901 }
902
903 #[test]
904 fn is_keyword() {
905 assert!(KW_LET.is_keyword());
906 assert!(KW_FUNCTION.is_keyword());
907 assert!(KW_TRUE.is_keyword());
908 assert!(!IDENT.is_keyword());
909 assert!(!PLUS.is_keyword());
910 }
911
912 #[test]
913 fn is_literal() {
914 assert!(INTEGER.is_literal());
915 assert!(STRING.is_literal());
916 assert!(ADDRESS_LIT.is_literal());
917 assert!(KW_TRUE.is_literal());
918 assert!(KW_FALSE.is_literal());
919 assert!(KW_NONE.is_literal());
920 assert!(!IDENT.is_literal());
921 }
922}