swc_ecma_parser/
context.rs

1use swc_atoms::Atom;
2
3bitflags::bitflags! {
4  #[derive(Debug, Clone, Copy, Default)]
5  pub struct Context: u32 {
6
7      /// `true` while backtracking
8      const IgnoreError = 1 << 0;
9
10      /// Is in module code?
11      const Module = 1 << 1;
12      const CanBeModule = 1 << 2;
13      const Strict = 1 << 3;
14
15      const ForLoopInit = 1 << 4;
16      const ForAwaitLoopInit = 1 << 5;
17
18      const IncludeInExpr = 1 << 6;
19      /// If true, await expression is parsed, and "await" is treated as a
20      /// keyword.
21      const InAsync = 1 << 7;
22      /// If true, yield expression is parsed, and "yield" is treated as a
23      /// keyword.
24      const InGenerator = 1 << 8;
25
26      /// If true, await is treated as a keyword.
27      const InStaticBlock = 1 << 9;
28
29      const IsContinueAllowed = 1 << 10;
30      const IsBreakAllowed = 1 << 11;
31
32      const InType = 1 << 12;
33      /// Typescript extension.
34      const ShouldNotLexLtOrGtAsType = 1 << 13;
35      /// Typescript extension.
36      const InDeclare = 1 << 14;
37
38      /// If true, `:` should not be treated as a type annotation.
39      const InCondExpr = 1 << 15;
40      const WillExpectColonForCond = 1 << 16;
41
42      const InClass = 1 << 17;
43
44      const InClassField = 1 << 18;
45
46      const InFunction = 1 << 19;
47
48      /// This indicates current scope or the scope out of arrow function is
49      /// function declaration or function expression or not.
50      const InsideNonArrowFunctionScope = 1 << 20;
51
52      const InParameters = 1 << 21;
53
54      const HasSuperClass = 1 << 22;
55
56      const InPropertyName = 1 << 23;
57
58      const InForcedJsxContext = 1 << 24;
59
60      // If true, allow super.x and super[x]
61      const AllowDirectSuper = 1 << 25;
62
63      const IgnoreElseClause = 1 << 26;
64
65      const DisallowConditionalTypes = 1 << 27;
66
67      const AllowUsingDecl = 1 << 28;
68
69      const TopLevel = 1 << 29;
70
71      const TsModuleBlock = 1 << 30;
72  }
73}
74
75impl Context {
76    #[cfg_attr(not(feature = "verify"), inline(always))]
77    pub fn is_reserved_word(self, word: &Atom) -> bool {
78        if !cfg!(feature = "verify") {
79            return false;
80        }
81
82        match &**word {
83            "let" => self.contains(Context::Strict),
84            // SyntaxError in the module only, not in the strict.
85            // ```JavaScript
86            // function foo() {
87            //     "use strict";
88            //     let await = 1;
89            // }
90            // ```
91            "await" => {
92                self.contains(Context::InAsync)
93                    || self.contains(Context::InStaticBlock)
94                    || self.contains(Context::Module)
95            }
96            "yield" => self.contains(Context::InGenerator) || self.contains(Context::Strict),
97
98            "null" | "true" | "false" | "break" | "case" | "catch" | "continue" | "debugger"
99            | "default" | "do" | "export" | "else" | "finally" | "for" | "function" | "if"
100            | "return" | "switch" | "throw" | "try" | "var" | "const" | "while" | "with"
101            | "new" | "this" | "super" | "class" | "extends" | "import" | "in" | "instanceof"
102            | "typeof" | "void" | "delete" => true,
103
104            // Future reserved word
105            "enum" => true,
106
107            "implements" | "package" | "protected" | "interface" | "private" | "public"
108                if self.contains(Context::Strict) =>
109            {
110                true
111            }
112
113            _ => false,
114        }
115    }
116}