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