1use 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}