1#[repr(u8)]
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum TokenKind {
8 FloatLiteral,
13
14 FloatLiteralSimple,
16
17 FloatLiteralLeadingDot,
19
20 HexIntLiteral,
22
23 BinIntLiteral,
25
26 OctIntLiteralNew,
28
29 OctIntLiteral,
31
32 IntLiteral,
34
35 SingleQuotedString,
37
38 DoubleQuotedString,
40
41 BacktickString,
43
44 Variable,
49
50 Dollar,
52
53 Identifier,
59
60 Plus,
65 Minus,
67 Star,
69 Slash,
71 Percent,
73 StarStar,
75 Dot,
77
78 Equals,
84 PlusEquals,
86 MinusEquals,
88 StarEquals,
90 SlashEquals,
92 PercentEquals,
94 StarStarEquals,
96 DotEquals,
98 AmpersandEquals,
100 PipeEquals,
102 CaretEquals,
104 ShiftLeftEquals,
106 ShiftRightEquals,
108 CoalesceEquals,
110
111 EqualsEquals,
116 BangEquals,
118 EqualsEqualsEquals,
120 BangEqualsEquals,
122 LessThan,
124 GreaterThan,
126 LessThanEquals,
128 GreaterThanEquals,
130 Spaceship,
132
133 AmpersandAmpersand,
138 PipePipe,
140 Bang,
142
143 Ampersand,
145 Pipe,
147 Caret,
149 Tilde,
151 ShiftLeft,
153 ShiftRight,
155
156 PlusPlus,
161 MinusMinus,
163
164 Question,
169 QuestionQuestion,
171 Colon,
173
174 FatArrow,
176
177 PipeArrow,
179
180 LeftParen,
185 RightParen,
187 LeftBracket,
189 RightBracket,
191 LeftBrace,
193 RightBrace,
195 Semicolon,
197 Comma,
199
200 DoubleColon,
202
203 Arrow,
205
206 NullsafeArrow,
208
209 Backslash,
211
212 At,
214
215 HashBracket,
217
218 Ellipsis,
220
221 If,
226 Else,
228 ElseIf,
230 While,
232 Do,
234 For,
236 Foreach,
238 As,
240 Function,
242 Return,
244 Echo,
246 Print,
248 True,
250 False,
252 Null,
254 And,
256 Or,
258 Xor,
260 Break,
262 Continue,
264 Switch,
266 Case,
268 Default,
270 EndIf,
272 EndWhile,
274 EndFor,
276 EndForeach,
278 Throw,
280 Try,
282 Catch,
284 Finally,
286 Instanceof,
288 Array,
290 List,
292 Goto,
294 Declare,
296 Unset,
298 Global,
300 EndDeclare,
302 EndSwitch,
304 Isset,
306 Empty,
308 Include,
310 IncludeOnce,
312 Require,
314 RequireOnce,
316 Eval,
318 Exit,
320 Die,
322 Clone,
324
325 New,
328 Class,
330 Abstract,
332 Final,
334 Interface,
336 Trait,
338 Extends,
340 Implements,
342 Public,
344 Protected,
346 Private,
348 Static,
350 Const,
352 Fn_,
354 Match_,
356 Namespace,
358 Use,
360 Readonly,
362 Enum_,
364 Yield_,
366 From,
368 Self_,
370 Parent_,
372
373 MagicClass,
378 MagicDir,
380 MagicFile,
382 MagicFunction,
384 MagicLine,
386 MagicMethod,
388 MagicNamespace,
390 MagicTrait,
392 MagicProperty,
394 HaltCompiler,
396
397 OpenTag,
402
403 CloseTag,
405
406 InlineHtml,
408
409 Heredoc,
414 Nowdoc,
416
417 InvalidNumericLiteral,
423
424 LineComment,
429 HashComment,
431 BlockComment,
433 DocComment,
435
436 Eof,
441}
442
443impl TokenKind {
444 #[inline]
446 pub fn is_comment(self) -> bool {
447 matches!(
448 self,
449 TokenKind::LineComment
450 | TokenKind::HashComment
451 | TokenKind::BlockComment
452 | TokenKind::DocComment
453 )
454 }
455}
456
457impl TokenKind {
458 #[inline(always)]
459 pub fn is_assignment_op(self) -> bool {
460 (self as u8).wrapping_sub(TokenKind::Equals as u8)
463 <= (TokenKind::CoalesceEquals as u8 - TokenKind::Equals as u8)
464 }
465}
466
467pub fn resolve_keyword(text: &str) -> Option<TokenKind> {
470 let t = text;
473 match text.len() {
474 2 => {
475 if t.eq_ignore_ascii_case("if") {
476 return Some(TokenKind::If);
477 }
478 if t.eq_ignore_ascii_case("do") {
479 return Some(TokenKind::Do);
480 }
481 if t.eq_ignore_ascii_case("or") {
482 return Some(TokenKind::Or);
483 }
484 if t.eq_ignore_ascii_case("as") {
485 return Some(TokenKind::As);
486 }
487 if t.eq_ignore_ascii_case("fn") {
488 return Some(TokenKind::Fn_);
489 }
490 }
491 3 => {
492 if t.eq_ignore_ascii_case("for") {
493 return Some(TokenKind::For);
494 }
495 if t.eq_ignore_ascii_case("xor") {
496 return Some(TokenKind::Xor);
497 }
498 if t.eq_ignore_ascii_case("and") {
499 return Some(TokenKind::And);
500 }
501 if t.eq_ignore_ascii_case("new") {
502 return Some(TokenKind::New);
503 }
504 if t.eq_ignore_ascii_case("use") {
505 return Some(TokenKind::Use);
506 }
507 if t.eq_ignore_ascii_case("try") {
508 return Some(TokenKind::Try);
509 }
510 if t.eq_ignore_ascii_case("die") {
511 return Some(TokenKind::Die);
512 }
513 }
514 4 => {
515 if t.eq_ignore_ascii_case("else") {
516 return Some(TokenKind::Else);
517 }
518 if t.eq_ignore_ascii_case("echo") {
519 return Some(TokenKind::Echo);
520 }
521 if t.eq_ignore_ascii_case("true") {
522 return Some(TokenKind::True);
523 }
524 if t.eq_ignore_ascii_case("null") {
525 return Some(TokenKind::Null);
526 }
527 if t.eq_ignore_ascii_case("list") {
528 return Some(TokenKind::List);
529 }
530 if t.eq_ignore_ascii_case("goto") {
531 return Some(TokenKind::Goto);
532 }
533 if t.eq_ignore_ascii_case("case") {
534 return Some(TokenKind::Case);
535 }
536 if t.eq_ignore_ascii_case("self") {
537 return Some(TokenKind::Self_);
538 }
539 if t.eq_ignore_ascii_case("from") {
540 return Some(TokenKind::From);
541 }
542 if t.eq_ignore_ascii_case("enum") {
543 return Some(TokenKind::Enum_);
544 }
545 if t.eq_ignore_ascii_case("eval") {
546 return Some(TokenKind::Eval);
547 }
548 if t.eq_ignore_ascii_case("exit") {
549 return Some(TokenKind::Exit);
550 }
551 }
552 5 => {
553 if t.eq_ignore_ascii_case("while") {
554 return Some(TokenKind::While);
555 }
556 if t.eq_ignore_ascii_case("false") {
557 return Some(TokenKind::False);
558 }
559 if t.eq_ignore_ascii_case("array") {
560 return Some(TokenKind::Array);
561 }
562 if t.eq_ignore_ascii_case("unset") {
563 return Some(TokenKind::Unset);
564 }
565 if t.eq_ignore_ascii_case("isset") {
566 return Some(TokenKind::Isset);
567 }
568 if t.eq_ignore_ascii_case("empty") {
569 return Some(TokenKind::Empty);
570 }
571 if t.eq_ignore_ascii_case("print") {
572 return Some(TokenKind::Print);
573 }
574 if t.eq_ignore_ascii_case("throw") {
575 return Some(TokenKind::Throw);
576 }
577 if t.eq_ignore_ascii_case("catch") {
578 return Some(TokenKind::Catch);
579 }
580 if t.eq_ignore_ascii_case("break") {
581 return Some(TokenKind::Break);
582 }
583 if t.eq_ignore_ascii_case("yield") {
584 return Some(TokenKind::Yield_);
585 }
586 if t.eq_ignore_ascii_case("class") {
587 return Some(TokenKind::Class);
588 }
589 if t.eq_ignore_ascii_case("const") {
590 return Some(TokenKind::Const);
591 }
592 if t.eq_ignore_ascii_case("final") {
593 return Some(TokenKind::Final);
594 }
595 if t.eq_ignore_ascii_case("match") {
596 return Some(TokenKind::Match_);
597 }
598 if t.eq_ignore_ascii_case("trait") {
599 return Some(TokenKind::Trait);
600 }
601 if t.eq_ignore_ascii_case("clone") {
602 return Some(TokenKind::Clone);
603 }
604 if t.eq_ignore_ascii_case("endif") {
605 return Some(TokenKind::EndIf);
606 }
607 }
608 6 => {
609 if t.eq_ignore_ascii_case("elseif") {
610 return Some(TokenKind::ElseIf);
611 }
612 if t.eq_ignore_ascii_case("return") {
613 return Some(TokenKind::Return);
614 }
615 if t.eq_ignore_ascii_case("switch") {
616 return Some(TokenKind::Switch);
617 }
618 if t.eq_ignore_ascii_case("global") {
619 return Some(TokenKind::Global);
620 }
621 if t.eq_ignore_ascii_case("static") {
622 return Some(TokenKind::Static);
623 }
624 if t.eq_ignore_ascii_case("public") {
625 return Some(TokenKind::Public);
626 }
627 if t.eq_ignore_ascii_case("parent") {
628 return Some(TokenKind::Parent_);
629 }
630 if t.eq_ignore_ascii_case("endfor") {
631 return Some(TokenKind::EndFor);
632 }
633 }
634 7 => {
635 if t.eq_ignore_ascii_case("foreach") {
636 return Some(TokenKind::Foreach);
637 }
638 if t.eq_ignore_ascii_case("default") {
639 return Some(TokenKind::Default);
640 }
641 if t.eq_ignore_ascii_case("finally") {
642 return Some(TokenKind::Finally);
643 }
644 if t.eq_ignore_ascii_case("include") {
645 return Some(TokenKind::Include);
646 }
647 if t.eq_ignore_ascii_case("declare") {
648 return Some(TokenKind::Declare);
649 }
650 if t.eq_ignore_ascii_case("extends") {
651 return Some(TokenKind::Extends);
652 }
653 if t.eq_ignore_ascii_case("require") {
654 return Some(TokenKind::Require);
655 }
656 if t.eq_ignore_ascii_case("private") {
657 return Some(TokenKind::Private);
658 }
659 if t.eq_ignore_ascii_case("__dir__") {
660 return Some(TokenKind::MagicDir);
661 }
662 }
663 8 => {
664 if t.eq_ignore_ascii_case("function") {
665 return Some(TokenKind::Function);
666 }
667 if t.eq_ignore_ascii_case("abstract") {
668 return Some(TokenKind::Abstract);
669 }
670 if t.eq_ignore_ascii_case("readonly") {
671 return Some(TokenKind::Readonly);
672 }
673 if t.eq_ignore_ascii_case("continue") {
674 return Some(TokenKind::Continue);
675 }
676 if t.eq_ignore_ascii_case("endwhile") {
677 return Some(TokenKind::EndWhile);
678 }
679 if t.eq_ignore_ascii_case("__file__") {
680 return Some(TokenKind::MagicFile);
681 }
682 if t.eq_ignore_ascii_case("__line__") {
683 return Some(TokenKind::MagicLine);
684 }
685 }
686 9 => {
687 if t.eq_ignore_ascii_case("namespace") {
688 return Some(TokenKind::Namespace);
689 }
690 if t.eq_ignore_ascii_case("interface") {
691 return Some(TokenKind::Interface);
692 }
693 if t.eq_ignore_ascii_case("protected") {
694 return Some(TokenKind::Protected);
695 }
696 if t.eq_ignore_ascii_case("endswitch") {
697 return Some(TokenKind::EndSwitch);
698 }
699 if t.eq_ignore_ascii_case("__class__") {
700 return Some(TokenKind::MagicClass);
701 }
702 if t.eq_ignore_ascii_case("__trait__") {
703 return Some(TokenKind::MagicTrait);
704 }
705 }
706 10 => {
707 if t.eq_ignore_ascii_case("implements") {
708 return Some(TokenKind::Implements);
709 }
710 if t.eq_ignore_ascii_case("instanceof") {
711 return Some(TokenKind::Instanceof);
712 }
713 if t.eq_ignore_ascii_case("endforeach") {
714 return Some(TokenKind::EndForeach);
715 }
716 if t.eq_ignore_ascii_case("enddeclare") {
717 return Some(TokenKind::EndDeclare);
718 }
719 if t.eq_ignore_ascii_case("__method__") {
720 return Some(TokenKind::MagicMethod);
721 }
722 }
723 12 => {
724 if t.eq_ignore_ascii_case("include_once") {
725 return Some(TokenKind::IncludeOnce);
726 }
727 if t.eq_ignore_ascii_case("require_once") {
728 return Some(TokenKind::RequireOnce);
729 }
730 if t.eq_ignore_ascii_case("__function__") {
731 return Some(TokenKind::MagicFunction);
732 }
733 if t.eq_ignore_ascii_case("__property__") {
734 return Some(TokenKind::MagicProperty);
735 }
736 }
737 13 if t.eq_ignore_ascii_case("__namespace__") => {
738 return Some(TokenKind::MagicNamespace);
739 }
740 15 if t.eq_ignore_ascii_case("__halt_compiler") => {
741 return Some(TokenKind::HaltCompiler);
742 }
743 _ => {}
744 }
745 None
746}
747
748impl std::fmt::Display for TokenKind {
749 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
750 match self {
751 TokenKind::IntLiteral => write!(f, "integer"),
752 TokenKind::HexIntLiteral => write!(f, "hex integer"),
753 TokenKind::BinIntLiteral => write!(f, "binary integer"),
754 TokenKind::OctIntLiteral | TokenKind::OctIntLiteralNew => write!(f, "octal integer"),
755 TokenKind::FloatLiteral
756 | TokenKind::FloatLiteralSimple
757 | TokenKind::FloatLiteralLeadingDot => write!(f, "float"),
758 TokenKind::SingleQuotedString | TokenKind::DoubleQuotedString => write!(f, "string"),
759 TokenKind::BacktickString => write!(f, "backtick string"),
760 TokenKind::Variable => write!(f, "variable"),
761 TokenKind::Dollar => write!(f, "'$'"),
762 TokenKind::Identifier => write!(f, "identifier"),
763 TokenKind::Plus => write!(f, "'+'"),
764 TokenKind::Minus => write!(f, "'-'"),
765 TokenKind::Star => write!(f, "'*'"),
766 TokenKind::Slash => write!(f, "'/'"),
767 TokenKind::Percent => write!(f, "'%'"),
768 TokenKind::StarStar => write!(f, "'**'"),
769 TokenKind::Dot => write!(f, "'.'"),
770 TokenKind::Equals => write!(f, "'='"),
771 TokenKind::PlusEquals => write!(f, "'+='"),
772 TokenKind::MinusEquals => write!(f, "'-='"),
773 TokenKind::StarEquals => write!(f, "'*='"),
774 TokenKind::SlashEquals => write!(f, "'/='"),
775 TokenKind::PercentEquals => write!(f, "'%='"),
776 TokenKind::StarStarEquals => write!(f, "'**='"),
777 TokenKind::DotEquals => write!(f, "'.='"),
778 TokenKind::AmpersandEquals => write!(f, "'&='"),
779 TokenKind::PipeEquals => write!(f, "'|='"),
780 TokenKind::CaretEquals => write!(f, "'^='"),
781 TokenKind::ShiftLeftEquals => write!(f, "'<<='"),
782 TokenKind::ShiftRightEquals => write!(f, "'>>='"),
783 TokenKind::CoalesceEquals => write!(f, "'??='"),
784 TokenKind::EqualsEquals => write!(f, "'=='"),
785 TokenKind::BangEquals => write!(f, "'!='"),
786 TokenKind::EqualsEqualsEquals => write!(f, "'==='"),
787 TokenKind::BangEqualsEquals => write!(f, "'!=='"),
788 TokenKind::LessThan => write!(f, "'<'"),
789 TokenKind::GreaterThan => write!(f, "'>'"),
790 TokenKind::LessThanEquals => write!(f, "'<='"),
791 TokenKind::GreaterThanEquals => write!(f, "'>='"),
792 TokenKind::Spaceship => write!(f, "'<=>'"),
793 TokenKind::AmpersandAmpersand => write!(f, "'&&'"),
794 TokenKind::PipePipe => write!(f, "'||'"),
795 TokenKind::Bang => write!(f, "'!'"),
796 TokenKind::Ampersand => write!(f, "'&'"),
797 TokenKind::Pipe => write!(f, "'|'"),
798 TokenKind::Caret => write!(f, "'^'"),
799 TokenKind::Tilde => write!(f, "'~'"),
800 TokenKind::ShiftLeft => write!(f, "'<<'"),
801 TokenKind::ShiftRight => write!(f, "'>>'"),
802 TokenKind::PlusPlus => write!(f, "'++'"),
803 TokenKind::MinusMinus => write!(f, "'--'"),
804 TokenKind::Question => write!(f, "'?'"),
805 TokenKind::QuestionQuestion => write!(f, "'??'"),
806 TokenKind::Colon => write!(f, "':'"),
807 TokenKind::FatArrow => write!(f, "'=>'"),
808 TokenKind::PipeArrow => write!(f, "'|>'"),
809 TokenKind::LeftParen => write!(f, "'('"),
810 TokenKind::RightParen => write!(f, "')'"),
811 TokenKind::LeftBracket => write!(f, "'['"),
812 TokenKind::RightBracket => write!(f, "']'"),
813 TokenKind::LeftBrace => write!(f, "'{{'"),
814 TokenKind::RightBrace => write!(f, "'}}'"),
815 TokenKind::Semicolon => write!(f, "';'"),
816 TokenKind::Comma => write!(f, "','"),
817 TokenKind::DoubleColon => write!(f, "'::'"),
818 TokenKind::Arrow => write!(f, "'->'"),
819 TokenKind::NullsafeArrow => write!(f, "'?->'"),
820 TokenKind::Backslash => write!(f, "'\\'"),
821 TokenKind::At => write!(f, "'@'"),
822 TokenKind::HashBracket => write!(f, "'#['"),
823 TokenKind::Ellipsis => write!(f, "'...'"),
824 TokenKind::If => write!(f, "'if'"),
825 TokenKind::Else => write!(f, "'else'"),
826 TokenKind::ElseIf => write!(f, "'elseif'"),
827 TokenKind::While => write!(f, "'while'"),
828 TokenKind::Do => write!(f, "'do'"),
829 TokenKind::For => write!(f, "'for'"),
830 TokenKind::Foreach => write!(f, "'foreach'"),
831 TokenKind::As => write!(f, "'as'"),
832 TokenKind::Function => write!(f, "'function'"),
833 TokenKind::Return => write!(f, "'return'"),
834 TokenKind::Echo => write!(f, "'echo'"),
835 TokenKind::Print => write!(f, "'print'"),
836 TokenKind::True => write!(f, "'true'"),
837 TokenKind::False => write!(f, "'false'"),
838 TokenKind::Null => write!(f, "'null'"),
839 TokenKind::And => write!(f, "'and'"),
840 TokenKind::Or => write!(f, "'or'"),
841 TokenKind::Xor => write!(f, "'xor'"),
842 TokenKind::Break => write!(f, "'break'"),
843 TokenKind::Continue => write!(f, "'continue'"),
844 TokenKind::Switch => write!(f, "'switch'"),
845 TokenKind::Case => write!(f, "'case'"),
846 TokenKind::Default => write!(f, "'default'"),
847 TokenKind::EndIf => write!(f, "'endif'"),
848 TokenKind::EndWhile => write!(f, "'endwhile'"),
849 TokenKind::EndFor => write!(f, "'endfor'"),
850 TokenKind::EndForeach => write!(f, "'endforeach'"),
851 TokenKind::Throw => write!(f, "'throw'"),
852 TokenKind::Try => write!(f, "'try'"),
853 TokenKind::Catch => write!(f, "'catch'"),
854 TokenKind::Finally => write!(f, "'finally'"),
855 TokenKind::Instanceof => write!(f, "'instanceof'"),
856 TokenKind::Array => write!(f, "'array'"),
857 TokenKind::List => write!(f, "'list'"),
858 TokenKind::Goto => write!(f, "'goto'"),
859 TokenKind::Declare => write!(f, "'declare'"),
860 TokenKind::Unset => write!(f, "'unset'"),
861 TokenKind::Global => write!(f, "'global'"),
862 TokenKind::EndDeclare => write!(f, "'enddeclare'"),
863 TokenKind::EndSwitch => write!(f, "'endswitch'"),
864 TokenKind::Isset => write!(f, "'isset'"),
865 TokenKind::Empty => write!(f, "'empty'"),
866 TokenKind::Include => write!(f, "'include'"),
867 TokenKind::IncludeOnce => write!(f, "'include_once'"),
868 TokenKind::Require => write!(f, "'require'"),
869 TokenKind::RequireOnce => write!(f, "'require_once'"),
870 TokenKind::Eval => write!(f, "'eval'"),
871 TokenKind::Exit => write!(f, "'exit'"),
872 TokenKind::Die => write!(f, "'die'"),
873 TokenKind::Clone => write!(f, "'clone'"),
874 TokenKind::New => write!(f, "'new'"),
875 TokenKind::Class => write!(f, "'class'"),
876 TokenKind::Abstract => write!(f, "'abstract'"),
877 TokenKind::Final => write!(f, "'final'"),
878 TokenKind::Interface => write!(f, "'interface'"),
879 TokenKind::Trait => write!(f, "'trait'"),
880 TokenKind::Extends => write!(f, "'extends'"),
881 TokenKind::Implements => write!(f, "'implements'"),
882 TokenKind::Public => write!(f, "'public'"),
883 TokenKind::Protected => write!(f, "'protected'"),
884 TokenKind::Private => write!(f, "'private'"),
885 TokenKind::Static => write!(f, "'static'"),
886 TokenKind::Const => write!(f, "'const'"),
887 TokenKind::Fn_ => write!(f, "'fn'"),
888 TokenKind::Match_ => write!(f, "'match'"),
889 TokenKind::Namespace => write!(f, "'namespace'"),
890 TokenKind::Use => write!(f, "'use'"),
891 TokenKind::Readonly => write!(f, "'readonly'"),
892 TokenKind::Enum_ => write!(f, "'enum'"),
893 TokenKind::Yield_ => write!(f, "'yield'"),
894 TokenKind::From => write!(f, "'from'"),
895 TokenKind::Self_ => write!(f, "'self'"),
896 TokenKind::Parent_ => write!(f, "'parent'"),
897 TokenKind::MagicClass => write!(f, "'__CLASS__'"),
898 TokenKind::MagicDir => write!(f, "'__DIR__'"),
899 TokenKind::MagicFile => write!(f, "'__FILE__'"),
900 TokenKind::MagicFunction => write!(f, "'__FUNCTION__'"),
901 TokenKind::MagicLine => write!(f, "'__LINE__'"),
902 TokenKind::MagicMethod => write!(f, "'__METHOD__'"),
903 TokenKind::MagicNamespace => write!(f, "'__NAMESPACE__'"),
904 TokenKind::MagicTrait => write!(f, "'__TRAIT__'"),
905 TokenKind::MagicProperty => write!(f, "'__PROPERTY__'"),
906 TokenKind::HaltCompiler => write!(f, "'__halt_compiler'"),
907 TokenKind::OpenTag => write!(f, "'<?php'"),
908 TokenKind::CloseTag => write!(f, "'?>'"),
909 TokenKind::InlineHtml => write!(f, "inline HTML"),
910 TokenKind::Heredoc => write!(f, "heredoc"),
911 TokenKind::Nowdoc => write!(f, "nowdoc"),
912 TokenKind::InvalidNumericLiteral => write!(f, "invalid numeric literal"),
913 TokenKind::LineComment => write!(f, "line comment"),
914 TokenKind::HashComment => write!(f, "hash comment"),
915 TokenKind::BlockComment => write!(f, "block comment"),
916 TokenKind::DocComment => write!(f, "doc comment"),
917 TokenKind::Eof => write!(f, "end of file"),
918 }
919 }
920}
921
922#[cfg(test)]
923mod tests {
924 use super::*;
925
926 #[test]
927 fn test_resolve_keyword() {
928 assert_eq!(resolve_keyword("if"), Some(TokenKind::If));
929 assert_eq!(resolve_keyword("IF"), Some(TokenKind::If));
930 assert_eq!(resolve_keyword("If"), Some(TokenKind::If));
931 assert_eq!(resolve_keyword("function"), Some(TokenKind::Function));
932 assert_eq!(resolve_keyword("myFunc"), None);
933 assert_eq!(resolve_keyword("true"), Some(TokenKind::True));
934 assert_eq!(resolve_keyword("TRUE"), Some(TokenKind::True));
935 assert_eq!(resolve_keyword("null"), Some(TokenKind::Null));
936 }
937
938 #[test]
939 fn test_is_assignment_op() {
940 assert!(TokenKind::Equals.is_assignment_op());
941 assert!(TokenKind::PlusEquals.is_assignment_op());
942 assert!(TokenKind::DotEquals.is_assignment_op());
943 assert!(!TokenKind::Plus.is_assignment_op());
944 assert!(!TokenKind::EqualsEquals.is_assignment_op());
945 }
946}