1use num_bigint::BigInt;
2use swc_atoms::{atom, Atom};
3use swc_common::Span;
4use swc_ecma_ast::AssignOp;
5use swc_ecma_lexer::common::context::Context;
6
7use super::LexResult;
8use crate::input::Tokens;
9
10#[derive(Debug, Clone)]
11pub enum TokenValue {
12 Word(Atom),
14 Template {
15 raw: Atom,
16 cooked: LexResult<Atom>,
17 },
18 Str {
20 value: Atom,
21 raw: Atom,
22 },
23 Regex {
25 value: Atom,
26 flags: Atom,
27 },
28 Num {
29 value: f64,
30 raw: Atom,
31 },
32 BigInt {
33 value: Box<num_bigint::BigInt>,
34 raw: Atom,
35 },
36 Error(swc_ecma_lexer::error::Error),
37}
38
39#[derive(Clone, Copy, PartialEq, Eq)]
40#[repr(u8)]
41pub enum Token {
42 LParen,
45 RParen,
47 LBrace,
49 RBrace,
51 LBracket,
53 RBracket,
55 Semi,
57 Comma,
59 Dot,
61 Colon,
63 QuestionMark,
65 Bang,
67 Tilde,
69 Plus,
71 Minus,
73 Asterisk,
75 Slash,
77 Percent,
79 Lt,
81 Gt,
83 Pipe,
85 Caret,
87 Ampersand,
89 Eq,
91 At,
93 Hash,
95 BackQuote,
97 Arrow,
99 DotDotDot,
101
102 PlusPlus,
105 MinusMinus,
107 PlusEq,
109 MinusEq,
111
112 MulEq,
115 DivEq,
117 ModEq,
119 LShiftEq,
121 RShiftEq,
123 ZeroFillRShiftEq,
125 BitOrEq,
127 BitXorEq,
129 BitAndEq,
131 ExpEq,
133 LogicalOrEq,
135 LogicalAndEq,
137 NullishEq,
139 OptionalChain,
141
142 EqEq,
144 NotEq,
146 EqEqEq,
148 NotEqEq,
150
151 LtEq,
153 GtEq,
155 LShift,
157 RShift,
159 ZeroFillRShift,
161
162 Exp,
164 LogicalOr,
166 LogicalAnd,
168 NullishCoalescing,
170
171 LessSlash,
173 DollarLBrace,
175
176 JSXTagStart,
178 JSXTagEnd,
179
180 Str,
182 Num,
183 BigInt,
184 Regex,
185 Template,
186 NoSubstitutionTemplateLiteral,
187 TemplateHead,
188 TemplateMiddle,
189 TemplateTail,
190 JSXName,
191 JSXText,
192 Ident,
194 Await,
196 Break,
197 Case,
198 Catch,
199 Class,
200 Const,
201 Continue,
202 Debugger,
203 Default,
204 Delete,
205 Do,
206 Else,
207 Export,
208 Extends,
209 False,
210 Finally,
211 For,
212 Function,
213 If,
214 Import,
215 In,
216 InstanceOf,
217 Let,
218 New,
219 Null,
220 Return,
221 Super,
222 Switch,
223 This,
224 Throw,
225 True,
226 Try,
227 TypeOf,
228 Var,
229 Void,
230 While,
231 With,
232 Yield,
233 Module,
234
235 Abstract,
237 Any,
238 As,
239 Asserts,
240 Assert,
241 Async,
242 Bigint,
243 Boolean,
244 Constructor,
245 Declare,
246 Enum,
247 From,
248 Get,
249 Global,
250 Implements,
251 Interface,
252 Intrinsic,
253 Is,
254 Keyof,
255 Namespace,
256 Never,
257 Number,
258 Object,
259 Of,
260 Out,
261 Override,
262 Package,
263 Private,
264 Protected,
265 Public,
266 Readonly,
267 Require,
268 Set,
269 Static,
270 String,
271 Symbol,
272 Type,
273 Undefined,
274 Unique,
275 Unknown,
276 Using,
277 Accessor,
278 Infer,
279 Satisfies,
280 Meta,
281 Target,
282
283 Shebang,
285 Error,
286 Eof,
287}
288
289impl swc_ecma_lexer::common::lexer::state::TokenKind for Token {
290 #[inline(always)]
291 fn is_dot(self) -> bool {
292 self == Token::Dot
293 }
294
295 #[inline(always)]
296 fn is_bin_op(self) -> bool {
297 Token::is_bin_op(self)
298 }
299
300 #[inline(always)]
301 fn is_semi(self) -> bool {
302 self == Token::Semi
303 }
304
305 #[inline(always)]
306 fn is_template(self) -> bool {
307 self == Token::Template
308 }
309
310 #[inline(always)]
311 fn is_keyword(self) -> bool {
312 Token::is_keyword(self)
313 }
314
315 #[inline(always)]
316 fn is_colon(self) -> bool {
317 self == Token::Colon
318 }
319
320 #[inline(always)]
321 fn is_lbrace(self) -> bool {
322 self == Token::LBrace
323 }
324
325 #[inline(always)]
326 fn is_rbrace(self) -> bool {
327 self == Token::RBrace
328 }
329
330 #[inline(always)]
331 fn is_lparen(self) -> bool {
332 self == Token::LParen
333 }
334
335 #[inline(always)]
336 fn is_rparen(self) -> bool {
337 self == Token::RParen
338 }
339
340 #[inline(always)]
341 fn is_keyword_fn(self) -> bool {
342 self == Token::Function
343 }
344
345 #[inline(always)]
346 fn is_keyword_return(self) -> bool {
347 self == Token::Return
348 }
349
350 #[inline(always)]
351 fn is_keyword_yield(self) -> bool {
352 self == Token::Yield
353 }
354
355 #[inline(always)]
356 fn is_keyword_else(self) -> bool {
357 self == Token::Else
358 }
359
360 #[inline(always)]
361 fn is_keyword_class(self) -> bool {
362 self == Token::Class
363 }
364
365 #[inline(always)]
366 fn is_keyword_let(self) -> bool {
367 self == Token::Let
368 }
369
370 #[inline(always)]
371 fn is_keyword_var(self) -> bool {
372 self == Token::Var
373 }
374
375 #[inline(always)]
376 fn is_keyword_const(self) -> bool {
377 self == Token::Const
378 }
379
380 #[inline(always)]
381 fn is_keyword_if(self) -> bool {
382 self == Token::If
383 }
384
385 #[inline(always)]
386 fn is_keyword_while(self) -> bool {
387 self == Token::While
388 }
389
390 #[inline(always)]
391 fn is_keyword_for(self) -> bool {
392 self == Token::For
393 }
394
395 #[inline(always)]
396 fn is_keyword_with(self) -> bool {
397 self == Token::With
398 }
399
400 #[inline(always)]
401 fn is_lt(self) -> bool {
402 self == Token::Lt
403 }
404
405 #[inline(always)]
406 fn is_gt(self) -> bool {
407 self == Token::Gt
408 }
409
410 #[inline(always)]
411 fn is_arrow(self) -> bool {
412 self == Token::Arrow
413 }
414
415 #[inline(always)]
416 fn is_ident(self) -> bool {
417 self == Token::Ident || self.is_known_ident()
418 }
419
420 #[inline(always)]
421 fn is_known_ident_of(self) -> bool {
422 self == Token::Of
423 }
424
425 #[inline(always)]
426 fn is_slash(self) -> bool {
427 self == Token::Slash
428 }
429
430 #[inline(always)]
431 fn is_dollar_lbrace(self) -> bool {
432 self == Token::DollarLBrace
433 }
434
435 #[inline(always)]
436 fn is_plus_plus(self) -> bool {
437 self == Token::PlusPlus
438 }
439
440 #[inline(always)]
441 fn is_minus_minus(self) -> bool {
442 self == Token::MinusMinus
443 }
444
445 #[inline(always)]
446 fn is_back_quote(self) -> bool {
447 self == Token::BackQuote
448 }
449
450 #[inline(always)]
451 fn is_jsx_tag_start(self) -> bool {
452 self == Token::JSXTagStart
453 }
454
455 #[inline(always)]
456 fn is_jsx_tag_end(self) -> bool {
457 self == Token::JSXTagEnd
458 }
459
460 #[inline(always)]
461 fn before_expr(self) -> bool {
462 self.before_expr()
463 }
464}
465
466impl swc_ecma_lexer::common::lexer::state::TokenType for Token {
467 fn is_other_and_before_expr_is_false(self) -> bool {
468 !self.is_keyword()
469 && !self.is_bin_op()
470 && !self.before_expr()
471 && !matches!(
472 self,
473 Token::Template
474 | Token::Dot
475 | Token::Colon
476 | Token::LBrace
477 | Token::RParen
478 | Token::Semi
479 | Token::JSXName
480 | Token::JSXText
481 | Token::JSXTagStart
482 | Token::JSXTagEnd
483 | Token::Arrow
484 )
485 }
486
487 fn is_other_and_can_have_trailing_comment(self) -> bool {
488 matches!(
489 self,
490 Token::Num
491 | Token::Str
492 | Token::Ident
493 | Token::DollarLBrace
494 | Token::Regex
495 | Token::BigInt
496 | Token::JSXText
497 | Token::RBrace
498 ) || self.is_known_ident()
499 }
500}
501
502impl<'a, I: Tokens> swc_ecma_lexer::common::lexer::token::TokenFactory<'a, TokenAndSpan, I>
503 for Token
504{
505 type Buffer = crate::input::Buffer<I>;
506 type Lexer = crate::Lexer<'a>;
507
508 const ABSTRACT: Self = Token::Abstract;
509 const ACCESSOR: Self = Token::Accessor;
510 const ANY: Self = Token::Any;
511 const ARROW: Self = Token::Arrow;
512 const AS: Self = Token::As;
513 const ASSERT: Self = Token::Assert;
514 const ASSERTS: Self = Token::Asserts;
515 const ASYNC: Self = Token::Async;
516 const AT: Self = Token::At;
517 const AWAIT: Self = Token::Await;
518 const BACKQUOTE: Self = Token::BackQuote;
519 const BANG: Self = Self::Bang;
520 const BIGINT: Self = Token::Bigint;
521 const BIT_AND: Self = Self::Ampersand;
522 const BIT_AND_EQ: Self = Self::BitAndEq;
523 const BIT_OR: Self = Self::Pipe;
524 const BIT_OR_EQ: Self = Self::BitOrEq;
525 const BOOLEAN: Self = Token::Boolean;
526 const BREAK: Self = Token::Break;
527 const CASE: Self = Token::Case;
528 const CATCH: Self = Token::Catch;
529 const CLASS: Self = Self::Class;
530 const COLON: Self = Self::Colon;
531 const COMMA: Self = Token::Comma;
532 const CONST: Self = Self::Const;
533 const CONTINUE: Self = Token::Continue;
534 const DEBUGGER: Self = Token::Debugger;
535 const DECLARE: Self = Token::Declare;
536 const DEFAULT: Self = Token::Default;
537 const DELETE: Self = Self::Delete;
538 const DIV: Self = Token::Slash;
539 const DIV_EQ: Self = Token::DivEq;
540 const DO: Self = Token::Do;
541 const DOLLAR_LBRACE: Self = Token::DollarLBrace;
542 const DOT: Self = Self::Dot;
543 const DOTDOTDOT: Self = Self::DotDotDot;
544 const ELSE: Self = Self::Else;
545 const ENUM: Self = Token::Enum;
546 const EOF: Self = Token::Eof;
547 const EQUAL: Self = Token::Eq;
548 const EXP: Self = Token::Exp;
549 const EXPORT: Self = Token::Export;
550 const EXP_EQ: Self = Token::ExpEq;
551 const EXTENDS: Self = Token::Extends;
552 const FALSE: Self = Token::False;
553 const FINALLY: Self = Token::Finally;
554 const FOR: Self = Token::For;
555 const FROM: Self = Token::From;
556 const FUNCTION: Self = Self::Function;
557 const GET: Self = Token::Get;
558 const GLOBAL: Self = Token::Global;
559 const GREATER: Self = Token::Gt;
560 const GREATER_EQ: Self = Token::GtEq;
561 const HASH: Self = Self::Hash;
562 const IF: Self = Self::If;
563 const IMPLEMENTS: Self = Token::Implements;
564 const IMPORT: Self = Self::Import;
565 const IN: Self = Self::In;
566 const INFER: Self = Token::Infer;
567 const INSTANCEOF: Self = Token::InstanceOf;
568 const INTERFACE: Self = Token::Interface;
569 const INTRINSIC: Self = Token::Intrinsic;
570 const IS: Self = Token::Is;
571 const JSX_TAG_END: Self = Token::JSXTagEnd;
572 const JSX_TAG_START: Self = Token::JSXTagStart;
573 const KEYOF: Self = Token::Keyof;
574 const LBRACE: Self = Self::LBrace;
575 const LBRACKET: Self = Self::LBracket;
576 const LESS: Self = Token::Lt;
577 const LESS_EQ: Self = Token::LtEq;
578 const LET: Self = Token::Let;
579 const LOGICAL_AND: Self = Token::LogicalAnd;
580 const LOGICAL_AND_EQ: Self = Self::LogicalAndEq;
581 const LOGICAL_OR: Self = Token::LogicalOr;
582 const LOGICAL_OR_EQ: Self = Self::LogicalOrEq;
583 const LPAREN: Self = Self::LParen;
584 const LSHIFT: Self = Token::LShift;
585 const LSHIFT_EQ: Self = Token::LShiftEq;
586 const MINUS: Self = Self::Minus;
587 const MINUS_MINUS: Self = Self::MinusMinus;
588 const MOD: Self = Token::Percent;
589 const MOD_EQ: Self = Token::ModEq;
590 const MUL: Self = Token::Asterisk;
591 const MUL_EQ: Self = Token::MulEq;
592 const NAMESPACE: Self = Token::Namespace;
593 const NEVER: Self = Token::Never;
594 const NEW: Self = Self::New;
595 const NULL: Self = Token::Null;
596 const NULLISH_ASSIGN: Self = Token::NullishEq;
597 const NULLISH_COALESCING: Self = Token::NullishCoalescing;
598 const NUMBER: Self = Token::Number;
599 const OBJECT: Self = Token::Object;
600 const OF: Self = Token::Of;
601 const PACKAGE: Self = Token::Package;
602 const PLUS: Self = Self::Plus;
603 const PLUS_PLUS: Self = Self::PlusPlus;
604 const PRIVATE: Self = Token::Private;
605 const PROTECTED: Self = Token::Protected;
606 const PUBLIC: Self = Token::Public;
607 const QUESTION: Self = Token::QuestionMark;
608 const RBRACE: Self = Self::RBrace;
609 const RBRACKET: Self = Self::RBracket;
610 const READONLY: Self = Token::Readonly;
611 const REQUIRE: Self = Token::Require;
612 const RETURN: Self = Token::Return;
613 const RPAREN: Self = Self::RParen;
614 const RSHIFT: Self = Token::RShift;
615 const RSHIFT_EQ: Self = Token::RShiftEq;
616 const SATISFIES: Self = Token::Satisfies;
617 const SEMI: Self = Token::Semi;
618 const SET: Self = Token::Set;
619 const STATIC: Self = Token::Static;
620 const STRING: Self = Token::String;
621 const SUPER: Self = Self::Super;
622 const SWITCH: Self = Token::Switch;
623 const SYMBOL: Self = Token::Symbol;
624 const TARGET: Self = Token::Target;
625 const THIS: Self = Token::This;
626 const THROW: Self = Token::Throw;
627 const TILDE: Self = Self::Tilde;
628 const TRUE: Self = Token::True;
629 const TRY: Self = Token::Try;
630 const TYPE: Self = Token::Type;
631 const TYPEOF: Self = Self::TypeOf;
632 const UNDEFINED: Self = Token::Undefined;
633 const UNIQUE: Self = Token::Unique;
634 const UNKNOWN: Self = Token::Unknown;
635 const USING: Self = Self::Using;
636 const VAR: Self = Self::Var;
637 const VOID: Self = Self::Void;
638 const WHILE: Self = Token::While;
639 const WITH: Self = Token::With;
640 const YIELD: Self = Token::Yield;
641 const ZERO_FILL_RSHIFT: Self = Token::ZeroFillRShift;
642 const ZERO_FILL_RSHIFT_EQ: Self = Token::ZeroFillRShiftEq;
643
644 #[inline(always)]
645 fn jsx_name(name: &str, lexer: &mut crate::Lexer) -> Self {
646 let name = lexer.atoms.atom(name);
647 lexer.set_token_value(Some(TokenValue::Word(name)));
648 Token::JSXName
649 }
650
651 #[inline(always)]
652 fn is_jsx_name(&self) -> bool {
653 Token::JSXName.eq(self)
654 }
655
656 #[inline(always)]
657 fn take_jsx_name(self, buffer: &mut Self::Buffer) -> Atom {
658 buffer.expect_word_token_value()
659 }
660
661 #[inline(always)]
662 fn str(value: Atom, raw: Atom, lexer: &mut crate::Lexer<'a>) -> Self {
663 lexer.set_token_value(Some(TokenValue::Str { value, raw }));
664 Token::Str
665 }
666
667 #[inline(always)]
668 fn template(cooked: LexResult<Atom>, raw: Atom, lexer: &mut crate::Lexer<'a>) -> Self {
669 lexer.set_token_value(Some(TokenValue::Template { cooked, raw }));
670 Token::Template
671 }
672
673 #[inline(always)]
674 fn regexp(content: Atom, flags: Atom, lexer: &mut crate::Lexer<'a>) -> Self {
675 lexer.set_token_value(Some(TokenValue::Regex {
676 value: content,
677 flags,
678 }));
679 Token::Regex
680 }
681
682 #[inline(always)]
683 fn num(value: f64, raw: Atom, lexer: &mut crate::Lexer<'a>) -> Self {
684 lexer.set_token_value(Some(TokenValue::Num { value, raw }));
685 Self::Num
686 }
687
688 #[inline(always)]
689 fn bigint(value: Box<num_bigint::BigInt>, raw: Atom, lexer: &mut crate::Lexer<'a>) -> Self {
690 lexer.set_token_value(Some(TokenValue::BigInt { value, raw }));
691 Self::BigInt
692 }
693
694 #[inline(always)]
695 fn unknown_ident(value: Atom, lexer: &mut crate::Lexer<'a>) -> Self {
696 lexer.set_token_value(Some(TokenValue::Word(value)));
697 Token::Ident
698 }
699
700 #[inline(always)]
701 fn is_reserved(&self, ctx: swc_ecma_lexer::common::context::Context) -> bool {
702 self.is_reserved(ctx)
703 }
704
705 #[inline(always)]
706 fn into_atom(self, lexer: &mut crate::Lexer<'a>) -> Option<Atom> {
707 let value = lexer.get_token_value();
708 self.as_word_atom(value)
709 }
710
711 #[inline(always)]
712 fn is_error(&self) -> bool {
713 Token::Error.eq(self)
714 }
715
716 #[inline(always)]
717 fn take_error(self, buffer: &mut Self::Buffer) -> swc_ecma_lexer::error::Error {
718 buffer.expect_error_token_value()
719 }
720
721 #[inline(always)]
722 fn is_str(&self) -> bool {
723 Self::Str.eq(self)
724 }
725
726 #[inline(always)]
727 fn is_str_raw_content(&self, content: &str, buffer: &Self::Buffer) -> bool {
728 Self::Str.eq(self)
729 && if let Some(TokenValue::Str { raw, .. }) = buffer.get_token_value() {
730 raw == content
731 } else {
732 unreachable!()
733 }
734 }
735
736 #[inline(always)]
737 fn take_str(self, buffer: &mut Self::Buffer) -> (Atom, Atom) {
738 buffer.expect_string_token_value()
739 }
740
741 #[inline(always)]
742 fn is_num(&self) -> bool {
743 Self::Num.eq(self)
744 }
745
746 #[inline(always)]
747 fn take_num(self, buffer: &mut Self::Buffer) -> (f64, Atom) {
748 buffer.expect_number_token_value()
749 }
750
751 #[inline(always)]
752 fn is_bigint(&self) -> bool {
753 Self::BigInt.eq(self)
754 }
755
756 #[inline(always)]
757 fn take_bigint(self, buffer: &mut Self::Buffer) -> (Box<BigInt>, Atom) {
758 buffer.expect_bigint_token_value()
759 }
760
761 #[inline(always)]
762 fn is_word(&self) -> bool {
763 (*self).is_word()
764 }
765
766 #[inline]
767 fn take_word(self, buffer: &Self::Buffer) -> Option<Atom> {
768 self.as_word_atom(buffer.get_token_value())
769 }
770
771 #[inline(always)]
772 fn is_unknown_ident(&self) -> bool {
773 Token::Ident.eq(self)
774 }
775
776 #[inline(always)]
777 fn take_unknown_ident(self, buffer: &mut Self::Buffer) -> Atom {
778 buffer.expect_word_token_value()
779 }
780
781 #[inline(always)]
782 fn is_keyword(&self) -> bool {
783 Token::is_keyword(*self)
784 }
785
786 #[inline(always)]
787 fn is_known_ident(&self) -> bool {
788 Token::is_known_ident(*self)
789 }
790
791 #[inline(always)]
792 fn take_known_ident(&self) -> Atom {
793 self.as_known_ident_atom().unwrap()
794 }
795
796 #[inline(always)]
797 fn is_regexp(&self) -> bool {
798 Token::Regex.eq(self)
799 }
800
801 #[inline(always)]
802 fn take_unknown_ident_ref<'b>(&'b self, buffer: &'b Self::Buffer) -> &'b Atom {
803 buffer.expect_word_token_value_ref()
804 }
805
806 #[inline(always)]
807 fn is_template(&self) -> bool {
808 Token::Template.eq(self)
809 }
810
811 #[inline(always)]
812 fn take_template(self, buffer: &mut Self::Buffer) -> (LexResult<Atom>, Atom) {
813 buffer.expect_template_token_value()
814 }
815
816 #[inline(always)]
817 fn jsx_text(value: Atom, raw: Atom, lexer: &mut Self::Lexer) -> Self {
818 lexer.set_token_value(Some(TokenValue::Str { value, raw }));
819 Token::JSXText
820 }
821
822 #[inline(always)]
823 fn is_jsx_text(&self) -> bool {
824 Token::JSXText.eq(self)
825 }
826
827 #[inline(always)]
828 fn take_jsx_text(self, buffer: &mut Self::Buffer) -> (Atom, Atom) {
829 buffer.expect_string_token_value()
830 }
831
832 #[inline(always)]
833 fn starts_expr(&self) -> bool {
834 (*self).starts_expr()
835 }
836
837 #[inline(always)]
838 fn to_string(&self, buffer: &Self::Buffer) -> String {
839 (*self).to_string(buffer.get_token_value())
840 }
841
842 #[inline(always)]
843 fn is_bin_op(&self) -> bool {
844 (*self).is_bin_op()
845 }
846
847 #[inline(always)]
848 fn as_assign_op(&self) -> Option<AssignOp> {
849 (*self).as_assign_op()
850 }
851
852 #[inline(always)]
853 fn as_bin_op(&self) -> Option<swc_ecma_ast::BinaryOp> {
854 (*self).as_bin_op()
855 }
856
857 #[inline(always)]
858 fn follows_keyword_let(&self) -> bool {
859 (*self).follows_keyword_let()
860 }
861
862 #[inline(always)]
863 fn is_assign_op(&self) -> bool {
864 (*self).is_assign_op()
865 }
866
867 #[inline(always)]
868 fn take_regexp(self, buffer: &mut Self::Buffer) -> (Atom, Atom) {
869 buffer.expect_regex_token_value()
870 }
871
872 #[inline(always)]
873 fn shebang(value: Atom, lexer: &mut Self::Lexer) -> Self {
874 lexer.set_token_value(Some(TokenValue::Word(value)));
875 Token::Shebang
876 }
877
878 #[inline(always)]
879 fn is_shebang(&self) -> bool {
880 Token::Shebang.eq(self)
881 }
882
883 #[inline(always)]
884 fn take_shebang(self, buffer: &mut Self::Buffer) -> Atom {
885 buffer.expect_word_token_value()
886 }
887
888 #[inline(always)]
889 fn is_no_substitution_template_literal(&self) -> bool {
890 Token::NoSubstitutionTemplateLiteral.eq(self)
891 }
892
893 #[inline(always)]
894 fn is_template_head(&self) -> bool {
895 Token::TemplateHead.eq(self)
896 }
897}
898
899impl std::fmt::Debug for Token {
900 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
901 let s = match self {
902 Token::Str => "<string literal>",
903 Token::Num => "<number literal>",
904 Token::BigInt => "<bigint literal>",
905 Token::Regex => "<regexp literal>",
906 Token::Template => "<template literal>",
907 Token::JSXName => "<jsx name>",
908 Token::JSXText => "<jsx text>",
909 Token::Ident => "<identifier>",
910 _ => &self.to_string(None),
911 };
912 f.write_str(s)
913 }
914}
915
916impl Token {
917 pub(crate) fn is_reserved(&self, ctx: Context) -> bool {
918 match self {
919 Token::Let | Token::Static => ctx.contains(Context::Strict),
920 Token::Await => {
921 ctx.contains(Context::InAsync)
922 || ctx.contains(Context::InStaticBlock)
923 || ctx.contains(Context::Strict)
924 }
925 Token::Yield => ctx.contains(Context::InGenerator) || ctx.contains(Context::Strict),
926
927 Token::Null
928 | Token::True
929 | Token::False
930 | Token::Break
931 | Token::Case
932 | Token::Catch
933 | Token::Continue
934 | Token::Debugger
935 | Token::Default
936 | Token::Do
937 | Token::Export
938 | Token::Else
939 | Token::Finally
940 | Token::For
941 | Token::Function
942 | Token::If
943 | Token::Return
944 | Token::Switch
945 | Token::Throw
946 | Token::Try
947 | Token::Var
948 | Token::Const
949 | Token::While
950 | Token::With
951 | Token::New
952 | Token::This
953 | Token::Super
954 | Token::Class
955 | Token::Extends
956 | Token::Import
957 | Token::In
958 | Token::InstanceOf
959 | Token::TypeOf
960 | Token::Void
961 | Token::Delete => true,
962
963 Token::Enum => true,
965
966 Token::Implements
967 | Token::Package
968 | Token::Protected
969 | Token::Interface
970 | Token::Private
971 | Token::Public
972 if ctx.contains(Context::Strict) =>
973 {
974 true
975 }
976
977 _ => false,
978 }
979 }
980
981 #[cold]
982 pub(crate) fn to_string(self, value: Option<&TokenValue>) -> String {
983 match self {
984 Token::LParen => "(",
985 Token::RParen => ")",
986 Token::LBrace => "{",
987 Token::RBrace => "}",
988 Token::LBracket => "[",
989 Token::RBracket => "]",
990 Token::Semi => ";",
991 Token::Comma => ",",
992 Token::Dot => ".",
993 Token::Colon => ":",
994 Token::QuestionMark => "?",
995 Token::Bang => "!",
996 Token::Tilde => "~",
997 Token::Plus => "+",
998 Token::Minus => "-",
999 Token::Asterisk => "*",
1000 Token::Slash => "/",
1001 Token::Percent => "%",
1002 Token::Lt => "<",
1003 Token::Gt => ">",
1004 Token::Pipe => "|",
1005 Token::Caret => "^",
1006 Token::Ampersand => "&",
1007 Token::Eq => "=",
1008 Token::At => "@",
1009 Token::Hash => "#",
1010 Token::BackQuote => "`",
1011 Token::Arrow => "=>",
1012 Token::DotDotDot => "...",
1013 Token::PlusPlus => "++",
1014 Token::MinusMinus => "--",
1015 Token::PlusEq => "+",
1016 Token::MinusEq => "-",
1017 Token::MulEq => "*",
1018 Token::DivEq => "/=",
1019 Token::ModEq => "%=",
1020 Token::LShiftEq => "<<=",
1021 Token::RShiftEq => ">>=",
1022 Token::ZeroFillRShiftEq => ">>>=",
1023 Token::BitOrEq => "|=",
1024 Token::BitXorEq => "^=",
1025 Token::BitAndEq => "&=",
1026 Token::ExpEq => "**=",
1027 Token::LogicalOrEq => "||=",
1028 Token::LogicalAndEq => "&&=",
1029 Token::NullishEq => "??=",
1030 Token::OptionalChain => "?.",
1031 Token::EqEq => "==",
1032 Token::NotEq => "!=",
1033 Token::EqEqEq => "===",
1034 Token::NotEqEq => "!==",
1035 Token::LtEq => "<=",
1036 Token::GtEq => ">=",
1037 Token::LShift => "<<",
1038 Token::RShift => ">>",
1039 Token::ZeroFillRShift => ">>>",
1040 Token::Exp => "**",
1041 Token::LogicalOr => "||",
1042 Token::LogicalAnd => "&&",
1043 Token::NullishCoalescing => "??",
1044 Token::DollarLBrace => "${",
1045 Token::JSXTagStart => "jsx tag start",
1046 Token::JSXTagEnd => "jsx tag end",
1047 Token::JSXText => {
1048 let Some(TokenValue::Str { raw, .. }) = value else {
1049 unreachable!("{:#?}", value)
1050 };
1051 return format!("jsx text ({raw})");
1052 }
1053 Token::Str => {
1054 let Some(TokenValue::Str { value, raw, .. }) = value else {
1055 unreachable!("{:#?}", value)
1056 };
1057 return format!("string literal ({value}, {raw})");
1058 }
1059 Token::Num => {
1060 let Some(TokenValue::Num { value, raw, .. }) = value else {
1061 unreachable!("{:#?}", value)
1062 };
1063 return format!("numeric literal ({value}, {raw})");
1064 }
1065 Token::BigInt => {
1066 let Some(TokenValue::BigInt { value, raw, .. }) = value else {
1067 unreachable!("{:#?}", value)
1068 };
1069 return format!("bigint literal ({value}, {raw})");
1070 }
1071 Token::Regex => {
1072 let Some(TokenValue::Regex { value, flags, .. }) = value else {
1073 unreachable!("{:#?}", value)
1074 };
1075 return format!("regexp literal ({value}, {flags})");
1076 }
1077 Token::Template => {
1078 let Some(TokenValue::Template { raw, .. }) = value else {
1079 unreachable!("{:#?}", value)
1080 };
1081 return format!("template token ({raw})");
1082 }
1083 Token::JSXName => {
1084 let Some(TokenValue::Word(w)) = value else {
1085 unreachable!("{:#?}", value)
1086 };
1087 return format!("jsx name ({w})");
1088 }
1089 Token::Error => {
1090 let Some(TokenValue::Error(e)) = value else {
1091 unreachable!("{:#?}", value)
1092 };
1093 return format!("<lexing error: {e:?}>");
1094 }
1095 Token::Ident => {
1096 let Some(TokenValue::Word(w)) = value else {
1097 unreachable!("{:#?}", value)
1098 };
1099 w.as_ref()
1100 }
1101 Token::NoSubstitutionTemplateLiteral
1102 | Token::TemplateHead
1103 | Token::TemplateMiddle
1104 | Token::TemplateTail => {
1105 let Some(TokenValue::Template { raw, .. }) = value else {
1106 unreachable!("{:#?}", value)
1107 };
1108 raw
1109 }
1110 Token::Await => "await",
1111 Token::Break => "break",
1112 Token::Case => "case",
1113 Token::Catch => "catch",
1114 Token::Class => "class",
1115 Token::Const => "const",
1116 Token::Continue => "continue",
1117 Token::Debugger => "debugger",
1118 Token::Default => "default",
1119 Token::Delete => "delete",
1120 Token::Do => "do",
1121 Token::Else => "else",
1122 Token::Export => "export",
1123 Token::Extends => "extends",
1124 Token::False => "false",
1125 Token::Finally => "finally",
1126 Token::For => "for",
1127 Token::Function => "function",
1128 Token::If => "if",
1129 Token::Import => "import",
1130 Token::In => "in",
1131 Token::InstanceOf => "instanceOf",
1132 Token::Let => "let",
1133 Token::New => "new",
1134 Token::Null => "null",
1135 Token::Return => "return",
1136 Token::Super => "super",
1137 Token::Switch => "switch",
1138 Token::This => "this",
1139 Token::Throw => "throw",
1140 Token::True => "true",
1141 Token::Try => "try",
1142 Token::TypeOf => "typeOf",
1143 Token::Var => "var",
1144 Token::Void => "void",
1145 Token::While => "while",
1146 Token::With => "with",
1147 Token::Yield => "yield",
1148 Token::Module => "module",
1149 Token::Abstract => "abstract",
1150 Token::Any => "any",
1151 Token::As => "as",
1152 Token::Asserts => "asserts",
1153 Token::Assert => "assert",
1154 Token::Async => "async",
1155 Token::Bigint => "bigint",
1156 Token::Boolean => "boolean",
1157 Token::Constructor => "constructor",
1158 Token::Declare => "declare",
1159 Token::Enum => "enum",
1160 Token::From => "from",
1161 Token::Get => "get",
1162 Token::Global => "global",
1163 Token::Implements => "implements",
1164 Token::Interface => "interface",
1165 Token::Intrinsic => "intrinsic",
1166 Token::Is => "is",
1167 Token::Keyof => "keyof",
1168 Token::Namespace => "namespace",
1169 Token::Never => "never",
1170 Token::Number => "number",
1171 Token::Object => "object",
1172 Token::Of => "of",
1173 Token::Out => "out",
1174 Token::Override => "override",
1175 Token::Package => "package",
1176 Token::Private => "private",
1177 Token::Protected => "protected",
1178 Token::Public => "public",
1179 Token::Readonly => "readonly",
1180 Token::Require => "require",
1181 Token::Set => "set",
1182 Token::Static => "static",
1183 Token::String => "string",
1184 Token::Symbol => "symbol",
1185 Token::Type => "type",
1186 Token::Undefined => "undefined",
1187 Token::Unique => "unique",
1188 Token::Unknown => "unknown",
1189 Token::Using => "using",
1190 Token::Accessor => "accessor",
1191 Token::Infer => "infer",
1192 Token::Satisfies => "satisfies",
1193 Token::Meta => "meta",
1194 Token::Target => "target",
1195 Token::Shebang => "#!",
1196 Token::LessSlash => "</",
1197 Token::Eof => "<eof>",
1198 }
1199 .to_string()
1200 }
1201
1202 pub(crate) fn as_keyword_atom(self) -> Option<Atom> {
1203 let atom = match self {
1204 Token::Await => atom!("await"),
1205 Token::Break => atom!("break"),
1206 Token::Case => atom!("case"),
1207 Token::Catch => atom!("catch"),
1208 Token::Class => atom!("class"),
1209 Token::Const => atom!("const"),
1210 Token::Continue => atom!("continue"),
1211 Token::Debugger => atom!("debugger"),
1212 Token::Default => atom!("default"),
1213 Token::Delete => atom!("delete"),
1214 Token::Do => atom!("do"),
1215 Token::Else => atom!("else"),
1216 Token::Export => atom!("export"),
1217 Token::Extends => atom!("extends"),
1218 Token::Finally => atom!("finally"),
1219 Token::For => atom!("for"),
1220 Token::Function => atom!("function"),
1221 Token::If => atom!("if"),
1222 Token::Import => atom!("import"),
1223 Token::In => atom!("in"),
1224 Token::InstanceOf => atom!("instanceof"),
1225 Token::Let => atom!("let"),
1226 Token::New => atom!("new"),
1227 Token::Return => atom!("return"),
1228 Token::Super => atom!("super"),
1229 Token::Switch => atom!("switch"),
1230 Token::This => atom!("this"),
1231 Token::Throw => atom!("throw"),
1232 Token::Try => atom!("try"),
1233 Token::TypeOf => atom!("typeof"),
1234 Token::Var => atom!("var"),
1235 Token::Void => atom!("void"),
1236 Token::While => atom!("while"),
1237 Token::With => atom!("with"),
1238 Token::Yield => atom!("yield"),
1239 Token::Module => atom!("module"),
1240 _ => return None,
1241 };
1242 Some(atom)
1243 }
1244
1245 pub(crate) const fn is_keyword(self) -> bool {
1246 let t = self as u8;
1247 t >= Token::Await as u8 && t <= Token::Module as u8
1248 }
1249
1250 pub(crate) fn as_known_ident_atom(self) -> Option<Atom> {
1251 let atom = match self {
1252 Token::Abstract => atom!("abstract"),
1253 Token::Any => atom!("any"),
1254 Token::As => atom!("as"),
1255 Token::Asserts => atom!("asserts"),
1256 Token::Assert => atom!("assert"),
1257 Token::Async => atom!("async"),
1258 Token::Bigint => atom!("bigint"),
1259 Token::Boolean => atom!("boolean"),
1260 Token::Constructor => atom!("constructor"),
1261 Token::Declare => atom!("declare"),
1262 Token::Enum => atom!("enum"),
1263 Token::From => atom!("from"),
1264 Token::Get => atom!("get"),
1265 Token::Global => atom!("global"),
1266 Token::Implements => atom!("implements"),
1267 Token::Interface => atom!("interface"),
1268 Token::Intrinsic => atom!("intrinsic"),
1269 Token::Is => atom!("is"),
1270 Token::Keyof => atom!("keyof"),
1271 Token::Namespace => atom!("namespace"),
1272 Token::Never => atom!("never"),
1273 Token::Number => atom!("number"),
1274 Token::Object => atom!("object"),
1275 Token::Of => atom!("of"),
1276 Token::Out => atom!("out"),
1277 Token::Override => atom!("override"),
1278 Token::Package => atom!("package"),
1279 Token::Private => atom!("private"),
1280 Token::Protected => atom!("protected"),
1281 Token::Public => atom!("public"),
1282 Token::Readonly => atom!("readonly"),
1283 Token::Require => atom!("require"),
1284 Token::Set => atom!("set"),
1285 Token::Static => atom!("static"),
1286 Token::String => atom!("string"),
1287 Token::Symbol => atom!("symbol"),
1288 Token::Type => atom!("type"),
1289 Token::Undefined => atom!("undefined"),
1290 Token::Unique => atom!("unique"),
1291 Token::Unknown => atom!("unknown"),
1292 Token::Using => atom!("using"),
1293 Token::Accessor => atom!("accessor"),
1294 Token::Infer => atom!("infer"),
1295 Token::Satisfies => atom!("satisfies"),
1296 Token::Meta => atom!("meta"),
1297 Token::Target => atom!("target"),
1298 _ => return None,
1299 };
1300 Some(atom)
1301 }
1302
1303 #[inline(always)]
1304 pub(crate) const fn is_known_ident(self) -> bool {
1305 let t = self as u8;
1306 t >= Token::Abstract as u8 && t <= Token::Target as u8
1307 }
1308
1309 pub(crate) const fn is_word(self) -> bool {
1310 matches!(
1311 self,
1312 Token::Null | Token::True | Token::False | Token::Ident
1313 ) || self.is_known_ident()
1314 || self.is_keyword()
1315 }
1316
1317 pub(crate) fn as_word_atom(self, value: Option<&TokenValue>) -> Option<Atom> {
1318 match self {
1319 Token::Null => Some(atom!("null")),
1320 Token::True => Some(atom!("true")),
1321 Token::False => Some(atom!("false")),
1322 Token::Ident => {
1323 let Some(TokenValue::Word(w)) = value else {
1324 unreachable!("{:#?}", value)
1325 };
1326 Some(w.clone())
1327 }
1328 _ => self
1329 .as_known_ident_atom()
1330 .or_else(|| self.as_keyword_atom()),
1331 }
1332 }
1333
1334 #[inline(always)]
1335 pub(crate) const fn is_bin_op(self) -> bool {
1336 let t = self as u8;
1337 (t >= Token::EqEq as u8 && t <= Token::NullishCoalescing as u8)
1338 || (t >= Token::Plus as u8 && t <= Token::Ampersand as u8)
1339 }
1340
1341 pub(crate) fn as_bin_op(self) -> Option<swc_ecma_ast::BinaryOp> {
1342 match self {
1343 Token::EqEq => Some(swc_ecma_ast::BinaryOp::EqEq),
1344 Token::NotEq => Some(swc_ecma_ast::BinaryOp::NotEq),
1345 Token::EqEqEq => Some(swc_ecma_ast::BinaryOp::EqEqEq),
1346 Token::NotEqEq => Some(swc_ecma_ast::BinaryOp::NotEqEq),
1347 Token::Lt => Some(swc_ecma_ast::BinaryOp::Lt),
1348 Token::LtEq => Some(swc_ecma_ast::BinaryOp::LtEq),
1349 Token::Gt => Some(swc_ecma_ast::BinaryOp::Gt),
1350 Token::GtEq => Some(swc_ecma_ast::BinaryOp::GtEq),
1351 Token::LShift => Some(swc_ecma_ast::BinaryOp::LShift),
1352 Token::RShift => Some(swc_ecma_ast::BinaryOp::RShift),
1353 Token::ZeroFillRShift => Some(swc_ecma_ast::BinaryOp::ZeroFillRShift),
1354 Token::Plus => Some(swc_ecma_ast::BinaryOp::Add),
1355 Token::Minus => Some(swc_ecma_ast::BinaryOp::Sub),
1356 Token::Asterisk => Some(swc_ecma_ast::BinaryOp::Mul),
1357 Token::Slash => Some(swc_ecma_ast::BinaryOp::Div),
1358 Token::Percent => Some(swc_ecma_ast::BinaryOp::Mod),
1359 Token::Pipe => Some(swc_ecma_ast::BinaryOp::BitOr),
1360 Token::Caret => Some(swc_ecma_ast::BinaryOp::BitXor),
1361 Token::Ampersand => Some(swc_ecma_ast::BinaryOp::BitAnd),
1362 Token::LogicalOr => Some(swc_ecma_ast::BinaryOp::LogicalOr),
1363 Token::LogicalAnd => Some(swc_ecma_ast::BinaryOp::LogicalAnd),
1364 Token::Exp => Some(swc_ecma_ast::BinaryOp::Exp),
1367 Token::NullishCoalescing => Some(swc_ecma_ast::BinaryOp::NullishCoalescing),
1368 _ => None,
1369 }
1370 }
1371
1372 #[inline(always)]
1373 pub(crate) const fn is_assign_op(self) -> bool {
1374 let t = self as u8;
1375 matches!(self, Token::Eq) || (t >= Token::PlusEq as u8 && t <= Token::NullishEq as u8)
1376 }
1377
1378 pub(crate) fn as_assign_op(self) -> Option<swc_ecma_ast::AssignOp> {
1379 match self {
1380 Self::Eq => Some(AssignOp::Assign),
1381 Self::PlusEq => Some(AssignOp::AddAssign),
1382 Self::MinusEq => Some(AssignOp::SubAssign),
1383 Self::MulEq => Some(AssignOp::MulAssign),
1384 Self::DivEq => Some(AssignOp::DivAssign),
1385 Self::ModEq => Some(AssignOp::ModAssign),
1386 Self::LShiftEq => Some(AssignOp::LShiftAssign),
1387 Self::RShiftEq => Some(AssignOp::RShiftAssign),
1388 Self::ZeroFillRShiftEq => Some(AssignOp::ZeroFillRShiftAssign),
1389 Self::BitOrEq => Some(AssignOp::BitOrAssign),
1390 Self::BitXorEq => Some(AssignOp::BitXorAssign),
1391 Self::BitAndEq => Some(AssignOp::BitAndAssign),
1392 Self::ExpEq => Some(AssignOp::ExpAssign),
1393 Self::LogicalAndEq => Some(AssignOp::AndAssign),
1394 Self::LogicalOrEq => Some(AssignOp::OrAssign),
1395 Self::NullishEq => Some(AssignOp::NullishAssign),
1396 _ => None,
1397 }
1398 }
1399
1400 #[inline(always)]
1401 pub(crate) const fn before_expr(self) -> bool {
1402 match self {
1403 Self::Await
1404 | Self::Case
1405 | Self::Default
1406 | Self::Do
1407 | Self::Else
1408 | Self::Return
1409 | Self::Throw
1410 | Self::New
1411 | Self::Extends
1412 | Self::Yield
1413 | Self::In
1414 | Self::InstanceOf
1415 | Self::TypeOf
1416 | Self::Void
1417 | Self::Delete
1418 | Self::Arrow
1419 | Self::DotDotDot
1420 | Self::Bang
1421 | Self::LParen
1422 | Self::LBrace
1423 | Self::LBracket
1424 | Self::Semi
1425 | Self::Comma
1426 | Self::Colon
1427 | Self::DollarLBrace
1428 | Self::QuestionMark
1429 | Self::PlusPlus
1430 | Self::MinusMinus
1431 | Self::Tilde
1432 | Self::JSXText => true,
1433 _ => self.is_bin_op() || self.is_assign_op(),
1434 }
1435 }
1436
1437 #[inline(always)]
1438 pub(crate) const fn starts_expr(self) -> bool {
1439 matches!(
1440 self,
1441 Self::Ident
1442 | Self::JSXName
1443 | Self::Plus
1444 | Self::Minus
1445 | Self::Bang
1446 | Self::LParen
1447 | Self::LBrace
1448 | Self::LBracket
1449 | Self::TemplateHead
1450 | Self::NoSubstitutionTemplateLiteral
1451 | Self::DollarLBrace
1452 | Self::PlusPlus
1453 | Self::MinusMinus
1454 | Self::Tilde
1455 | Self::Str
1456 | Self::Regex
1457 | Self::Num
1458 | Self::BigInt
1459 | Self::JSXTagStart
1460 | Self::Await
1461 | Self::Function
1462 | Self::Throw
1463 | Self::New
1464 | Self::This
1465 | Self::Super
1466 | Self::Class
1467 | Self::Import
1468 | Self::Yield
1469 | Self::TypeOf
1470 | Self::Void
1471 | Self::Delete
1472 | Self::Null
1473 | Self::True
1474 | Self::False
1475 | Self::BackQuote
1476 ) || self.is_known_ident()
1477 }
1478
1479 pub(crate) fn follows_keyword_let(self) -> bool {
1480 match self {
1481 Token::Let
1482 | Token::LBrace
1483 | Token::LBracket
1484 | Token::Ident
1485 | Token::Yield
1486 | Token::Await => true,
1487 _ if self.is_known_ident() => true,
1488 _ => false,
1489 }
1490 }
1491
1492 pub(crate) fn should_rescan_into_gt_in_jsx(self) -> bool {
1493 matches!(
1494 self,
1495 Token::GtEq
1496 | Token::RShift
1497 | Token::RShiftEq
1498 | Token::ZeroFillRShift
1499 | Token::ZeroFillRShiftEq
1500 )
1501 }
1502}
1503
1504#[derive(Clone, Copy, Debug)]
1505pub struct TokenAndSpan {
1506 pub token: Token,
1507 pub had_line_break: bool,
1509 pub span: Span,
1510}
1511
1512impl swc_ecma_lexer::common::parser::token_and_span::TokenAndSpan for TokenAndSpan {
1513 type Token = Token;
1514
1515 #[inline(always)]
1516 fn new(token: Token, span: Span, had_line_break: bool) -> Self {
1517 Self {
1518 token,
1519 had_line_break,
1520 span,
1521 }
1522 }
1523
1524 #[inline(always)]
1525 fn token(&self) -> &Token {
1526 &self.token
1527 }
1528
1529 #[inline(always)]
1530 fn take_token(self) -> Token {
1531 self.token
1532 }
1533
1534 #[inline(always)]
1535 fn had_line_break(&self) -> bool {
1536 self.had_line_break
1537 }
1538
1539 #[inline]
1540 fn span(&self) -> Span {
1541 self.span
1542 }
1543}
1544
1545#[derive(Clone)]
1546pub struct NextTokenAndSpan {
1547 pub token_and_span: TokenAndSpan,
1548 pub value: Option<TokenValue>,
1549}
1550
1551impl swc_ecma_lexer::common::parser::buffer::NextTokenAndSpan for NextTokenAndSpan {
1552 type Token = Token;
1553
1554 #[inline(always)]
1555 fn token(&self) -> &Self::Token {
1556 &self.token_and_span.token
1557 }
1558
1559 #[inline(always)]
1560 fn span(&self) -> Span {
1561 self.token_and_span.span
1562 }
1563
1564 #[inline(always)]
1565 fn had_line_break(&self) -> bool {
1566 self.token_and_span.had_line_break
1567 }
1568}