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)]
460 pub fn is_assignment_op(self) -> bool {
461 (self as u8).wrapping_sub(TokenKind::Equals as u8)
464 <= (TokenKind::CoalesceEquals as u8 - TokenKind::Equals as u8)
465 }
466}
467
468pub fn resolve_keyword(text: &str) -> Option<TokenKind> {
471 let t = text;
474 match text.len() {
475 2 => {
476 if t.eq_ignore_ascii_case("if") {
477 return Some(TokenKind::If);
478 }
479 if t.eq_ignore_ascii_case("do") {
480 return Some(TokenKind::Do);
481 }
482 if t.eq_ignore_ascii_case("or") {
483 return Some(TokenKind::Or);
484 }
485 if t.eq_ignore_ascii_case("as") {
486 return Some(TokenKind::As);
487 }
488 if t.eq_ignore_ascii_case("fn") {
489 return Some(TokenKind::Fn_);
490 }
491 }
492 3 => {
493 if t.eq_ignore_ascii_case("for") {
494 return Some(TokenKind::For);
495 }
496 if t.eq_ignore_ascii_case("xor") {
497 return Some(TokenKind::Xor);
498 }
499 if t.eq_ignore_ascii_case("and") {
500 return Some(TokenKind::And);
501 }
502 if t.eq_ignore_ascii_case("new") {
503 return Some(TokenKind::New);
504 }
505 if t.eq_ignore_ascii_case("use") {
506 return Some(TokenKind::Use);
507 }
508 if t.eq_ignore_ascii_case("try") {
509 return Some(TokenKind::Try);
510 }
511 if t.eq_ignore_ascii_case("die") {
512 return Some(TokenKind::Die);
513 }
514 }
515 4 => {
516 if t.eq_ignore_ascii_case("else") {
517 return Some(TokenKind::Else);
518 }
519 if t.eq_ignore_ascii_case("echo") {
520 return Some(TokenKind::Echo);
521 }
522 if t.eq_ignore_ascii_case("true") {
523 return Some(TokenKind::True);
524 }
525 if t.eq_ignore_ascii_case("null") {
526 return Some(TokenKind::Null);
527 }
528 if t.eq_ignore_ascii_case("list") {
529 return Some(TokenKind::List);
530 }
531 if t.eq_ignore_ascii_case("goto") {
532 return Some(TokenKind::Goto);
533 }
534 if t.eq_ignore_ascii_case("case") {
535 return Some(TokenKind::Case);
536 }
537 if t.eq_ignore_ascii_case("self") {
538 return Some(TokenKind::Self_);
539 }
540 if t.eq_ignore_ascii_case("from") {
541 return Some(TokenKind::From);
542 }
543 if t.eq_ignore_ascii_case("enum") {
544 return Some(TokenKind::Enum_);
545 }
546 if t.eq_ignore_ascii_case("eval") {
547 return Some(TokenKind::Eval);
548 }
549 if t.eq_ignore_ascii_case("exit") {
550 return Some(TokenKind::Exit);
551 }
552 }
553 5 => {
554 if t.eq_ignore_ascii_case("while") {
555 return Some(TokenKind::While);
556 }
557 if t.eq_ignore_ascii_case("false") {
558 return Some(TokenKind::False);
559 }
560 if t.eq_ignore_ascii_case("array") {
561 return Some(TokenKind::Array);
562 }
563 if t.eq_ignore_ascii_case("unset") {
564 return Some(TokenKind::Unset);
565 }
566 if t.eq_ignore_ascii_case("isset") {
567 return Some(TokenKind::Isset);
568 }
569 if t.eq_ignore_ascii_case("empty") {
570 return Some(TokenKind::Empty);
571 }
572 if t.eq_ignore_ascii_case("print") {
573 return Some(TokenKind::Print);
574 }
575 if t.eq_ignore_ascii_case("throw") {
576 return Some(TokenKind::Throw);
577 }
578 if t.eq_ignore_ascii_case("catch") {
579 return Some(TokenKind::Catch);
580 }
581 if t.eq_ignore_ascii_case("break") {
582 return Some(TokenKind::Break);
583 }
584 if t.eq_ignore_ascii_case("yield") {
585 return Some(TokenKind::Yield_);
586 }
587 if t.eq_ignore_ascii_case("class") {
588 return Some(TokenKind::Class);
589 }
590 if t.eq_ignore_ascii_case("const") {
591 return Some(TokenKind::Const);
592 }
593 if t.eq_ignore_ascii_case("final") {
594 return Some(TokenKind::Final);
595 }
596 if t.eq_ignore_ascii_case("match") {
597 return Some(TokenKind::Match_);
598 }
599 if t.eq_ignore_ascii_case("trait") {
600 return Some(TokenKind::Trait);
601 }
602 if t.eq_ignore_ascii_case("clone") {
603 return Some(TokenKind::Clone);
604 }
605 if t.eq_ignore_ascii_case("endif") {
606 return Some(TokenKind::EndIf);
607 }
608 }
609 6 => {
610 if t.eq_ignore_ascii_case("elseif") {
611 return Some(TokenKind::ElseIf);
612 }
613 if t.eq_ignore_ascii_case("return") {
614 return Some(TokenKind::Return);
615 }
616 if t.eq_ignore_ascii_case("switch") {
617 return Some(TokenKind::Switch);
618 }
619 if t.eq_ignore_ascii_case("global") {
620 return Some(TokenKind::Global);
621 }
622 if t.eq_ignore_ascii_case("static") {
623 return Some(TokenKind::Static);
624 }
625 if t.eq_ignore_ascii_case("public") {
626 return Some(TokenKind::Public);
627 }
628 if t.eq_ignore_ascii_case("parent") {
629 return Some(TokenKind::Parent_);
630 }
631 if t.eq_ignore_ascii_case("endfor") {
632 return Some(TokenKind::EndFor);
633 }
634 }
635 7 => {
636 if t.eq_ignore_ascii_case("foreach") {
637 return Some(TokenKind::Foreach);
638 }
639 if t.eq_ignore_ascii_case("default") {
640 return Some(TokenKind::Default);
641 }
642 if t.eq_ignore_ascii_case("finally") {
643 return Some(TokenKind::Finally);
644 }
645 if t.eq_ignore_ascii_case("include") {
646 return Some(TokenKind::Include);
647 }
648 if t.eq_ignore_ascii_case("declare") {
649 return Some(TokenKind::Declare);
650 }
651 if t.eq_ignore_ascii_case("extends") {
652 return Some(TokenKind::Extends);
653 }
654 if t.eq_ignore_ascii_case("require") {
655 return Some(TokenKind::Require);
656 }
657 if t.eq_ignore_ascii_case("private") {
658 return Some(TokenKind::Private);
659 }
660 if t.eq_ignore_ascii_case("__dir__") {
661 return Some(TokenKind::MagicDir);
662 }
663 }
664 8 => {
665 if t.eq_ignore_ascii_case("function") {
666 return Some(TokenKind::Function);
667 }
668 if t.eq_ignore_ascii_case("abstract") {
669 return Some(TokenKind::Abstract);
670 }
671 if t.eq_ignore_ascii_case("readonly") {
672 return Some(TokenKind::Readonly);
673 }
674 if t.eq_ignore_ascii_case("continue") {
675 return Some(TokenKind::Continue);
676 }
677 if t.eq_ignore_ascii_case("endwhile") {
678 return Some(TokenKind::EndWhile);
679 }
680 if t.eq_ignore_ascii_case("__file__") {
681 return Some(TokenKind::MagicFile);
682 }
683 if t.eq_ignore_ascii_case("__line__") {
684 return Some(TokenKind::MagicLine);
685 }
686 }
687 9 => {
688 if t.eq_ignore_ascii_case("namespace") {
689 return Some(TokenKind::Namespace);
690 }
691 if t.eq_ignore_ascii_case("interface") {
692 return Some(TokenKind::Interface);
693 }
694 if t.eq_ignore_ascii_case("protected") {
695 return Some(TokenKind::Protected);
696 }
697 if t.eq_ignore_ascii_case("endswitch") {
698 return Some(TokenKind::EndSwitch);
699 }
700 if t.eq_ignore_ascii_case("__class__") {
701 return Some(TokenKind::MagicClass);
702 }
703 if t.eq_ignore_ascii_case("__trait__") {
704 return Some(TokenKind::MagicTrait);
705 }
706 }
707 10 => {
708 if t.eq_ignore_ascii_case("implements") {
709 return Some(TokenKind::Implements);
710 }
711 if t.eq_ignore_ascii_case("instanceof") {
712 return Some(TokenKind::Instanceof);
713 }
714 if t.eq_ignore_ascii_case("endforeach") {
715 return Some(TokenKind::EndForeach);
716 }
717 if t.eq_ignore_ascii_case("enddeclare") {
718 return Some(TokenKind::EndDeclare);
719 }
720 if t.eq_ignore_ascii_case("__method__") {
721 return Some(TokenKind::MagicMethod);
722 }
723 }
724 12 => {
725 if t.eq_ignore_ascii_case("include_once") {
726 return Some(TokenKind::IncludeOnce);
727 }
728 if t.eq_ignore_ascii_case("require_once") {
729 return Some(TokenKind::RequireOnce);
730 }
731 if t.eq_ignore_ascii_case("__function__") {
732 return Some(TokenKind::MagicFunction);
733 }
734 if t.eq_ignore_ascii_case("__property__") {
735 return Some(TokenKind::MagicProperty);
736 }
737 }
738 13 if t.eq_ignore_ascii_case("__namespace__") => {
739 return Some(TokenKind::MagicNamespace);
740 }
741 15 if t.eq_ignore_ascii_case("__halt_compiler") => {
742 return Some(TokenKind::HaltCompiler);
743 }
744 _ => {}
745 }
746 None
747}
748
749impl std::fmt::Display for TokenKind {
750 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
751 match self {
752 TokenKind::IntLiteral => write!(f, "integer"),
753 TokenKind::HexIntLiteral => write!(f, "hex integer"),
754 TokenKind::BinIntLiteral => write!(f, "binary integer"),
755 TokenKind::OctIntLiteral | TokenKind::OctIntLiteralNew => write!(f, "octal integer"),
756 TokenKind::FloatLiteral
757 | TokenKind::FloatLiteralSimple
758 | TokenKind::FloatLiteralLeadingDot => write!(f, "float"),
759 TokenKind::SingleQuotedString | TokenKind::DoubleQuotedString => write!(f, "string"),
760 TokenKind::BacktickString => write!(f, "backtick string"),
761 TokenKind::Variable => write!(f, "variable"),
762 TokenKind::Dollar => write!(f, "'$'"),
763 TokenKind::Identifier => write!(f, "identifier"),
764 TokenKind::Plus => write!(f, "'+'"),
765 TokenKind::Minus => write!(f, "'-'"),
766 TokenKind::Star => write!(f, "'*'"),
767 TokenKind::Slash => write!(f, "'/'"),
768 TokenKind::Percent => write!(f, "'%'"),
769 TokenKind::StarStar => write!(f, "'**'"),
770 TokenKind::Dot => write!(f, "'.'"),
771 TokenKind::Equals => write!(f, "'='"),
772 TokenKind::PlusEquals => write!(f, "'+='"),
773 TokenKind::MinusEquals => write!(f, "'-='"),
774 TokenKind::StarEquals => write!(f, "'*='"),
775 TokenKind::SlashEquals => write!(f, "'/='"),
776 TokenKind::PercentEquals => write!(f, "'%='"),
777 TokenKind::StarStarEquals => write!(f, "'**='"),
778 TokenKind::DotEquals => write!(f, "'.='"),
779 TokenKind::AmpersandEquals => write!(f, "'&='"),
780 TokenKind::PipeEquals => write!(f, "'|='"),
781 TokenKind::CaretEquals => write!(f, "'^='"),
782 TokenKind::ShiftLeftEquals => write!(f, "'<<='"),
783 TokenKind::ShiftRightEquals => write!(f, "'>>='"),
784 TokenKind::CoalesceEquals => write!(f, "'??='"),
785 TokenKind::EqualsEquals => write!(f, "'=='"),
786 TokenKind::BangEquals => write!(f, "'!='"),
787 TokenKind::EqualsEqualsEquals => write!(f, "'==='"),
788 TokenKind::BangEqualsEquals => write!(f, "'!=='"),
789 TokenKind::LessThan => write!(f, "'<'"),
790 TokenKind::GreaterThan => write!(f, "'>'"),
791 TokenKind::LessThanEquals => write!(f, "'<='"),
792 TokenKind::GreaterThanEquals => write!(f, "'>='"),
793 TokenKind::Spaceship => write!(f, "'<=>'"),
794 TokenKind::AmpersandAmpersand => write!(f, "'&&'"),
795 TokenKind::PipePipe => write!(f, "'||'"),
796 TokenKind::Bang => write!(f, "'!'"),
797 TokenKind::Ampersand => write!(f, "'&'"),
798 TokenKind::Pipe => write!(f, "'|'"),
799 TokenKind::Caret => write!(f, "'^'"),
800 TokenKind::Tilde => write!(f, "'~'"),
801 TokenKind::ShiftLeft => write!(f, "'<<'"),
802 TokenKind::ShiftRight => write!(f, "'>>'"),
803 TokenKind::PlusPlus => write!(f, "'++'"),
804 TokenKind::MinusMinus => write!(f, "'--'"),
805 TokenKind::Question => write!(f, "'?'"),
806 TokenKind::QuestionQuestion => write!(f, "'??'"),
807 TokenKind::Colon => write!(f, "':'"),
808 TokenKind::FatArrow => write!(f, "'=>'"),
809 TokenKind::PipeArrow => write!(f, "'|>'"),
810 TokenKind::LeftParen => write!(f, "'('"),
811 TokenKind::RightParen => write!(f, "')'"),
812 TokenKind::LeftBracket => write!(f, "'['"),
813 TokenKind::RightBracket => write!(f, "']'"),
814 TokenKind::LeftBrace => write!(f, "'{{'"),
815 TokenKind::RightBrace => write!(f, "'}}'"),
816 TokenKind::Semicolon => write!(f, "';'"),
817 TokenKind::Comma => write!(f, "','"),
818 TokenKind::DoubleColon => write!(f, "'::'"),
819 TokenKind::Arrow => write!(f, "'->'"),
820 TokenKind::NullsafeArrow => write!(f, "'?->'"),
821 TokenKind::Backslash => write!(f, "'\\'"),
822 TokenKind::At => write!(f, "'@'"),
823 TokenKind::HashBracket => write!(f, "'#['"),
824 TokenKind::Ellipsis => write!(f, "'...'"),
825 TokenKind::If => write!(f, "'if'"),
826 TokenKind::Else => write!(f, "'else'"),
827 TokenKind::ElseIf => write!(f, "'elseif'"),
828 TokenKind::While => write!(f, "'while'"),
829 TokenKind::Do => write!(f, "'do'"),
830 TokenKind::For => write!(f, "'for'"),
831 TokenKind::Foreach => write!(f, "'foreach'"),
832 TokenKind::As => write!(f, "'as'"),
833 TokenKind::Function => write!(f, "'function'"),
834 TokenKind::Return => write!(f, "'return'"),
835 TokenKind::Echo => write!(f, "'echo'"),
836 TokenKind::Print => write!(f, "'print'"),
837 TokenKind::True => write!(f, "'true'"),
838 TokenKind::False => write!(f, "'false'"),
839 TokenKind::Null => write!(f, "'null'"),
840 TokenKind::And => write!(f, "'and'"),
841 TokenKind::Or => write!(f, "'or'"),
842 TokenKind::Xor => write!(f, "'xor'"),
843 TokenKind::Break => write!(f, "'break'"),
844 TokenKind::Continue => write!(f, "'continue'"),
845 TokenKind::Switch => write!(f, "'switch'"),
846 TokenKind::Case => write!(f, "'case'"),
847 TokenKind::Default => write!(f, "'default'"),
848 TokenKind::EndIf => write!(f, "'endif'"),
849 TokenKind::EndWhile => write!(f, "'endwhile'"),
850 TokenKind::EndFor => write!(f, "'endfor'"),
851 TokenKind::EndForeach => write!(f, "'endforeach'"),
852 TokenKind::Throw => write!(f, "'throw'"),
853 TokenKind::Try => write!(f, "'try'"),
854 TokenKind::Catch => write!(f, "'catch'"),
855 TokenKind::Finally => write!(f, "'finally'"),
856 TokenKind::Instanceof => write!(f, "'instanceof'"),
857 TokenKind::Array => write!(f, "'array'"),
858 TokenKind::List => write!(f, "'list'"),
859 TokenKind::Goto => write!(f, "'goto'"),
860 TokenKind::Declare => write!(f, "'declare'"),
861 TokenKind::Unset => write!(f, "'unset'"),
862 TokenKind::Global => write!(f, "'global'"),
863 TokenKind::EndDeclare => write!(f, "'enddeclare'"),
864 TokenKind::EndSwitch => write!(f, "'endswitch'"),
865 TokenKind::Isset => write!(f, "'isset'"),
866 TokenKind::Empty => write!(f, "'empty'"),
867 TokenKind::Include => write!(f, "'include'"),
868 TokenKind::IncludeOnce => write!(f, "'include_once'"),
869 TokenKind::Require => write!(f, "'require'"),
870 TokenKind::RequireOnce => write!(f, "'require_once'"),
871 TokenKind::Eval => write!(f, "'eval'"),
872 TokenKind::Exit => write!(f, "'exit'"),
873 TokenKind::Die => write!(f, "'die'"),
874 TokenKind::Clone => write!(f, "'clone'"),
875 TokenKind::New => write!(f, "'new'"),
876 TokenKind::Class => write!(f, "'class'"),
877 TokenKind::Abstract => write!(f, "'abstract'"),
878 TokenKind::Final => write!(f, "'final'"),
879 TokenKind::Interface => write!(f, "'interface'"),
880 TokenKind::Trait => write!(f, "'trait'"),
881 TokenKind::Extends => write!(f, "'extends'"),
882 TokenKind::Implements => write!(f, "'implements'"),
883 TokenKind::Public => write!(f, "'public'"),
884 TokenKind::Protected => write!(f, "'protected'"),
885 TokenKind::Private => write!(f, "'private'"),
886 TokenKind::Static => write!(f, "'static'"),
887 TokenKind::Const => write!(f, "'const'"),
888 TokenKind::Fn_ => write!(f, "'fn'"),
889 TokenKind::Match_ => write!(f, "'match'"),
890 TokenKind::Namespace => write!(f, "'namespace'"),
891 TokenKind::Use => write!(f, "'use'"),
892 TokenKind::Readonly => write!(f, "'readonly'"),
893 TokenKind::Enum_ => write!(f, "'enum'"),
894 TokenKind::Yield_ => write!(f, "'yield'"),
895 TokenKind::From => write!(f, "'from'"),
896 TokenKind::Self_ => write!(f, "'self'"),
897 TokenKind::Parent_ => write!(f, "'parent'"),
898 TokenKind::MagicClass => write!(f, "'__CLASS__'"),
899 TokenKind::MagicDir => write!(f, "'__DIR__'"),
900 TokenKind::MagicFile => write!(f, "'__FILE__'"),
901 TokenKind::MagicFunction => write!(f, "'__FUNCTION__'"),
902 TokenKind::MagicLine => write!(f, "'__LINE__'"),
903 TokenKind::MagicMethod => write!(f, "'__METHOD__'"),
904 TokenKind::MagicNamespace => write!(f, "'__NAMESPACE__'"),
905 TokenKind::MagicTrait => write!(f, "'__TRAIT__'"),
906 TokenKind::MagicProperty => write!(f, "'__PROPERTY__'"),
907 TokenKind::HaltCompiler => write!(f, "'__halt_compiler'"),
908 TokenKind::OpenTag => write!(f, "'<?php'"),
909 TokenKind::CloseTag => write!(f, "'?>'"),
910 TokenKind::InlineHtml => write!(f, "inline HTML"),
911 TokenKind::Heredoc => write!(f, "heredoc"),
912 TokenKind::Nowdoc => write!(f, "nowdoc"),
913 TokenKind::InvalidNumericLiteral => write!(f, "invalid numeric literal"),
914 TokenKind::LineComment => write!(f, "line comment"),
915 TokenKind::HashComment => write!(f, "hash comment"),
916 TokenKind::BlockComment => write!(f, "block comment"),
917 TokenKind::DocComment => write!(f, "doc comment"),
918 TokenKind::Eof => write!(f, "end of file"),
919 }
920 }
921}
922
923#[cfg(test)]
924mod tests {
925 use super::*;
926
927 #[test]
928 fn test_resolve_keyword() {
929 assert_eq!(resolve_keyword("if"), Some(TokenKind::If));
930 assert_eq!(resolve_keyword("IF"), Some(TokenKind::If));
931 assert_eq!(resolve_keyword("If"), Some(TokenKind::If));
932 assert_eq!(resolve_keyword("function"), Some(TokenKind::Function));
933 assert_eq!(resolve_keyword("myFunc"), None);
934 assert_eq!(resolve_keyword("true"), Some(TokenKind::True));
935 assert_eq!(resolve_keyword("TRUE"), Some(TokenKind::True));
936 assert_eq!(resolve_keyword("null"), Some(TokenKind::Null));
937 }
938
939 #[test]
940 fn test_is_assignment_op() {
941 assert!(TokenKind::Equals.is_assignment_op());
942 assert!(TokenKind::PlusEquals.is_assignment_op());
943 assert!(TokenKind::DotEquals.is_assignment_op());
944 assert!(!TokenKind::Plus.is_assignment_op());
945 assert!(!TokenKind::EqualsEquals.is_assignment_op());
946 }
947}