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