swc_ecma_lexer/
token.rs

1//! Ported from [babel/babylon][]
2//!
3//! [babel/babylon]:https://github.com/babel/babel/blob/2d378d076eb0c5fe63234a8b509886005c01d7ee/packages/babylon/src/tokenizer/types.js
4use num_bigint::BigInt as BigIntValue;
5use swc_atoms::{Atom, Wtf8Atom};
6use swc_common::Span;
7pub(crate) use swc_ecma_ast::{AssignOp, BinaryOp};
8pub use swc_ecma_parser::{
9    known_ident,
10    token::{
11        BinOpToken, IdentKind, IdentLike, Keyword, KnownIdent, Token, TokenAndSpan, TokenKind,
12        Word, WordKind,
13    },
14};
15
16pub(crate) use self::Token::*;
17use crate::{
18    common::{
19        input::Tokens,
20        lexer::{LexResult, Lexer},
21    },
22    tok,
23};
24
25impl crate::common::lexer::state::TokenKind for TokenKind {
26    #[inline(always)]
27    fn is_dot(self) -> bool {
28        self == Self::Dot
29    }
30
31    #[inline(always)]
32    fn is_bin_op(self) -> bool {
33        matches!(self, Self::BinOp(_))
34    }
35
36    #[inline(always)]
37    fn is_semi(self) -> bool {
38        self == Self::Semi
39    }
40
41    #[inline(always)]
42    fn is_template(self) -> bool {
43        self == Self::Template
44    }
45
46    #[inline(always)]
47    fn is_keyword(self) -> bool {
48        matches!(self, Self::Word(WordKind::Keyword(_)))
49    }
50
51    #[inline(always)]
52    fn is_colon(self) -> bool {
53        self == Self::Colon
54    }
55
56    #[inline(always)]
57    fn is_lbrace(self) -> bool {
58        self == Self::LBrace
59    }
60
61    #[inline(always)]
62    fn is_rbrace(self) -> bool {
63        self == Self::RBrace
64    }
65
66    #[inline(always)]
67    fn is_lparen(self) -> bool {
68        self == Self::LParen
69    }
70
71    #[inline(always)]
72    fn is_rparen(self) -> bool {
73        self == Self::RParen
74    }
75
76    #[inline(always)]
77    fn is_keyword_fn(self) -> bool {
78        self == Self::Word(WordKind::Keyword(Keyword::Function))
79    }
80
81    #[inline(always)]
82    fn is_keyword_return(self) -> bool {
83        self == Self::Word(WordKind::Keyword(Keyword::Return))
84    }
85
86    #[inline(always)]
87    fn is_keyword_yield(self) -> bool {
88        self == Self::Word(WordKind::Keyword(Keyword::Yield))
89    }
90
91    #[inline(always)]
92    fn is_keyword_else(self) -> bool {
93        self == Self::Word(WordKind::Keyword(Keyword::Else))
94    }
95
96    #[inline(always)]
97    fn is_keyword_class(self) -> bool {
98        self == Self::Word(WordKind::Keyword(Keyword::Class))
99    }
100
101    #[inline(always)]
102    fn is_keyword_let(self) -> bool {
103        self == Self::Word(WordKind::Keyword(Keyword::Let))
104    }
105
106    #[inline(always)]
107    fn is_keyword_var(self) -> bool {
108        self == Self::Word(WordKind::Keyword(Keyword::Var))
109    }
110
111    #[inline(always)]
112    fn is_keyword_const(self) -> bool {
113        self == Self::Word(WordKind::Keyword(Keyword::Const))
114    }
115
116    #[inline(always)]
117    fn is_keyword_if(self) -> bool {
118        self == Self::Word(WordKind::Keyword(Keyword::If))
119    }
120
121    #[inline(always)]
122    fn is_keyword_while(self) -> bool {
123        self == Self::Word(WordKind::Keyword(Keyword::While))
124    }
125
126    #[inline(always)]
127    fn is_keyword_for(self) -> bool {
128        self == Self::Word(WordKind::Keyword(Keyword::For))
129    }
130
131    #[inline(always)]
132    fn is_keyword_with(self) -> bool {
133        self == Self::Word(WordKind::Keyword(Keyword::With))
134    }
135
136    #[inline(always)]
137    fn is_lt(self) -> bool {
138        self == Self::BinOp(BinOpToken::Lt)
139    }
140
141    #[inline(always)]
142    fn is_gt(self) -> bool {
143        self == Self::BinOp(BinOpToken::Gt)
144    }
145
146    #[inline(always)]
147    fn is_arrow(self) -> bool {
148        self == Self::Arrow
149    }
150
151    #[inline(always)]
152    fn is_ident(self) -> bool {
153        matches!(self, Self::Word(WordKind::Ident(_)))
154    }
155
156    #[inline(always)]
157    fn is_known_ident_of(self) -> bool {
158        self == Self::Word(WordKind::Ident(IdentKind::Known(KnownIdent::Of)))
159    }
160
161    #[inline(always)]
162    fn is_slash(self) -> bool {
163        self == Self::BinOp(BinOpToken::Div)
164    }
165
166    #[inline(always)]
167    fn is_dollar_lbrace(self) -> bool {
168        self == Self::DollarLBrace
169    }
170
171    #[inline(always)]
172    fn is_plus_plus(self) -> bool {
173        self == Self::PlusPlus
174    }
175
176    #[inline(always)]
177    fn is_minus_minus(self) -> bool {
178        self == Self::MinusMinus
179    }
180
181    #[inline(always)]
182    fn is_back_quote(self) -> bool {
183        self == Self::BackQuote
184    }
185
186    #[inline(always)]
187    fn before_expr(self) -> bool {
188        self.before_expr()
189    }
190
191    #[inline(always)]
192    fn is_jsx_tag_start(self) -> bool {
193        self == Self::JSXTagStart
194    }
195
196    #[inline(always)]
197    fn is_jsx_tag_end(self) -> bool {
198        self == Self::JSXTagEnd
199    }
200}
201
202impl<'a, I: Tokens<TokenAndSpan>> crate::common::lexer::token::TokenFactory<'a, TokenAndSpan, I>
203    for Token
204{
205    type Buffer = crate::input::Buffer<I>;
206    type Lexer = crate::Lexer<'a>;
207
208    const ABSTRACT: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Abstract)));
209    const ACCESSOR: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Accessor)));
210    const ANY: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Any)));
211    const ARROW: Self = Self::Arrow;
212    const AS: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::As)));
213    const ASSERT: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Assert)));
214    const ASSERTS: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Asserts)));
215    const ASYNC: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Async)));
216    const AT: Self = Self::At;
217    const AWAIT: Self = Token::Word(Word::Keyword(Keyword::Await));
218    const BACKQUOTE: Self = Self::BackQuote;
219    const BANG: Self = Self::Bang;
220    const BIGINT: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Bigint)));
221    const BIT_AND: Self = Self::BinOp(BinOpToken::BitAnd);
222    const BIT_AND_EQ: Self = Self::AssignOp(AssignOp::BitAndAssign);
223    const BIT_OR: Self = Self::BinOp(BinOpToken::BitOr);
224    const BIT_OR_EQ: Self = Self::AssignOp(AssignOp::BitOrAssign);
225    const BOOLEAN: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Boolean)));
226    const BREAK: Self = Token::Word(Word::Keyword(Keyword::Break));
227    const CASE: Self = Self::Word(Word::Keyword(Keyword::Case));
228    const CATCH: Self = Self::Word(Word::Keyword(Keyword::Catch));
229    const CLASS: Self = Token::Word(Word::Keyword(Keyword::Class));
230    const COLON: Self = Self::Colon;
231    const COMMA: Self = Self::Comma;
232    const CONST: Self = Token::Word(Word::Keyword(Keyword::Const));
233    const CONTINUE: Self = Self::Word(Word::Keyword(Keyword::Continue));
234    const DEBUGGER: Self = Self::Word(Word::Keyword(Keyword::Debugger));
235    const DECLARE: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Declare)));
236    const DEFAULT: Self = Self::Word(Word::Keyword(Keyword::Default_));
237    const DELETE: Self = Token::Word(Word::Keyword(Keyword::Delete));
238    const DIV: Self = Token::BinOp(BinOpToken::Div);
239    const DIV_EQ: Self = Token::AssignOp(AssignOp::DivAssign);
240    const DO: Self = Token::Word(Word::Keyword(Keyword::Do));
241    const DOLLAR_LBRACE: Self = Self::DollarLBrace;
242    const DOT: Self = Self::Dot;
243    const DOTDOTDOT: Self = Self::DotDotDot;
244    const ELSE: Self = Token::Word(Word::Keyword(Keyword::Else));
245    const ENUM: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Enum)));
246    const EOF: Self = Token::Eof;
247    const EQUAL: Self = Token::AssignOp(AssignOp::Assign);
248    const EXP: Self = Token::BinOp(BinOpToken::Exp);
249    const EXPORT: Self = Token::Word(Word::Keyword(Keyword::Export));
250    const EXP_EQ: Self = Token::AssignOp(AssignOp::ExpAssign);
251    const EXTENDS: Self = Self::Word(Word::Keyword(Keyword::Extends));
252    const FALSE: Self = Token::Word(Word::False);
253    const FINALLY: Self = Self::Word(Word::Keyword(Keyword::Finally));
254    const FOR: Self = Token::Word(Word::Keyword(Keyword::For));
255    const FROM: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::From)));
256    const FUNCTION: Self = Token::Word(Word::Keyword(Keyword::Function));
257    const GET: Self = Self::Word(Word::Ident(IdentLike::Known(KnownIdent::Get)));
258    const GLOBAL: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Global)));
259    const GREATER: Self = Token::BinOp(BinOpToken::Gt);
260    const GREATER_EQ: Self = Token::BinOp(BinOpToken::GtEq);
261    const HASH: Self = Self::Hash;
262    const IF: Self = Token::Word(Word::Keyword(Keyword::If));
263    const IMPLEMENTS: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Implements)));
264    const IMPORT: Self = Token::Word(Word::Keyword(Keyword::Import));
265    const IN: Self = Token::Word(Word::Keyword(Keyword::In));
266    const INFER: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Infer)));
267    const INSTANCEOF: Self = Token::Word(Word::Keyword(Keyword::InstanceOf));
268    const INTERFACE: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Interface)));
269    const INTRINSIC: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Intrinsic)));
270    const IS: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Is)));
271    const JSX_TAG_END: Self = Self::JSXTagEnd;
272    const JSX_TAG_START: Self = Self::JSXTagStart;
273    const KEYOF: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Keyof)));
274    const LBRACE: Self = Self::LBrace;
275    const LBRACKET: Self = Self::LBracket;
276    const LESS: Self = Token::BinOp(BinOpToken::Lt);
277    const LESS_EQ: Self = Token::BinOp(BinOpToken::LtEq);
278    const LET: Self = Token::Word(Word::Keyword(Keyword::Let));
279    const LOGICAL_AND: Self = tok!("&&");
280    const LOGICAL_AND_EQ: Self = Token::AssignOp(AssignOp::AndAssign);
281    const LOGICAL_OR: Self = tok!("||");
282    const LOGICAL_OR_EQ: Self = Token::AssignOp(AssignOp::OrAssign);
283    const LPAREN: Self = Self::LParen;
284    const LSHIFT: Self = Token::BinOp(BinOpToken::LShift);
285    const LSHIFT_EQ: Self = Token::AssignOp(AssignOp::LShiftAssign);
286    const MINUS: Self = Token::BinOp(BinOpToken::Sub);
287    const MINUS_MINUS: Self = Self::MinusMinus;
288    const MOD: Self = Token::BinOp(BinOpToken::Mod);
289    const MOD_EQ: Self = Token::AssignOp(AssignOp::ModAssign);
290    const MUL: Self = Token::BinOp(BinOpToken::Mul);
291    const MUL_EQ: Self = Token::AssignOp(AssignOp::MulAssign);
292    const NAMESPACE: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Namespace)));
293    const NEVER: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Never)));
294    const NEW: Self = Token::Word(Word::Keyword(Keyword::New));
295    const NULL: Self = Token::Word(Word::Null);
296    const NULLISH_ASSIGN: Self = tok!("??=");
297    const NULLISH_COALESCING: Self = tok!("??");
298    const NUMBER: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Number)));
299    const OBJECT: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Object)));
300    const OF: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Of)));
301    const PACKAGE: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Package)));
302    const PLUS: Self = Token::BinOp(BinOpToken::Add);
303    const PLUS_PLUS: Self = Self::PlusPlus;
304    const PRIVATE: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Private)));
305    const PROTECTED: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Protected)));
306    const PUBLIC: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Public)));
307    const QUESTION: Self = Token::QuestionMark;
308    const RBRACE: Self = Self::RBrace;
309    const RBRACKET: Self = Self::RBracket;
310    const READONLY: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Readonly)));
311    const REQUIRE: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Require)));
312    const RETURN: Self = Token::Word(Word::Keyword(Keyword::Return));
313    const RPAREN: Self = Self::RParen;
314    const RSHIFT: Self = Token::BinOp(BinOpToken::RShift);
315    const RSHIFT_EQ: Self = Token::AssignOp(AssignOp::RShiftAssign);
316    const SATISFIES: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Satisfies)));
317    const SEMI: Self = Self::Semi;
318    const SET: Self = Self::Word(Word::Ident(IdentLike::Known(KnownIdent::Set)));
319    const STATIC: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Static)));
320    const STRING: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::String)));
321    const SUPER: Self = Token::Word(Word::Keyword(Keyword::Super));
322    const SWITCH: Self = Self::Word(Word::Keyword(Keyword::Switch));
323    const SYMBOL: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Symbol)));
324    const TARGET: Self = Self::Word(Word::Ident(IdentLike::Known(KnownIdent::Target)));
325    const THIS: Self = Token::Word(Word::Keyword(Keyword::This));
326    const THROW: Self = Token::Word(Word::Keyword(Keyword::Throw));
327    const TILDE: Self = Self::Tilde;
328    const TRUE: Self = Token::Word(Word::True);
329    const TRY: Self = Self::Word(Word::Keyword(Keyword::Try));
330    const TYPE: Self = Self::Word(Word::Ident(IdentLike::Known(KnownIdent::Type)));
331    const TYPEOF: Self = Token::Word(Word::Keyword(Keyword::TypeOf));
332    const UNDEFINED: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Undefined)));
333    const UNIQUE: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Unique)));
334    const UNKNOWN: Self = Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Unknown)));
335    const USING: Self = Self::Word(Word::Ident(IdentLike::Known(KnownIdent::Using)));
336    const VAR: Self = Self::Word(Word::Keyword(Keyword::Var));
337    const VOID: Self = Token::Word(Word::Keyword(Keyword::Void));
338    const WHILE: Self = Token::Word(Word::Keyword(Keyword::While));
339    const WITH: Self = Token::Word(Word::Keyword(Keyword::With));
340    const YIELD: Self = Token::Word(Word::Keyword(Keyword::Yield));
341    const ZERO_FILL_RSHIFT: Self = Token::BinOp(BinOpToken::ZeroFillRShift);
342    const ZERO_FILL_RSHIFT_EQ: Self = Token::AssignOp(AssignOp::ZeroFillRShiftAssign);
343
344    #[inline(always)]
345    fn jsx_name(name: &'a str, lexer: &mut crate::Lexer<'a>) -> Self {
346        let name = lexer.atom(name);
347        Self::JSXName { name }
348    }
349
350    #[inline(always)]
351    fn is_jsx_name(&self) -> bool {
352        matches!(self, Self::JSXName { .. })
353    }
354
355    #[inline(always)]
356    fn take_jsx_name(self, _: &mut Self::Buffer) -> Atom {
357        match self {
358            JSXName { name } => name,
359            _ => unreachable!(),
360        }
361    }
362
363    #[inline(always)]
364    fn str(value: Wtf8Atom, raw: Atom, _: &mut crate::Lexer<'a>) -> Self {
365        Self::Str { value, raw }
366    }
367
368    #[inline(always)]
369    fn template(cooked: LexResult<Wtf8Atom>, raw: Atom, _: &mut crate::Lexer<'a>) -> Self {
370        Self::Template { cooked, raw }
371    }
372
373    #[inline(always)]
374    fn regexp(content: Atom, flags: Atom, _: &mut crate::Lexer<'a>) -> Self {
375        Self::Regex(content, flags)
376    }
377
378    #[inline(always)]
379    fn num(value: f64, raw: Atom, _: &mut crate::Lexer<'a>) -> Self {
380        Self::Num { value, raw }
381    }
382
383    #[inline(always)]
384    fn bigint(value: Box<BigIntValue>, raw: Atom, _: &mut crate::Lexer<'a>) -> Self {
385        Self::BigInt { value, raw }
386    }
387
388    #[inline(always)]
389    fn unknown_ident(value: Atom, _: &mut crate::Lexer<'a>) -> Self {
390        Token::Word(Word::Ident(IdentLike::Other(value)))
391    }
392
393    #[inline(always)]
394    fn is_word(&self) -> bool {
395        matches!(self, Self::Word(_))
396    }
397
398    #[inline(always)]
399    fn is_reserved(&self, ctx: crate::common::context::Context) -> bool {
400        if let Token::Word(word) = self {
401            ctx.is_reserved(word)
402        } else {
403            unreachable!()
404        }
405    }
406
407    #[inline(always)]
408    fn into_atom(self, _: &mut crate::Lexer<'a>) -> Option<Atom> {
409        match self {
410            Token::Word(word) => Some(word.into()),
411            _ => None,
412        }
413    }
414
415    #[inline(always)]
416    fn is_error(&self) -> bool {
417        matches!(self, Self::Error(_))
418    }
419
420    #[inline(always)]
421    fn take_error(self, _: &mut Self::Buffer) -> crate::error::Error {
422        match self {
423            Self::Error(e) => e,
424            _ => unreachable!(),
425        }
426    }
427
428    #[inline(always)]
429    fn is_str(&self) -> bool {
430        matches!(self, Self::Str { .. })
431    }
432
433    #[inline(always)]
434    fn is_str_raw_content(&self, content: &str, _: &Self::Buffer) -> bool {
435        if let Self::Str { raw, .. } = self {
436            raw == content
437        } else {
438            false
439        }
440    }
441
442    #[inline(always)]
443    fn take_str(self, _: &mut Self::Buffer) -> (Wtf8Atom, Atom) {
444        match self {
445            Self::Str { value, raw } => (value, raw),
446            _ => unreachable!(),
447        }
448    }
449
450    #[inline(always)]
451    fn is_num(&self) -> bool {
452        matches!(self, Self::Num { .. })
453    }
454
455    #[inline(always)]
456    fn take_num(self, _: &mut Self::Buffer) -> (f64, Atom) {
457        match self {
458            Self::Num { value, raw } => (value, raw),
459            _ => unreachable!(),
460        }
461    }
462
463    #[inline(always)]
464    fn is_bigint(&self) -> bool {
465        matches!(self, Self::BigInt { .. })
466    }
467
468    #[inline(always)]
469    fn take_bigint(self, _: &mut Self::Buffer) -> (Box<BigIntValue>, Atom) {
470        match self {
471            Self::BigInt { value, raw } => (value, raw),
472            _ => unreachable!(),
473        }
474    }
475
476    #[inline(always)]
477    fn take_word(self, _: &Self::Buffer) -> Option<Atom> {
478        match self {
479            Self::Word(word) => Some(word.into()),
480            _ => unreachable!(),
481        }
482    }
483
484    #[inline(always)]
485    fn is_unknown_ident(&self) -> bool {
486        matches!(self, Self::Word(Word::Ident(IdentLike::Other(_))))
487    }
488
489    #[inline(always)]
490    fn take_unknown_ident(self, _: &mut Self::Buffer) -> Atom {
491        match self {
492            Self::Word(Word::Ident(IdentLike::Other(ident))) => ident,
493            _ => unreachable!(),
494        }
495    }
496
497    #[inline(always)]
498    fn take_unknown_ident_ref<'b>(&'b self, _: &'b Self::Buffer) -> &'b Atom {
499        match self {
500            Self::Word(Word::Ident(IdentLike::Other(ref ident))) => ident,
501            _ => unreachable!(),
502        }
503    }
504
505    #[inline(always)]
506    fn is_keyword(&self) -> bool {
507        matches!(self, Self::Word(Word::Keyword(_)))
508    }
509
510    #[inline(always)]
511    fn is_known_ident(&self) -> bool {
512        matches!(self, Self::Word(Word::Ident(IdentLike::Known(_))))
513    }
514
515    #[inline(always)]
516    fn take_known_ident(&self) -> Atom {
517        match self {
518            Self::Word(Word::Ident(IdentLike::Known(kwd))) => (*kwd).into(),
519            _ => unreachable!(),
520        }
521    }
522
523    #[inline(always)]
524    fn is_regexp(&self) -> bool {
525        matches!(self, Self::Regex(..))
526    }
527
528    #[inline(always)]
529    fn is_template(&self) -> bool {
530        matches!(self, Self::Template { .. })
531    }
532
533    #[inline(always)]
534    fn take_template(self, _: &mut Self::Buffer) -> (LexResult<Wtf8Atom>, Atom) {
535        match self {
536            Self::Template { cooked, raw } => (cooked, raw),
537            _ => unreachable!(),
538        }
539    }
540
541    #[inline(always)]
542    fn jsx_text(value: Atom, raw: Atom, _: &mut Self::Lexer) -> Self {
543        Self::JSXText { value, raw }
544    }
545
546    #[inline(always)]
547    fn is_jsx_text(&self) -> bool {
548        matches!(self, Self::JSXText { .. })
549    }
550
551    #[inline(always)]
552    fn take_jsx_text(self, _: &mut Self::Buffer) -> (Atom, Atom) {
553        match self {
554            Self::JSXText { value, raw } => (value, raw),
555            _ => unreachable!(),
556        }
557    }
558
559    #[inline(always)]
560    fn starts_expr(&self) -> bool {
561        self.kind().starts_expr()
562    }
563
564    #[inline(always)]
565    fn to_string(&self, _: &Self::Buffer) -> String {
566        format!("{self:?}")
567    }
568
569    #[inline(always)]
570    fn is_bin_op(&self) -> bool {
571        matches!(self, Self::BinOp(_))
572    }
573
574    #[inline(always)]
575    fn as_assign_op(&self) -> Option<AssignOp> {
576        match self {
577            Self::AssignOp(op) => Some(*op),
578            _ => None,
579        }
580    }
581
582    #[inline(always)]
583    fn as_bin_op(&self) -> Option<BinaryOp> {
584        match self {
585            Self::BinOp(op) => Some((*op).into()),
586            _ => None,
587        }
588    }
589
590    #[inline(always)]
591    fn follows_keyword_let(&self) -> bool {
592        self.kind().follows_keyword_let(false)
593    }
594
595    #[inline(always)]
596    fn is_assign_op(&self) -> bool {
597        matches!(self, Self::AssignOp(_))
598    }
599
600    #[inline(always)]
601    fn take_regexp(self, _: &mut Self::Buffer) -> (Atom, Atom) {
602        match self {
603            Self::Regex(content, flags) => (content, flags),
604            _ => unreachable!(),
605        }
606    }
607
608    #[inline(always)]
609    fn shebang(value: Atom, _: &mut Self::Lexer) -> Self {
610        Self::Shebang(value)
611    }
612
613    #[inline(always)]
614    fn is_shebang(&self) -> bool {
615        matches!(self, Self::Shebang(..))
616    }
617
618    #[inline(always)]
619    fn take_shebang(self, _: &mut Self::Buffer) -> Atom {
620        match self {
621            Self::Shebang(value) => value,
622            _ => unreachable!(),
623        }
624    }
625
626    #[inline(always)]
627    fn is_no_substitution_template_literal(&self) -> bool {
628        false
629    }
630
631    #[inline(always)]
632    fn is_template_head(&self) -> bool {
633        false
634    }
635}
636
637impl crate::common::parser::token_and_span::TokenAndSpan for TokenAndSpan {
638    type Token = Token;
639
640    #[inline(always)]
641    fn new(token: Token, span: Span, had_line_break: bool) -> Self {
642        Self {
643            token,
644            had_line_break,
645            span,
646        }
647    }
648
649    #[inline(always)]
650    fn token(&self) -> &Token {
651        &self.token
652    }
653
654    #[inline(always)]
655    fn take_token(self) -> Token {
656        self.token
657    }
658
659    #[inline(always)]
660    fn had_line_break(&self) -> bool {
661        self.had_line_break
662    }
663
664    #[inline(always)]
665    fn span(&self) -> Span {
666        self.span
667    }
668}
669
670impl crate::common::parser::buffer::NextTokenAndSpan for TokenAndSpan {
671    type Token = Token;
672
673    #[inline(always)]
674    fn token(&self) -> &Self::Token {
675        &self.token
676    }
677
678    #[inline(always)]
679    fn span(&self) -> Span {
680        self.span
681    }
682
683    #[inline(always)]
684    fn had_line_break(&self) -> bool {
685        self.had_line_break
686    }
687}