boa_ast/keyword/mod.rs
1//! The `Keyword` AST node, which represents reserved words of the ECMAScript language.
2//!
3//! The [specification][spec] defines keywords as tokens that match an `IdentifierName`, but also
4//! have special meaning in ECMAScript. In ECMAScript, you cannot use these reserved words as variables,
5//! labels, or function names.
6//!
7//! The [MDN documentation][mdn] contains a more extensive explanation about keywords.
8//!
9//! [spec]: https://tc39.es/ecma262/#sec-keywords-and-reserved-words
10//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords
11
12use crate::expression::operator::binary::{BinaryOp, RelationalOp};
13use boa_interner::Sym;
14use boa_macros::utf16;
15use std::{convert::TryFrom, error, fmt, str::FromStr};
16
17#[cfg(test)]
18mod tests;
19
20/// List of keywords recognized by the JavaScript grammar.
21///
22/// See the [module-level documentation][self] for more details.
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24#[derive(Clone, Copy, PartialEq, Eq, Debug)]
25pub enum Keyword {
26 /// The `await` keyword.
27 ///
28 /// More information:
29 /// - [ECMAScript reference][spec]
30 /// - [MDN documentation][mdn]
31 ///
32 /// [spec]: https://tc39.es/ecma262/#prod-AwaitExpression
33 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
34 Await,
35
36 /// The `async` keyword.
37 ///
38 /// More information:
39 /// - [ECMAScript reference][spec]
40 /// - [MDN documentation][mdn]
41 ///
42 /// [spec]: https://tc39.es/ecma262/#prod-AsyncMethod
43 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
44 Async,
45
46 /// The `break` keyword.
47 ///
48 /// More information:
49 /// - [break `Node` documentation][node]
50 /// - [ECMAScript reference][spec]
51 /// - [MDN documentation][mdn]
52 ///
53 /// [spec]: https://tc39.es/ecma262/#prod-BreakStatement
54 /// [node]: ../node/enum.Node.html#variant.Break
55 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break
56 Break,
57
58 /// The `case` keyword.
59 ///
60 /// More information:
61 /// - [switch `Node` documentation][node]
62 /// - [ECMAScript reference][spec]
63 /// - [MDN documentation][mdn]
64 ///
65 /// [spec]: https://tc39.es/ecma262/#prod-CaseClause
66 /// [node]: ../node/enum.Node.html#variant.Switch
67 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
68 Case,
69
70 /// The `catch` keyword.
71 ///
72 /// More information:
73 /// - [try `Node` documentation][node]
74 /// - [ECMAScript reference][spec]
75 /// - [MDN documentation][mdn]
76 ///
77 /// [spec]: https://tc39.es/ecma262/#prod-Catch
78 /// [node]: ../node/enum.Node.html#variant.Try
79 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
80 Catch,
81
82 /// The `class` keyword.
83 ///
84 /// More information:
85 /// - [ECMAScript reference][spec]
86 /// - [MDN documentation][mdn]
87 ///
88 /// [spec]: https://tc39.es/ecma262/#prod-ClassDeclaration
89 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class
90 Class,
91
92 /// The `continue` keyword.
93 ///
94 /// More information:
95 /// - [continue `Node` documentation][node]
96 /// - [ECMAScript reference][spec]
97 /// - [MDN documentation][mdn]
98 ///
99 /// [spec]: https://tc39.es/ecma262/#prod-ContinueStatement
100 /// [node]: ../node/enum.Node.html#variant.Continue
101 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue
102 Continue,
103
104 /// The `const` keyword.
105 ///
106 /// More information:
107 /// - [const `Node` documentation][node]
108 /// - [ECMAScript reference][spec]
109 /// - [MDN documentation][mdn]
110 ///
111 /// [spec]: https://tc39.es/ecma262/#sec-let-and-const-declarations
112 /// [node]: ../node/enum.Node.html#variant.ConstDecl
113 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
114 Const,
115
116 /// The `debugger` keyword.
117 ///
118 /// More information:
119 /// - [ECMAScript reference][spec]
120 /// - [MDN documentation][mdn]
121 ///
122 /// [spec]: https://tc39.es/ecma262/#sec-debugger-statement
123 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger
124 Debugger,
125
126 /// The `default` keyword.
127 ///
128 /// More information:
129 /// - [switch `Node` documentation][node]
130 /// - [ECMAScript reference default clause][spec-clause]
131 /// - [ECMAScript reference default export][spec-export]
132 /// - [MDN documentation][mdn]
133 ///
134 /// [node]: ../node/enum.Node.html#variant.Switch
135 /// [spec-clause]: https://tc39.es/ecma262/#prod-DefaultClause
136 /// [spec-export]: https://tc39.es/ecma262/#prod-ImportedDefaultBinding
137 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/default
138 Default,
139
140 /// The `delete` keyword.
141 ///
142 /// More information:
143 /// - [delete `UnaryOp` documentation][unary]
144 /// - [ECMAScript reference][spec]
145 /// - [MDN documentation][mdn]
146 ///
147 /// [spec]: https://tc39.es/ecma262/#sec-delete-operator
148 /// [unary]: ../op/enum.UnaryOp.html#variant.Delete
149 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
150 Delete,
151
152 /// The `do` keyword.
153 ///
154 /// More information:
155 /// - [ECMAScript reference][spec]
156 /// - [MDN documentation][mdn]
157 ///
158 /// [spec]: https://tc39.es/ecma262/#sec-do-while-statement
159 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while
160 Do,
161
162 /// The `else` keyword.
163 ///
164 /// More information:
165 /// - [if `Node` documentation][node]
166 /// - [ECMAScript reference][spec]
167 /// - [MDN documentation][mdn]
168 ///
169 /// [node]: ../node/enum.Node.html#variant.If
170 /// [spec]: https://tc39.es/ecma262/#prod-IfStatement
171 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else
172 Else,
173
174 /// The `enum` keyword.
175 ///
176 /// Future reserved keyword.
177 Enum,
178
179 /// The `export` keyword.
180 ///
181 /// More information:
182 /// - [ECMAScript reference][spec]
183 /// - [MDN documentation][mdn]
184 ///
185 /// [spec]: https://tc39.es/ecma262/#sec-exports
186 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
187 Export,
188
189 /// The `extends` keyword.
190 ///
191 /// More information:
192 /// - [ECMAScript reference][spec]
193 /// - [MDN documentation][mdn]
194 ///
195 /// [spec]: https://tc39.es/ecma262/#prod-ClassHeritage
196 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends
197 Extends,
198
199 /// The `finally` keyword.
200 ///
201 /// More information:
202 /// - [try `Node` documentation][node]
203 /// - [ECMAScript reference][spec]
204 /// - [MDN documentation][mdn]
205 ///
206 /// [node]: ../node/enum.Node.html#variant.Try
207 /// [spec]: https://tc39.es/ecma262/#prod-Finally
208 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
209 Finally,
210
211 /// The `for` keyword.
212 ///
213 /// More information:
214 /// - [for loop `Node` documentation][node]
215 /// - [ECMAScript reference][spec]
216 /// - [MDN documentation][mdn]
217 ///
218 /// [node]: ../node/enum.Node.html#variant.ForLoop
219 /// [spec]: https://tc39.es/ecma262/#prod-ForDeclaration
220 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for
221 For,
222
223 /// The `function` keyword.
224 ///
225 /// More information:
226 /// - [function `Node` documentation][node]
227 /// - [ECMAScript reference][spec]
228 /// - [MDN documentation][mdn]
229 ///
230 /// [node]: ../node/enum.Node.html#variant.FunctionDecl
231 /// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-function
232 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function
233 Function,
234
235 /// The `if` keyword.
236 ///
237 /// More information:
238 /// - [if `Node` documentation][node]
239 /// - [ECMAScript reference][spec]
240 /// - [MDN documentation][mdn]
241 ///
242 /// [node]: ../node/enum.Node.html#variant.If
243 /// [spec]: https://tc39.es/ecma262/#prod-IfStatement
244 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else
245 If,
246
247 /// The `in` keyword.
248 ///
249 /// More information:
250 /// - [ECMAScript reference][spec]
251 /// - [MDN documentation][mdn]
252 ///
253 /// [spec]: https://tc39.es/ecma262/#prod-RelationalExpression
254 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in
255 In,
256
257 /// The `instanceof` keyword.
258 ///
259 /// More information:
260 /// - [ECMAScript reference][spec]
261 /// - [MDN documentation][mdn]
262 ///
263 /// [spec]: https://tc39.es/ecma262/#sec-instanceofoperator
264 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
265 InstanceOf,
266
267 /// The `import` keyword.
268 ///
269 /// More information:
270 /// - [ECMAScript reference][spec]
271 /// - [MDN documentation][mdn]
272 ///
273 /// [spec]: https://tc39.es/ecma262/#sec-imports
274 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
275 Import,
276
277 /// The `let` keyword.
278 ///
279 /// More information:
280 /// - [let `Node` documentation][node]
281 /// - [ECMAScript reference][spec]
282 /// - [MDN documentation][mdn]
283 ///
284 /// [node]: ../node/enum.Node.html#variant.LetDecl
285 /// [spec]: https://tc39.es/ecma262/#sec-let-and-const-declarations
286 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
287 Let,
288
289 /// The `new` keyword.
290 ///
291 /// More information:
292 /// - [new `Node` documentation][node]
293 /// - [ECMAScript reference][spec]
294 /// - [MDN documentation][mdn]
295 ///
296 /// [node]: ../node/enum.Node.html#variant.New
297 /// [spec]: https://tc39.es/ecma262/#prod-NewExpression
298 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
299 New,
300
301 /// The `of` keyword.
302 ///
303 /// More information:
304 /// - [ECMAScript reference][spec]
305 /// - [MDN documentation][mdn]
306 ///
307 /// [spec]: https://tc39.es/ecma262/#sec-for-in-and-for-of-statements
308 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
309 Of,
310
311 /// The `return` keyword
312 ///
313 /// More information:
314 /// - [return `Node` documentation][node]
315 /// - [ECMAScript reference][spec]
316 /// - [MDN documentation][mdn]
317 ///
318 /// [node]: ../node/enum.Node.html#variant.Return
319 /// [spec]: https://tc39.es/ecma262/#prod-ReturnStatement
320 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return
321 Return,
322
323 /// The `super` keyword
324 ///
325 /// More information:
326 /// - [ECMAScript reference][spec]
327 /// - [MDN documentation][mdn]
328 ///
329 /// [spec]: https://tc39.es/ecma262/#sec-super-keyword
330 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
331 Super,
332
333 /// The `switch` keyword.
334 ///
335 /// More information:
336 /// - [switch `Node` documentation][node]
337 /// - [ECMAScript reference][spec]
338 /// - [MDN documentation][mdn]
339 ///
340 /// [node]: ../node/enum.Node.html#variant.Switch
341 /// [spec]: https://tc39.es/ecma262/#prod-SwitchStatement
342 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
343 Switch,
344
345 /// The `this` keyword.
346 ///
347 /// More information:
348 /// - [this `Node` documentation][node]
349 /// - [ECMAScript reference][spec]
350 /// - [MDN documentation][mdn]
351 ///
352 /// [node]: ../node/enum.Node.html#variant.This
353 /// [spec]: https://tc39.es/ecma262/#sec-this-keyword
354 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
355 This,
356
357 /// The `throw` keyword.
358 ///
359 /// More information:
360 /// - [throw `Node` documentation][node]
361 /// - [ECMAScript reference][spec]
362 /// - [MDN documentation][mdn]
363 ///
364 /// [node]: ../node/enum.Node.html#variant.Throw
365 /// [spec]: https://tc39.es/ecma262/#sec-throw-statement
366 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
367 Throw,
368
369 /// The `try` keyword.
370 ///
371 /// More information:
372 /// - [try `Node` documentation][node]
373 /// - [ECMAScript reference][spec]
374 /// - [MDN documentation][mdn]
375 ///
376 /// [node]: ../node/enum.Node.html#variant.Try
377 /// [spec]: https://tc39.es/ecma262/#prod-TryStatement
378 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
379 Try,
380
381 /// The `typeof` keyword.
382 ///
383 /// More information:
384 /// - [typeof `UnaryOp` documentation][unary]
385 /// - [ECMAScript reference][spec]
386 /// - [MDN documentation][mdn]
387 ///
388 /// [unary]: ../op/enum.UnaryOp.html#variant.TypeOf
389 /// [spec]: https://tc39.es/ecma262/#sec-typeof-operator
390 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
391 TypeOf,
392
393 /// The `var` keyword.
394 ///
395 /// More information:
396 /// - [var `Node` documentation][node]
397 /// - [ECMAScript reference][spec]
398 /// - [MDN documentation][mdn]
399 ///
400 /// [node]: ../node/enum.Node.html#variant.VarDecl
401 /// [spec]: https://tc39.es/ecma262/#prod-VariableStatement
402 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
403 Var,
404
405 /// The `void` keyword.
406 ///
407 /// More information:
408 /// - [void `UnaryOp` documentation][unary]
409 /// - [ECMAScript reference][spec]
410 /// - [MDN documentation][mdn]
411 ///
412 /// [unary]: ../op/enum.UnaryOp.html#variant.Void
413 /// [spec]: https://tc39.es/ecma262/#sec-void-operator
414 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
415 Void,
416
417 /// The `while` keyword.
418 ///
419 /// More information:
420 /// - [while `Node` documentation][node]
421 /// - [ECMAScript reference][spec]
422 /// - [MDN documentation][mdn]
423 ///
424 /// [node]: ../node/enum.Node.html#variant.While
425 /// [spec]: https://tc39.es/ecma262/#prod-grammar-notation-WhileStatement
426 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while
427 While,
428
429 /// The `with` keyword.
430 ///
431 /// More information:
432 /// - [ECMAScript reference][spec]
433 /// - [MDN documentation][mdn]
434 ///
435 /// [spec]: https://tc39.es/ecma262/#prod-WithStatement
436 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with
437 With,
438
439 /// The 'yield' keyword.
440 ///
441 /// More information:
442 /// - [ECMAScript reference][spec]
443 /// - [MDN documentation][mdn]
444 ///
445 /// [spec]: https://tc39.es/ecma262/#prod-YieldExpression
446 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
447 Yield,
448
449 /// The `using` keyword.
450 ///
451 /// More information:
452 /// - [ECMAScript reference][spec]
453 /// - [MDN documentation][mdn]
454 ///
455 /// [spec]: https://tc39.es/proposal-explicit-resource-management/
456 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/using
457 Using,
458}
459
460impl Keyword {
461 /// Gets the keyword as a binary operation, if this keyword is the `in` or the `instanceof`
462 /// keywords.
463 #[must_use]
464 pub const fn as_binary_op(self) -> Option<BinaryOp> {
465 match self {
466 Self::In => Some(BinaryOp::Relational(RelationalOp::In)),
467 Self::InstanceOf => Some(BinaryOp::Relational(RelationalOp::InstanceOf)),
468 _ => None,
469 }
470 }
471
472 /// Gets the keyword as a tuple of strings.
473 #[must_use]
474 pub const fn as_str(self) -> (&'static str, &'static [u16]) {
475 match self {
476 Self::Await => ("await", utf16!("await")),
477 Self::Async => ("async", utf16!("async")),
478 Self::Break => ("break", utf16!("break")),
479 Self::Case => ("case", utf16!("case")),
480 Self::Catch => ("catch", utf16!("catch")),
481 Self::Class => ("class", utf16!("class")),
482 Self::Continue => ("continue", utf16!("continue")),
483 Self::Const => ("const", utf16!("const")),
484 Self::Debugger => ("debugger", utf16!("debugger")),
485 Self::Default => ("default", utf16!("default")),
486 Self::Delete => ("delete", utf16!("delete")),
487 Self::Do => ("do", utf16!("do")),
488 Self::Else => ("else", utf16!("else")),
489 Self::Enum => ("enum", utf16!("enum")),
490 Self::Extends => ("extends", utf16!("extends")),
491 Self::Export => ("export", utf16!("export")),
492 Self::Finally => ("finally", utf16!("finally")),
493 Self::For => ("for", utf16!("for")),
494 Self::Function => ("function", utf16!("function")),
495 Self::If => ("if", utf16!("if")),
496 Self::In => ("in", utf16!("in")),
497 Self::InstanceOf => ("instanceof", utf16!("instanceof")),
498 Self::Import => ("import", utf16!("import")),
499 Self::Let => ("let", utf16!("let")),
500 Self::New => ("new", utf16!("new")),
501 Self::Of => ("of", utf16!("of")),
502 Self::Return => ("return", utf16!("return")),
503 Self::Super => ("super", utf16!("super")),
504 Self::Switch => ("switch", utf16!("switch")),
505 Self::This => ("this", utf16!("this")),
506 Self::Throw => ("throw", utf16!("throw")),
507 Self::Try => ("try", utf16!("try")),
508 Self::TypeOf => ("typeof", utf16!("typeof")),
509 Self::Var => ("var", utf16!("var")),
510 Self::Void => ("void", utf16!("void")),
511 Self::While => ("while", utf16!("while")),
512 Self::With => ("with", utf16!("with")),
513 Self::Yield => ("yield", utf16!("yield")),
514 Self::Using => ("using", utf16!("using")),
515 }
516 }
517
518 /// Converts the keyword to a symbol in the given interner.
519 #[must_use]
520 pub const fn to_sym(self) -> Sym {
521 match self {
522 Self::Await => Sym::AWAIT,
523 Self::Async => Sym::ASYNC,
524 Self::Break => Sym::BREAK,
525 Self::Case => Sym::CASE,
526 Self::Catch => Sym::CATCH,
527 Self::Class => Sym::CLASS,
528 Self::Continue => Sym::CONTINUE,
529 Self::Const => Sym::CONST,
530 Self::Debugger => Sym::DEBUGGER,
531 Self::Default => Sym::DEFAULT,
532 Self::Delete => Sym::DELETE,
533 Self::Do => Sym::DO,
534 Self::Else => Sym::ELSE,
535 Self::Enum => Sym::ENUM,
536 Self::Export => Sym::EXPORT,
537 Self::Extends => Sym::EXTENDS,
538 Self::Finally => Sym::FINALLY,
539 Self::For => Sym::FOR,
540 Self::Function => Sym::FUNCTION,
541 Self::If => Sym::IF,
542 Self::In => Sym::IN,
543 Self::InstanceOf => Sym::INSTANCEOF,
544 Self::Import => Sym::IMPORT,
545 Self::Let => Sym::LET,
546 Self::New => Sym::NEW,
547 Self::Of => Sym::OF,
548 Self::Return => Sym::RETURN,
549 Self::Super => Sym::SUPER,
550 Self::Switch => Sym::SWITCH,
551 Self::This => Sym::THIS,
552 Self::Throw => Sym::THROW,
553 Self::Try => Sym::TRY,
554 Self::TypeOf => Sym::TYPEOF,
555 Self::Var => Sym::VAR,
556 Self::Void => Sym::VOID,
557 Self::While => Sym::WHILE,
558 Self::With => Sym::WITH,
559 Self::Yield => Sym::YIELD,
560 Self::Using => Sym::USING,
561 }
562 }
563}
564
565impl TryFrom<Keyword> for BinaryOp {
566 type Error = KeywordToBinaryOpError;
567
568 fn try_from(value: Keyword) -> Result<Self, Self::Error> {
569 value.as_binary_op().ok_or(KeywordToBinaryOpError)
570 }
571}
572
573/// Error returned when a [`Keyword`] cannot be converted into a [`BinaryOp`].
574#[derive(Debug, Clone, Copy)]
575pub struct KeywordToBinaryOpError;
576
577impl fmt::Display for KeywordToBinaryOpError {
578 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
579 write!(f, "keyword is not a binary operator")
580 }
581}
582
583impl error::Error for KeywordToBinaryOpError {}
584
585/// The error type which is returned from parsing a [`str`] into a [`Keyword`].
586#[derive(Debug, Clone, Copy)]
587pub struct KeywordError;
588impl fmt::Display for KeywordError {
589 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
590 write!(f, "invalid token")
591 }
592}
593
594// This is important for other errors to wrap this one.
595impl error::Error for KeywordError {}
596
597impl FromStr for Keyword {
598 type Err = KeywordError;
599 fn from_str(s: &str) -> Result<Self, Self::Err> {
600 match s {
601 "await" => Ok(Self::Await),
602 "async" => Ok(Self::Async),
603 "break" => Ok(Self::Break),
604 "case" => Ok(Self::Case),
605 "catch" => Ok(Self::Catch),
606 "class" => Ok(Self::Class),
607 "continue" => Ok(Self::Continue),
608 "const" => Ok(Self::Const),
609 "debugger" => Ok(Self::Debugger),
610 "default" => Ok(Self::Default),
611 "delete" => Ok(Self::Delete),
612 "do" => Ok(Self::Do),
613 "else" => Ok(Self::Else),
614 "enum" => Ok(Self::Enum),
615 "extends" => Ok(Self::Extends),
616 "export" => Ok(Self::Export),
617 "finally" => Ok(Self::Finally),
618 "for" => Ok(Self::For),
619 "function" => Ok(Self::Function),
620 "if" => Ok(Self::If),
621 "in" => Ok(Self::In),
622 "instanceof" => Ok(Self::InstanceOf),
623 "import" => Ok(Self::Import),
624 "let" => Ok(Self::Let),
625 "new" => Ok(Self::New),
626 "of" => Ok(Self::Of),
627 "return" => Ok(Self::Return),
628 "super" => Ok(Self::Super),
629 "switch" => Ok(Self::Switch),
630 "this" => Ok(Self::This),
631 "throw" => Ok(Self::Throw),
632 "try" => Ok(Self::Try),
633 "typeof" => Ok(Self::TypeOf),
634 "var" => Ok(Self::Var),
635 "void" => Ok(Self::Void),
636 "while" => Ok(Self::While),
637 "with" => Ok(Self::With),
638 "yield" => Ok(Self::Yield),
639 "using" => Ok(Self::Using),
640 _ => Err(KeywordError),
641 }
642 }
643}
644
645impl fmt::Display for Keyword {
646 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
647 fmt::Display::fmt(self.as_str().0, f)
648 }
649}