• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ark::es2panda::parser {
25 class Program;
26 }  // namespace ark::es2panda::parser
27 
28 namespace ark::es2panda::checker {
29 class Signature;
30 }  // namespace ark::es2panda::checker
31 
32 namespace ark::es2panda::ir {
33 class ClassDefinition;
34 class TSInterfaceDeclaration;
35 class AnnotationDeclaration;
36 class Identifier;
37 }  // namespace ark::es2panda::ir
38 
39 namespace ark::es2panda::varbinder {
40 class FunctionScope;
41 class BoundContext;
42 
43 using ENUMBITOPS_OPERATORS;
44 
45 enum class RecordTableFlags : uint32_t {
46     NONE = 0U,
47     EXTERNAL = 1U << 0U,
48 };
49 
50 }  // namespace ark::es2panda::varbinder
51 
52 template <>
53 struct enumbitops::IsAllowedType<ark::es2panda::varbinder::RecordTableFlags> : std::true_type {
54 };
55 
56 namespace ark::es2panda::varbinder {
57 
58 class RecordTable {
59 public:
60     explicit RecordTable(ArenaAllocator *allocator, parser::Program *program, RecordTableFlags flags)
61         : classDefinitions_(allocator->Adapter()),
62           interfaceDeclarations_(allocator->Adapter()),
63           annotationDeclarations_(allocator->Adapter()),
64           signatures_(allocator->Adapter()),
65           program_(program),
66           flags_(flags)
67     {
68     }
69 
70     NO_COPY_SEMANTIC(RecordTable);
71     NO_MOVE_SEMANTIC(RecordTable);
72 
73     ~RecordTable() = default;
74 
75     bool IsExternal() const
76     {
77         return (flags_ & RecordTableFlags::EXTERNAL) != 0;
78     }
79 
80     ArenaSet<ir::ClassDefinition *> &ClassDefinitions()
81     {
82         return classDefinitions_;
83     }
84 
85     const ArenaSet<ir::ClassDefinition *> &ClassDefinitions() const
86     {
87         return classDefinitions_;
88     }
89 
90     ArenaSet<ir::TSInterfaceDeclaration *> &InterfaceDeclarations()
91     {
92         return interfaceDeclarations_;
93     }
94 
95     const ArenaSet<ir::TSInterfaceDeclaration *> &InterfaceDeclarations() const
96     {
97         return interfaceDeclarations_;
98     }
99 
100     ArenaSet<ir::AnnotationDeclaration *> &AnnotationDeclarations()
101     {
102         return annotationDeclarations_;
103     }
104 
105     const ArenaSet<ir::AnnotationDeclaration *> &AnnotationDeclarations() const
106     {
107         return annotationDeclarations_;
108     }
109 
110     ArenaVector<FunctionScope *> &Signatures()
111     {
112         return signatures_;
113     }
114 
115     const ArenaVector<FunctionScope *> &Signatures() const
116     {
117         return signatures_;
118     }
119 
120     void SetClassDefinition(ir::ClassDefinition *classDefinition)
121     {
122         record_ = classDefinition;
123     }
124 
125     ir::ClassDefinition *ClassDefinition()
126     {
127         return std::holds_alternative<ir::ClassDefinition *>(record_) ? std::get<ir::ClassDefinition *>(record_)
128                                                                       : nullptr;
129     }
130 
131     const ir::ClassDefinition *ClassDefinition() const
132     {
133         return std::holds_alternative<ir::ClassDefinition *>(record_) ? std::get<ir::ClassDefinition *>(record_)
134                                                                       : nullptr;
135     }
136 
137     void SetInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDeclaration)
138     {
139         record_ = interfaceDeclaration;
140     }
141 
142     ir::TSInterfaceDeclaration *InterfaceDeclaration()
143     {
144         return std::holds_alternative<ir::TSInterfaceDeclaration *>(record_)
145                    ? std::get<ir::TSInterfaceDeclaration *>(record_)
146                    : nullptr;
147     }
148 
149     const ir::TSInterfaceDeclaration *InterfaceDeclaration() const
150     {
151         return std::holds_alternative<ir::TSInterfaceDeclaration *>(record_)
152                    ? std::get<ir::TSInterfaceDeclaration *>(record_)
153                    : nullptr;
154     }
155 
156     void SetAnnotationDeclaration(ir::AnnotationDeclaration *annotationDeclaration)
157     {
158         record_ = annotationDeclaration;
159     }
160 
161     ir::AnnotationDeclaration *AnnotationDeclaration()
162     {
163         return std::holds_alternative<ir::AnnotationDeclaration *>(record_)
164                    ? std::get<ir::AnnotationDeclaration *>(record_)
165                    : nullptr;
166     }
167 
168     const ir::AnnotationDeclaration *AnnotationDeclaration() const
169     {
170         return std::holds_alternative<ir::AnnotationDeclaration *>(record_)
171                    ? std::get<ir::AnnotationDeclaration *>(record_)
172                    : nullptr;
173     }
174 
175     void SetProgram(parser::Program *program)
176     {
177         program_ = program;
178     }
179 
180     parser::Program *Program()
181     {
182         return program_;
183     }
184 
185     const parser::Program *Program() const
186     {
187         return program_;
188     }
189 
190     util::StringView RecordName() const;
191 
192 private:
193     friend class BoundContext;
194     using RecordHolder =
195         std::variant<ir::ClassDefinition *, ir::TSInterfaceDeclaration *, ir::AnnotationDeclaration *, std::nullptr_t>;
196 
197     ArenaSet<ir::ClassDefinition *> classDefinitions_;
198     ArenaSet<ir::TSInterfaceDeclaration *> interfaceDeclarations_;
199     ArenaSet<ir::AnnotationDeclaration *> annotationDeclarations_;
200     ArenaVector<varbinder::FunctionScope *> signatures_;
201     RecordHolder record_ {nullptr};
202     parser::Program *program_ {};
203     BoundContext *boundCtx_ {};
204     RecordTableFlags flags_ {};
205 };
206 
207 class BoundContext {
208 public:
209     explicit BoundContext(RecordTable *recordTable, ir::ClassDefinition *classDef, bool force = false);
210     explicit BoundContext(RecordTable *recordTable, ir::TSInterfaceDeclaration *interfaceDecl, bool force = false);
211     explicit BoundContext(RecordTable *recordTable, ir::AnnotationDeclaration *annotationDecl, bool force = false);
212     ~BoundContext();
213 
214     NO_COPY_SEMANTIC(BoundContext);
215     NO_MOVE_SEMANTIC(BoundContext);
216 
217     void *operator new(size_t) = delete;
218     void *operator new[](size_t) = delete;
219 
220     util::StringView FormRecordName() const;
221 
222 private:
223     BoundContext *prev_;
224     RecordTable *recordTable_;
225     RecordTable::RecordHolder currentRecord_ {nullptr};
226     RecordTable::RecordHolder savedRecord_ {nullptr};
227     ir::Identifier *recordIdent_ {nullptr};
228 };
229 
230 }  // namespace ark::es2panda::varbinder
231 
232 #endif  // ES2PANDA_VARBINDER_RECORDTABLE_H
233