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