1/**
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ES2PANDA_PARSER_CORE_PARSER_PRIVATE_CONTEXT_H
17#define ES2PANDA_PARSER_CORE_PARSER_PRIVATE_CONTEXT_H
18
19#include <macros.h>
20#include <parser/program/program.h>
21#include <util/enumbitops.h>
22#include <util/ustring.h>
23
24#include <vector>
25
26namespace panda::es2panda::parser {
27enum class ParserStatus : uint64_t {
28    NO_OPTS = 0,
29    STRICT = (1 << 0),
30
31    FUNCTION = (1 << 1),
32    ARROW_FUNCTION = (1 << 2),
33    GENERATOR_FUNCTION = (1 << 3),
34    ASYNC_FUNCTION = (1 << 4),
35    CONSTRUCTOR_FUNCTION = (1 << 5),
36    FUNCTION_PARAM = (1 << 6),
37    IS_SPREAD = (1 << 7),
38    ACCESSOR_FUNCTION = (1 << 8),
39    FUNCTION_DECLARATION = (1 << 9),
40
41    ALLOW_SUPER = (1 << 10),
42    ALLOW_SUPER_CALL = (1 << 11),
43
44    DISALLOW_AWAIT = (1 << 12),
45    ALLOW_YIELD = (1 << 13),
46    IN_ITERATION = (1 << 14),
47    IN_LABELED = (1 << 15),
48
49    EXPORT_REACHED = (1 << 16),
50    HAS_COMPLEX_PARAM = (1 << 17),
51    IN_SWITCH = (1 << 18),
52
53    MODULE = (1 << 19),
54    ALLOW_NEW_TARGET = (1 << 20),
55
56    IN_EXTENDS = (1 << 21),
57    ALLOW_THIS_TYPE = (1 << 22),
58    IN_METHOD_DEFINITION = (1 << 23),
59    IN_AMBIENT_CONTEXT = (1 << 24),
60    IN_CLASS_BODY = (1 << 25),
61    IN_DECORATOR = (1 << 26),
62    DISALLOW_CONTINUE = (1 << 27),
63
64    TS_MODULE = (1 << 28),
65    DISALLOW_CONDITIONAL_TYPES = (1 << 29),
66    STATIC_BLOCK = (1 << 30),
67    DISALLOW_ARGUMENTS = (1 << 31),
68};
69
70DEFINE_BITOPS(ParserStatus)
71
72class ParserContext {
73public:
74    explicit ParserContext(const Program *program) : program_(program) {}
75    explicit ParserContext(ParserContext *current, ParserStatus newStatus, util::StringView label = "")
76        : program_(current->program_), prev_(current), label_(label)
77    {
78        ParserStatus currentStatus = current->status_;
79        currentStatus &= (ParserStatus::MODULE | ParserStatus::ALLOW_NEW_TARGET | ParserStatus::IN_EXTENDS |
80                          ParserStatus::ALLOW_THIS_TYPE | ParserStatus::IN_CLASS_BODY | ParserStatus::FUNCTION);
81        status_ = currentStatus | newStatus;
82    }
83
84    DEFAULT_COPY_SEMANTIC(ParserContext);
85    DEFAULT_MOVE_SEMANTIC(ParserContext);
86    ~ParserContext() = default;
87
88    const Program *GetProgram() const
89    {
90        return program_;
91    }
92
93    ParserContext *Prev() const
94    {
95        return prev_;
96    }
97
98    const ParserStatus &Status() const
99    {
100        return status_;
101    }
102
103    ParserStatus &Status()
104    {
105        return status_;
106    }
107
108    bool IsGenerator() const
109    {
110        return (status_ & ParserStatus::GENERATOR_FUNCTION) != 0;
111    }
112
113    bool AllowYield() const
114    {
115        return (status_ & ParserStatus::ALLOW_YIELD) != 0;
116    }
117
118    bool DisallowAwait() const
119    {
120        return (status_ & ParserStatus::DISALLOW_AWAIT) != 0;
121    }
122
123    bool IsAsync() const
124    {
125        return (status_ & ParserStatus::ASYNC_FUNCTION) != 0;
126    }
127
128    bool IsModule() const
129    {
130        return (status_ & ParserStatus::MODULE) != 0;
131    }
132
133    bool IsTsModule() const
134    {
135        return (status_ & ParserStatus::TS_MODULE) != 0;
136    }
137
138    bool IsStaticBlock() const
139    {
140        return (status_ & ParserStatus::STATIC_BLOCK) != 0;
141    }
142
143    bool DisallowArguments() const
144    {
145        return (status_ & ParserStatus::DISALLOW_ARGUMENTS) != 0;
146    }
147
148    const ParserContext *FindLabel(const util::StringView &label) const;
149
150private:
151    const Program *program_;
152    ParserContext *prev_ {};
153    ParserStatus status_ {};
154    util::StringView label_ {};
155};
156}  // namespace panda::es2panda::parser
157
158#endif
159