1 /*
2 * Copyright (c) 2021-2024 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_VARBINDER_RECORDTABLE_H
17 #define ES2PANDA_VARBINDER_RECORDTABLE_H
18
19 #include "macros.h"
20 #include "utils/arena_containers.h"
21 #include "util/ustring.h"
22 #include "util/enumbitops.h"
23
24 namespace panda::es2panda::parser {
25 class Program;
26 } // namespace panda::es2panda::parser
27
28 namespace panda::es2panda::checker {
29 class Signature;
30 } // namespace panda::es2panda::checker
31
32 namespace panda::es2panda::ir {
33 class ClassDefinition;
34 class TSInterfaceDeclaration;
35 class Identifier;
36 } // namespace panda::es2panda::ir
37
38 namespace panda::es2panda::varbinder {
39 class FunctionScope;
40 class BoundContext;
41
42 enum class RecordTableFlags : uint32_t {
43 NONE = 0U,
44 EXTERNAL = 1U << 0U,
45 };
46
DEFINE_BITOPS(RecordTableFlags)47 DEFINE_BITOPS(RecordTableFlags)
48
49 class RecordTable {
50 public:
51 explicit RecordTable(ArenaAllocator *allocator, parser::Program *program, RecordTableFlags flags)
52 : classDefinitions_(allocator->Adapter()),
53 interfaceDeclarations_(allocator->Adapter()),
54 signatures_(allocator->Adapter()),
55 program_(program),
56 flags_(flags)
57 {
58 }
59
60 NO_COPY_SEMANTIC(RecordTable);
61 NO_MOVE_SEMANTIC(RecordTable);
62
63 ~RecordTable() = default;
64
65 bool IsExternal() const
66 {
67 return (flags_ & RecordTableFlags::EXTERNAL) != 0;
68 }
69
70 ArenaSet<ir::ClassDefinition *> &ClassDefinitions()
71 {
72 return classDefinitions_;
73 }
74
75 const ArenaSet<ir::ClassDefinition *> &ClassDefinitions() const
76 {
77 return classDefinitions_;
78 }
79
80 ArenaSet<ir::TSInterfaceDeclaration *> &InterfaceDeclarations()
81 {
82 return interfaceDeclarations_;
83 }
84
85 const ArenaSet<ir::TSInterfaceDeclaration *> &InterfaceDeclarations() const
86 {
87 return interfaceDeclarations_;
88 }
89
90 ArenaVector<FunctionScope *> &Signatures()
91 {
92 return signatures_;
93 }
94
95 const ArenaVector<FunctionScope *> &Signatures() const
96 {
97 return signatures_;
98 }
99
100 void SetClassDefinition(ir::ClassDefinition *classDefinition)
101 {
102 record_ = classDefinition;
103 }
104
105 ir::ClassDefinition *ClassDefinition()
106 {
107 return std::holds_alternative<ir::ClassDefinition *>(record_) ? std::get<ir::ClassDefinition *>(record_)
108 : nullptr;
109 }
110
111 const ir::ClassDefinition *ClassDefinition() const
112 {
113 return std::holds_alternative<ir::ClassDefinition *>(record_) ? std::get<ir::ClassDefinition *>(record_)
114 : nullptr;
115 }
116
117 void SetInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDeclaration)
118 {
119 record_ = interfaceDeclaration;
120 }
121
122 ir::TSInterfaceDeclaration *InterfaceDeclaration()
123 {
124 return std::holds_alternative<ir::TSInterfaceDeclaration *>(record_)
125 ? std::get<ir::TSInterfaceDeclaration *>(record_)
126 : nullptr;
127 }
128
129 const ir::TSInterfaceDeclaration *InterfaceDeclaration() const
130 {
131 return std::holds_alternative<ir::TSInterfaceDeclaration *>(record_)
132 ? std::get<ir::TSInterfaceDeclaration *>(record_)
133 : nullptr;
134 }
135
136 void SetProgram(parser::Program *program)
137 {
138 program_ = program;
139 }
140
141 parser::Program *Program()
142 {
143 return program_;
144 }
145
146 const parser::Program *Program() const
147 {
148 return program_;
149 }
150
151 util::StringView RecordName() const;
152
153 private:
154 friend class BoundContext;
155 using RecordHolder = std::variant<ir::ClassDefinition *, ir::TSInterfaceDeclaration *, std::nullptr_t>;
156
157 ArenaSet<ir::ClassDefinition *> classDefinitions_;
158 ArenaSet<ir::TSInterfaceDeclaration *> interfaceDeclarations_;
159 ArenaVector<varbinder::FunctionScope *> signatures_;
160 RecordHolder record_ {nullptr};
161 parser::Program *program_ {};
162 BoundContext *boundCtx_ {};
163 RecordTableFlags flags_ {};
164 };
165
166 class BoundContext {
167 public:
168 explicit BoundContext(RecordTable *recordTable, ir::ClassDefinition *classDef);
169 explicit BoundContext(RecordTable *recordTable, ir::TSInterfaceDeclaration *interfaceDecl);
170 ~BoundContext();
171
172 NO_COPY_SEMANTIC(BoundContext);
173 NO_MOVE_SEMANTIC(BoundContext);
174
175 void *operator new(size_t) = delete;
176 void *operator new[](size_t) = delete;
177
178 util::StringView FormRecordName() const;
179
180 private:
181 BoundContext *prev_;
182 RecordTable *recordTable_;
183 RecordTable::RecordHolder savedRecord_ {nullptr};
184 ir::Identifier *recordIdent_;
185 };
186
187 } // namespace panda::es2panda::varbinder
188
189 #endif
190