1#[repr(u8)]
2#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3pub enum TokenKind {
4 FloatLiteral,
7
8 FloatLiteralSimple,
10
11 FloatLiteralLeadingDot,
13
14 HexIntLiteral,
15
16 BinIntLiteral,
17
18 OctIntLiteralNew,
19
20 OctIntLiteral,
21
22 IntLiteral,
23
24 SingleQuotedString,
26
27 DoubleQuotedString,
28
29 BacktickString,
30
31 Variable,
33 Dollar,
34
35 Identifier,
37
38 Plus,
40 Minus,
41 Star,
42 Slash,
43 Percent,
44 StarStar,
45 Dot,
46
47 Equals,
48 PlusEquals,
49 MinusEquals,
50 StarEquals,
51 SlashEquals,
52 PercentEquals,
53 StarStarEquals,
54 DotEquals,
55 AmpersandEquals,
56 PipeEquals,
57 CaretEquals,
58 ShiftLeftEquals,
59 ShiftRightEquals,
60 CoalesceEquals,
61
62 EqualsEquals,
63 BangEquals,
64 EqualsEqualsEquals,
65 BangEqualsEquals,
66 LessThan,
67 GreaterThan,
68 LessThanEquals,
69 GreaterThanEquals,
70 Spaceship,
71
72 AmpersandAmpersand,
73 PipePipe,
74 Bang,
75
76 Ampersand,
77 Pipe,
78 Caret,
79 Tilde,
80 ShiftLeft,
81 ShiftRight,
82
83 PlusPlus,
84 MinusMinus,
85
86 Question,
87 QuestionQuestion,
88 Colon,
89
90 FatArrow,
91
92 PipeArrow,
93
94 LeftParen,
96 RightParen,
97 LeftBracket,
98 RightBracket,
99 LeftBrace,
100 RightBrace,
101 Semicolon,
102 Comma,
103
104 DoubleColon,
105
106 Arrow,
107
108 NullsafeArrow,
109
110 Backslash,
111
112 At,
113
114 HashBracket,
115
116 Ellipsis,
117
118 If,
120 Else,
121 ElseIf,
122 While,
123 Do,
124 For,
125 Foreach,
126 As,
127 Function,
128 Return,
129 Echo,
130 Print,
131 True,
132 False,
133 Null,
134 And,
135 Or,
136 Xor,
137 Break,
138 Continue,
139 Switch,
140 Case,
141 Default,
142 EndIf,
143 EndWhile,
144 EndFor,
145 EndForeach,
146 Throw,
147 Try,
148 Catch,
149 Finally,
150 Instanceof,
151 Array,
152 List,
153 Goto,
154 Declare,
155 Unset,
156 Global,
157 EndDeclare,
158 EndSwitch,
159 Isset,
160 Empty,
161 Include,
162 IncludeOnce,
163 Require,
164 RequireOnce,
165 Eval,
166 Exit,
167 Die,
168 Clone,
169 New,
171 Class,
172 Abstract,
173 Final,
174 Interface,
175 Trait,
176 Extends,
177 Implements,
178 Public,
179 Protected,
180 Private,
181 Static,
182 Const,
183 Fn_,
184 Match_,
185 Namespace,
186 Use,
187 Readonly,
188 Enum_,
189 Yield_,
190 From,
191 Self_,
192 Parent_,
193 MagicClass,
195 MagicDir,
196 MagicFile,
197 MagicFunction,
198 MagicLine,
199 MagicMethod,
200 MagicNamespace,
201 MagicTrait,
202 MagicProperty,
203 HaltCompiler,
204
205 OpenTag,
207
208 CloseTag,
209
210 InlineHtml,
212
213 Heredoc,
215 Nowdoc,
216
217 InvalidNumericLiteral,
219
220 LineComment,
223 HashComment,
225 BlockComment,
227 DocComment,
229
230 Eof,
232}
233
234impl TokenKind {
235 #[inline]
237 pub fn is_comment(self) -> bool {
238 matches!(
239 self,
240 TokenKind::LineComment
241 | TokenKind::HashComment
242 | TokenKind::BlockComment
243 | TokenKind::DocComment
244 )
245 }
246}
247
248impl TokenKind {
249 #[inline(always)]
250 pub fn is_assignment_op(self) -> bool {
251 (self as u8).wrapping_sub(TokenKind::Equals as u8)
254 <= (TokenKind::CoalesceEquals as u8 - TokenKind::Equals as u8)
255 }
256}
257
258pub fn resolve_keyword(text: &str) -> Option<TokenKind> {
261 let t = text;
264 match text.len() {
265 2 => {
266 if t.eq_ignore_ascii_case("if") {
267 return Some(TokenKind::If);
268 }
269 if t.eq_ignore_ascii_case("do") {
270 return Some(TokenKind::Do);
271 }
272 if t.eq_ignore_ascii_case("or") {
273 return Some(TokenKind::Or);
274 }
275 if t.eq_ignore_ascii_case("as") {
276 return Some(TokenKind::As);
277 }
278 if t.eq_ignore_ascii_case("fn") {
279 return Some(TokenKind::Fn_);
280 }
281 }
282 3 => {
283 if t.eq_ignore_ascii_case("for") {
284 return Some(TokenKind::For);
285 }
286 if t.eq_ignore_ascii_case("xor") {
287 return Some(TokenKind::Xor);
288 }
289 if t.eq_ignore_ascii_case("and") {
290 return Some(TokenKind::And);
291 }
292 if t.eq_ignore_ascii_case("new") {
293 return Some(TokenKind::New);
294 }
295 if t.eq_ignore_ascii_case("use") {
296 return Some(TokenKind::Use);
297 }
298 if t.eq_ignore_ascii_case("try") {
299 return Some(TokenKind::Try);
300 }
301 if t.eq_ignore_ascii_case("die") {
302 return Some(TokenKind::Die);
303 }
304 }
305 4 => {
306 if t.eq_ignore_ascii_case("else") {
307 return Some(TokenKind::Else);
308 }
309 if t.eq_ignore_ascii_case("echo") {
310 return Some(TokenKind::Echo);
311 }
312 if t.eq_ignore_ascii_case("true") {
313 return Some(TokenKind::True);
314 }
315 if t.eq_ignore_ascii_case("null") {
316 return Some(TokenKind::Null);
317 }
318 if t.eq_ignore_ascii_case("list") {
319 return Some(TokenKind::List);
320 }
321 if t.eq_ignore_ascii_case("goto") {
322 return Some(TokenKind::Goto);
323 }
324 if t.eq_ignore_ascii_case("case") {
325 return Some(TokenKind::Case);
326 }
327 if t.eq_ignore_ascii_case("self") {
328 return Some(TokenKind::Self_);
329 }
330 if t.eq_ignore_ascii_case("from") {
331 return Some(TokenKind::From);
332 }
333 if t.eq_ignore_ascii_case("enum") {
334 return Some(TokenKind::Enum_);
335 }
336 if t.eq_ignore_ascii_case("eval") {
337 return Some(TokenKind::Eval);
338 }
339 if t.eq_ignore_ascii_case("exit") {
340 return Some(TokenKind::Exit);
341 }
342 }
343 5 => {
344 if t.eq_ignore_ascii_case("while") {
345 return Some(TokenKind::While);
346 }
347 if t.eq_ignore_ascii_case("false") {
348 return Some(TokenKind::False);
349 }
350 if t.eq_ignore_ascii_case("array") {
351 return Some(TokenKind::Array);
352 }
353 if t.eq_ignore_ascii_case("unset") {
354 return Some(TokenKind::Unset);
355 }
356 if t.eq_ignore_ascii_case("isset") {
357 return Some(TokenKind::Isset);
358 }
359 if t.eq_ignore_ascii_case("empty") {
360 return Some(TokenKind::Empty);
361 }
362 if t.eq_ignore_ascii_case("print") {
363 return Some(TokenKind::Print);
364 }
365 if t.eq_ignore_ascii_case("throw") {
366 return Some(TokenKind::Throw);
367 }
368 if t.eq_ignore_ascii_case("catch") {
369 return Some(TokenKind::Catch);
370 }
371 if t.eq_ignore_ascii_case("break") {
372 return Some(TokenKind::Break);
373 }
374 if t.eq_ignore_ascii_case("yield") {
375 return Some(TokenKind::Yield_);
376 }
377 if t.eq_ignore_ascii_case("class") {
378 return Some(TokenKind::Class);
379 }
380 if t.eq_ignore_ascii_case("const") {
381 return Some(TokenKind::Const);
382 }
383 if t.eq_ignore_ascii_case("final") {
384 return Some(TokenKind::Final);
385 }
386 if t.eq_ignore_ascii_case("match") {
387 return Some(TokenKind::Match_);
388 }
389 if t.eq_ignore_ascii_case("trait") {
390 return Some(TokenKind::Trait);
391 }
392 if t.eq_ignore_ascii_case("clone") {
393 return Some(TokenKind::Clone);
394 }
395 if t.eq_ignore_ascii_case("endif") {
396 return Some(TokenKind::EndIf);
397 }
398 }
399 6 => {
400 if t.eq_ignore_ascii_case("elseif") {
401 return Some(TokenKind::ElseIf);
402 }
403 if t.eq_ignore_ascii_case("return") {
404 return Some(TokenKind::Return);
405 }
406 if t.eq_ignore_ascii_case("switch") {
407 return Some(TokenKind::Switch);
408 }
409 if t.eq_ignore_ascii_case("global") {
410 return Some(TokenKind::Global);
411 }
412 if t.eq_ignore_ascii_case("static") {
413 return Some(TokenKind::Static);
414 }
415 if t.eq_ignore_ascii_case("public") {
416 return Some(TokenKind::Public);
417 }
418 if t.eq_ignore_ascii_case("parent") {
419 return Some(TokenKind::Parent_);
420 }
421 if t.eq_ignore_ascii_case("endfor") {
422 return Some(TokenKind::EndFor);
423 }
424 }
425 7 => {
426 if t.eq_ignore_ascii_case("foreach") {
427 return Some(TokenKind::Foreach);
428 }
429 if t.eq_ignore_ascii_case("default") {
430 return Some(TokenKind::Default);
431 }
432 if t.eq_ignore_ascii_case("finally") {
433 return Some(TokenKind::Finally);
434 }
435 if t.eq_ignore_ascii_case("include") {
436 return Some(TokenKind::Include);
437 }
438 if t.eq_ignore_ascii_case("declare") {
439 return Some(TokenKind::Declare);
440 }
441 if t.eq_ignore_ascii_case("extends") {
442 return Some(TokenKind::Extends);
443 }
444 if t.eq_ignore_ascii_case("require") {
445 return Some(TokenKind::Require);
446 }
447 if t.eq_ignore_ascii_case("private") {
448 return Some(TokenKind::Private);
449 }
450 if t.eq_ignore_ascii_case("__dir__") {
451 return Some(TokenKind::MagicDir);
452 }
453 }
454 8 => {
455 if t.eq_ignore_ascii_case("function") {
456 return Some(TokenKind::Function);
457 }
458 if t.eq_ignore_ascii_case("abstract") {
459 return Some(TokenKind::Abstract);
460 }
461 if t.eq_ignore_ascii_case("readonly") {
462 return Some(TokenKind::Readonly);
463 }
464 if t.eq_ignore_ascii_case("continue") {
465 return Some(TokenKind::Continue);
466 }
467 if t.eq_ignore_ascii_case("endwhile") {
468 return Some(TokenKind::EndWhile);
469 }
470 if t.eq_ignore_ascii_case("__file__") {
471 return Some(TokenKind::MagicFile);
472 }
473 if t.eq_ignore_ascii_case("__line__") {
474 return Some(TokenKind::MagicLine);
475 }
476 }
477 9 => {
478 if t.eq_ignore_ascii_case("namespace") {
479 return Some(TokenKind::Namespace);
480 }
481 if t.eq_ignore_ascii_case("interface") {
482 return Some(TokenKind::Interface);
483 }
484 if t.eq_ignore_ascii_case("protected") {
485 return Some(TokenKind::Protected);
486 }
487 if t.eq_ignore_ascii_case("endswitch") {
488 return Some(TokenKind::EndSwitch);
489 }
490 if t.eq_ignore_ascii_case("__class__") {
491 return Some(TokenKind::MagicClass);
492 }
493 if t.eq_ignore_ascii_case("__trait__") {
494 return Some(TokenKind::MagicTrait);
495 }
496 }
497 10 => {
498 if t.eq_ignore_ascii_case("implements") {
499 return Some(TokenKind::Implements);
500 }
501 if t.eq_ignore_ascii_case("instanceof") {
502 return Some(TokenKind::Instanceof);
503 }
504 if t.eq_ignore_ascii_case("endforeach") {
505 return Some(TokenKind::EndForeach);
506 }
507 if t.eq_ignore_ascii_case("enddeclare") {
508 return Some(TokenKind::EndDeclare);
509 }
510 if t.eq_ignore_ascii_case("__method__") {
511 return Some(TokenKind::MagicMethod);
512 }
513 }
514 12 => {
515 if t.eq_ignore_ascii_case("include_once") {
516 return Some(TokenKind::IncludeOnce);
517 }
518 if t.eq_ignore_ascii_case("require_once") {
519 return Some(TokenKind::RequireOnce);
520 }
521 if t.eq_ignore_ascii_case("__function__") {
522 return Some(TokenKind::MagicFunction);
523 }
524 if t.eq_ignore_ascii_case("__property__") {
525 return Some(TokenKind::MagicProperty);
526 }
527 }
528 13 => {
529 if t.eq_ignore_ascii_case("__namespace__") {
530 return Some(TokenKind::MagicNamespace);
531 }
532 }
533 15 => {
534 if t.eq_ignore_ascii_case("__halt_compiler") {
535 return Some(TokenKind::HaltCompiler);
536 }
537 }
538 _ => {}
539 }
540 None
541}
542
543impl std::fmt::Display for TokenKind {
544 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
545 match self {
546 TokenKind::IntLiteral => write!(f, "integer"),
547 TokenKind::HexIntLiteral => write!(f, "hex integer"),
548 TokenKind::BinIntLiteral => write!(f, "binary integer"),
549 TokenKind::OctIntLiteral | TokenKind::OctIntLiteralNew => write!(f, "octal integer"),
550 TokenKind::FloatLiteral
551 | TokenKind::FloatLiteralSimple
552 | TokenKind::FloatLiteralLeadingDot => write!(f, "float"),
553 TokenKind::SingleQuotedString | TokenKind::DoubleQuotedString => write!(f, "string"),
554 TokenKind::BacktickString => write!(f, "backtick string"),
555 TokenKind::Variable => write!(f, "variable"),
556 TokenKind::Dollar => write!(f, "'$'"),
557 TokenKind::Identifier => write!(f, "identifier"),
558 TokenKind::Plus => write!(f, "'+'"),
559 TokenKind::Minus => write!(f, "'-'"),
560 TokenKind::Star => write!(f, "'*'"),
561 TokenKind::Slash => write!(f, "'/'"),
562 TokenKind::Percent => write!(f, "'%'"),
563 TokenKind::StarStar => write!(f, "'**'"),
564 TokenKind::Dot => write!(f, "'.'"),
565 TokenKind::Equals => write!(f, "'='"),
566 TokenKind::PlusEquals => write!(f, "'+='"),
567 TokenKind::MinusEquals => write!(f, "'-='"),
568 TokenKind::StarEquals => write!(f, "'*='"),
569 TokenKind::SlashEquals => write!(f, "'/='"),
570 TokenKind::PercentEquals => write!(f, "'%='"),
571 TokenKind::StarStarEquals => write!(f, "'**='"),
572 TokenKind::DotEquals => write!(f, "'.='"),
573 TokenKind::AmpersandEquals => write!(f, "'&='"),
574 TokenKind::PipeEquals => write!(f, "'|='"),
575 TokenKind::CaretEquals => write!(f, "'^='"),
576 TokenKind::ShiftLeftEquals => write!(f, "'<<='"),
577 TokenKind::ShiftRightEquals => write!(f, "'>>='"),
578 TokenKind::CoalesceEquals => write!(f, "'??='"),
579 TokenKind::EqualsEquals => write!(f, "'=='"),
580 TokenKind::BangEquals => write!(f, "'!='"),
581 TokenKind::EqualsEqualsEquals => write!(f, "'==='"),
582 TokenKind::BangEqualsEquals => write!(f, "'!=='"),
583 TokenKind::LessThan => write!(f, "'<'"),
584 TokenKind::GreaterThan => write!(f, "'>'"),
585 TokenKind::LessThanEquals => write!(f, "'<='"),
586 TokenKind::GreaterThanEquals => write!(f, "'>='"),
587 TokenKind::Spaceship => write!(f, "'<=>'"),
588 TokenKind::AmpersandAmpersand => write!(f, "'&&'"),
589 TokenKind::PipePipe => write!(f, "'||'"),
590 TokenKind::Bang => write!(f, "'!'"),
591 TokenKind::Ampersand => write!(f, "'&'"),
592 TokenKind::Pipe => write!(f, "'|'"),
593 TokenKind::Caret => write!(f, "'^'"),
594 TokenKind::Tilde => write!(f, "'~'"),
595 TokenKind::ShiftLeft => write!(f, "'<<'"),
596 TokenKind::ShiftRight => write!(f, "'>>'"),
597 TokenKind::PlusPlus => write!(f, "'++'"),
598 TokenKind::MinusMinus => write!(f, "'--'"),
599 TokenKind::Question => write!(f, "'?'"),
600 TokenKind::QuestionQuestion => write!(f, "'??'"),
601 TokenKind::Colon => write!(f, "':'"),
602 TokenKind::FatArrow => write!(f, "'=>'"),
603 TokenKind::PipeArrow => write!(f, "'|>'"),
604 TokenKind::LeftParen => write!(f, "'('"),
605 TokenKind::RightParen => write!(f, "')'"),
606 TokenKind::LeftBracket => write!(f, "'['"),
607 TokenKind::RightBracket => write!(f, "']'"),
608 TokenKind::LeftBrace => write!(f, "'{{'"),
609 TokenKind::RightBrace => write!(f, "'}}'"),
610 TokenKind::Semicolon => write!(f, "';'"),
611 TokenKind::Comma => write!(f, "','"),
612 TokenKind::DoubleColon => write!(f, "'::'"),
613 TokenKind::Arrow => write!(f, "'->'"),
614 TokenKind::NullsafeArrow => write!(f, "'?->'"),
615 TokenKind::Backslash => write!(f, "'\\'"),
616 TokenKind::At => write!(f, "'@'"),
617 TokenKind::HashBracket => write!(f, "'#['"),
618 TokenKind::Ellipsis => write!(f, "'...'"),
619 TokenKind::If => write!(f, "'if'"),
620 TokenKind::Else => write!(f, "'else'"),
621 TokenKind::ElseIf => write!(f, "'elseif'"),
622 TokenKind::While => write!(f, "'while'"),
623 TokenKind::Do => write!(f, "'do'"),
624 TokenKind::For => write!(f, "'for'"),
625 TokenKind::Foreach => write!(f, "'foreach'"),
626 TokenKind::As => write!(f, "'as'"),
627 TokenKind::Function => write!(f, "'function'"),
628 TokenKind::Return => write!(f, "'return'"),
629 TokenKind::Echo => write!(f, "'echo'"),
630 TokenKind::Print => write!(f, "'print'"),
631 TokenKind::True => write!(f, "'true'"),
632 TokenKind::False => write!(f, "'false'"),
633 TokenKind::Null => write!(f, "'null'"),
634 TokenKind::And => write!(f, "'and'"),
635 TokenKind::Or => write!(f, "'or'"),
636 TokenKind::Xor => write!(f, "'xor'"),
637 TokenKind::Break => write!(f, "'break'"),
638 TokenKind::Continue => write!(f, "'continue'"),
639 TokenKind::Switch => write!(f, "'switch'"),
640 TokenKind::Case => write!(f, "'case'"),
641 TokenKind::Default => write!(f, "'default'"),
642 TokenKind::EndIf => write!(f, "'endif'"),
643 TokenKind::EndWhile => write!(f, "'endwhile'"),
644 TokenKind::EndFor => write!(f, "'endfor'"),
645 TokenKind::EndForeach => write!(f, "'endforeach'"),
646 TokenKind::Throw => write!(f, "'throw'"),
647 TokenKind::Try => write!(f, "'try'"),
648 TokenKind::Catch => write!(f, "'catch'"),
649 TokenKind::Finally => write!(f, "'finally'"),
650 TokenKind::Instanceof => write!(f, "'instanceof'"),
651 TokenKind::Array => write!(f, "'array'"),
652 TokenKind::List => write!(f, "'list'"),
653 TokenKind::Goto => write!(f, "'goto'"),
654 TokenKind::Declare => write!(f, "'declare'"),
655 TokenKind::Unset => write!(f, "'unset'"),
656 TokenKind::Global => write!(f, "'global'"),
657 TokenKind::EndDeclare => write!(f, "'enddeclare'"),
658 TokenKind::EndSwitch => write!(f, "'endswitch'"),
659 TokenKind::Isset => write!(f, "'isset'"),
660 TokenKind::Empty => write!(f, "'empty'"),
661 TokenKind::Include => write!(f, "'include'"),
662 TokenKind::IncludeOnce => write!(f, "'include_once'"),
663 TokenKind::Require => write!(f, "'require'"),
664 TokenKind::RequireOnce => write!(f, "'require_once'"),
665 TokenKind::Eval => write!(f, "'eval'"),
666 TokenKind::Exit => write!(f, "'exit'"),
667 TokenKind::Die => write!(f, "'die'"),
668 TokenKind::Clone => write!(f, "'clone'"),
669 TokenKind::New => write!(f, "'new'"),
670 TokenKind::Class => write!(f, "'class'"),
671 TokenKind::Abstract => write!(f, "'abstract'"),
672 TokenKind::Final => write!(f, "'final'"),
673 TokenKind::Interface => write!(f, "'interface'"),
674 TokenKind::Trait => write!(f, "'trait'"),
675 TokenKind::Extends => write!(f, "'extends'"),
676 TokenKind::Implements => write!(f, "'implements'"),
677 TokenKind::Public => write!(f, "'public'"),
678 TokenKind::Protected => write!(f, "'protected'"),
679 TokenKind::Private => write!(f, "'private'"),
680 TokenKind::Static => write!(f, "'static'"),
681 TokenKind::Const => write!(f, "'const'"),
682 TokenKind::Fn_ => write!(f, "'fn'"),
683 TokenKind::Match_ => write!(f, "'match'"),
684 TokenKind::Namespace => write!(f, "'namespace'"),
685 TokenKind::Use => write!(f, "'use'"),
686 TokenKind::Readonly => write!(f, "'readonly'"),
687 TokenKind::Enum_ => write!(f, "'enum'"),
688 TokenKind::Yield_ => write!(f, "'yield'"),
689 TokenKind::From => write!(f, "'from'"),
690 TokenKind::Self_ => write!(f, "'self'"),
691 TokenKind::Parent_ => write!(f, "'parent'"),
692 TokenKind::MagicClass => write!(f, "'__CLASS__'"),
693 TokenKind::MagicDir => write!(f, "'__DIR__'"),
694 TokenKind::MagicFile => write!(f, "'__FILE__'"),
695 TokenKind::MagicFunction => write!(f, "'__FUNCTION__'"),
696 TokenKind::MagicLine => write!(f, "'__LINE__'"),
697 TokenKind::MagicMethod => write!(f, "'__METHOD__'"),
698 TokenKind::MagicNamespace => write!(f, "'__NAMESPACE__'"),
699 TokenKind::MagicTrait => write!(f, "'__TRAIT__'"),
700 TokenKind::MagicProperty => write!(f, "'__PROPERTY__'"),
701 TokenKind::HaltCompiler => write!(f, "'__halt_compiler'"),
702 TokenKind::OpenTag => write!(f, "'<?php'"),
703 TokenKind::CloseTag => write!(f, "'?>'"),
704 TokenKind::InlineHtml => write!(f, "inline HTML"),
705 TokenKind::Heredoc => write!(f, "heredoc"),
706 TokenKind::Nowdoc => write!(f, "nowdoc"),
707 TokenKind::InvalidNumericLiteral => write!(f, "invalid numeric literal"),
708 TokenKind::LineComment => write!(f, "line comment"),
709 TokenKind::HashComment => write!(f, "hash comment"),
710 TokenKind::BlockComment => write!(f, "block comment"),
711 TokenKind::DocComment => write!(f, "doc comment"),
712 TokenKind::Eof => write!(f, "end of file"),
713 }
714 }
715}
716
717#[cfg(test)]
718mod tests {
719 use super::*;
720
721 #[test]
722 fn test_resolve_keyword() {
723 assert_eq!(resolve_keyword("if"), Some(TokenKind::If));
724 assert_eq!(resolve_keyword("IF"), Some(TokenKind::If));
725 assert_eq!(resolve_keyword("If"), Some(TokenKind::If));
726 assert_eq!(resolve_keyword("function"), Some(TokenKind::Function));
727 assert_eq!(resolve_keyword("myFunc"), None);
728 assert_eq!(resolve_keyword("true"), Some(TokenKind::True));
729 assert_eq!(resolve_keyword("TRUE"), Some(TokenKind::True));
730 assert_eq!(resolve_keyword("null"), Some(TokenKind::Null));
731 }
732
733 #[test]
734 fn test_is_assignment_op() {
735 assert!(TokenKind::Equals.is_assignment_op());
736 assert!(TokenKind::PlusEquals.is_assignment_op());
737 assert!(TokenKind::DotEquals.is_assignment_op());
738 assert!(!TokenKind::Plus.is_assignment_op());
739 assert!(!TokenKind::EqualsEquals.is_assignment_op());
740 }
741}