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_COMPILER_SCOPES_DECLARATION_H
17 #define ES2PANDA_COMPILER_SCOPES_DECLARATION_H
18
19 #include <binder/variableFlags.h>
20 #include <macros.h>
21 #include <util/ustring.h>
22
23 namespace panda::es2panda::ir {
24 class AstNode;
25 class ScriptFunction;
26 class TSInterfaceDeclaration;
27 class TSModuleDeclaration;
28 class ImportDeclaration;
29 } // namespace panda::es2panda::ir
30
31 namespace panda::es2panda::binder {
32
33 class Scope;
34 class LocalScope;
35
36 #define DECLARE_CLASSES(decl_kind, className) class className;
DECLARATION_KINDS(DECLARE_CLASSES)37 DECLARATION_KINDS(DECLARE_CLASSES)
38 #undef DECLARE_CLASSES
39
40 class Decl {
41 public:
42 virtual ~Decl() = default;
43 NO_COPY_SEMANTIC(Decl);
44 NO_MOVE_SEMANTIC(Decl);
45
46 virtual DeclType Type() const = 0;
47
48 const util::StringView &Name() const
49 {
50 return name_;
51 }
52
53 const ir::AstNode *Node() const
54 {
55 return node_;
56 }
57
58 #define DECLARE_CHECKS_CASTS(declKind, className) \
59 bool Is##className() const \
60 { \
61 return Type() == DeclType::declKind; \
62 } \
63 className *As##className() \
64 { \
65 ASSERT(Is##className()); \
66 return reinterpret_cast<className *>(this); \
67 } \
68 const className *As##className() const \
69 { \
70 ASSERT(Is##className()); \
71 return reinterpret_cast<const className *>(this); \
72 }
73 DECLARATION_KINDS(DECLARE_CHECKS_CASTS)
74 #undef DECLARE_CHECKS_CASTS
75
76 void BindNode(const ir::AstNode *node)
77 {
78 node_ = node;
79 }
80
81 bool IsLetOrConstOrClassDecl() const
82 {
83 return IsLetDecl() || IsConstDecl() || IsClassDecl();
84 }
85
86 DeclarationFlags Flags() const
87 {
88 return flags_;
89 }
90
91 void AddFlag(DeclarationFlags flag)
92 {
93 flags_ |= flag;
94 }
95
96 bool HasFlag(DeclarationFlags flag) const
97 {
98 return (flags_ & flag) != 0;
99 }
100
101 bool IsImportDecl() const
102 {
103 return HasFlag(DeclarationFlags::IMPORT);
104 }
105
106 bool IsImportOrExportDecl() const
107 {
108 return HasFlag(DeclarationFlags::IMPORT | DeclarationFlags::EXPORT);
109 }
110
111 protected:
112 explicit Decl(util::StringView name) : name_(name) {}
113
114 util::StringView name_;
115 DeclarationFlags flags_ {};
116 const ir::AstNode *node_ {};
117 };
118
119 template <typename T>
120 class MultiDecl : public Decl {
121 public:
MultiDecl(ArenaAllocator * allocator,util::StringView name)122 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name)
123 : Decl(name), declarations_(allocator->Adapter())
124 {
125 }
126
Decls()127 const ArenaVector<T *> &Decls() const
128 {
129 return declarations_;
130 }
131
Add(T * decl)132 void Add(T *decl)
133 {
134 declarations_.push_back(decl);
135 }
136
137 private:
138 ArenaVector<T *> declarations_;
139 };
140
141 class EnumLiteralDecl : public Decl {
142 public:
EnumLiteralDecl(util::StringView name,bool isConst)143 explicit EnumLiteralDecl(util::StringView name, bool isConst) : Decl(name), isConst_(isConst) {}
144
Type()145 DeclType Type() const override
146 {
147 return DeclType::ENUM_LITERAL;
148 }
149
IsConst()150 bool IsConst() const
151 {
152 return isConst_;
153 }
154
BindScope(LocalScope * scope)155 void BindScope(LocalScope *scope)
156 {
157 scope_ = scope;
158 }
159
Scope()160 LocalScope *Scope()
161 {
162 return scope_;
163 }
164
165 private:
166 LocalScope *scope_ {};
167 bool isConst_ {};
168 };
169
170 class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> {
171 public:
InterfaceDecl(ArenaAllocator * allocator,util::StringView name)172 explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {}
173
Type()174 DeclType Type() const override
175 {
176 return DeclType::INTERFACE;
177 }
178 };
179
180 class FunctionDecl : public MultiDecl<ir::ScriptFunction> {
181 public:
FunctionDecl(ArenaAllocator * allocator,util::StringView name,const ir::AstNode * node)182 explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, const ir::AstNode *node)
183 : MultiDecl(allocator, name)
184 {
185 node_ = node;
186 }
187
Type()188 DeclType Type() const override
189 {
190 return DeclType::FUNC;
191 }
192 };
193
194 class TypeParameterDecl : public Decl {
195 public:
196 explicit TypeParameterDecl(util::StringView name, const ir::AstNode *node);
197
Type()198 DeclType Type() const override
199 {
200 return DeclType::TYPE_PARAMETER;
201 }
202 };
203
204 class PropertyDecl : public Decl {
205 public:
PropertyDecl(util::StringView name)206 explicit PropertyDecl(util::StringView name) : Decl(name) {}
207
Type()208 DeclType Type() const override
209 {
210 return DeclType::PROPERTY;
211 }
212 };
213
214 class MethodDecl : public Decl {
215 public:
MethodDecl(util::StringView name)216 explicit MethodDecl(util::StringView name) : Decl(name) {}
217
Type()218 DeclType Type() const override
219 {
220 return DeclType::METHOD;
221 }
222 };
223
224 class EnumDecl : public Decl {
225 public:
EnumDecl(util::StringView name)226 explicit EnumDecl(util::StringView name) : Decl(name) {}
227
Type()228 DeclType Type() const override
229 {
230 return DeclType::ENUM;
231 }
232 };
233
234 class TypeAliasDecl : public Decl {
235 public:
TypeAliasDecl(util::StringView name)236 explicit TypeAliasDecl(util::StringView name) : Decl(name) {}
237
Type()238 DeclType Type() const override
239 {
240 return DeclType::TYPE_ALIAS;
241 }
242 };
243
244 class NamespaceDecl : public MultiDecl<ir::TSModuleDeclaration> {
245 public:
NamespaceDecl(ArenaAllocator * allocator,util::StringView name)246 explicit NamespaceDecl(ArenaAllocator *allocator, util::StringView name)
247 : MultiDecl(allocator, name)
248 {
249 }
250
Type()251 DeclType Type() const override
252 {
253 return DeclType::NAMESPACE;
254 }
255 };
256
257 class VarDecl : public Decl {
258 public:
VarDecl(util::StringView name)259 explicit VarDecl(util::StringView name) : Decl(name) {}
260
Type()261 DeclType Type() const override
262 {
263 return DeclType::VAR;
264 }
265 };
266
267 class LetDecl : public Decl {
268 public:
LetDecl(util::StringView name)269 explicit LetDecl(util::StringView name) : Decl(name) {}
270
Type()271 DeclType Type() const override
272 {
273 return DeclType::LET;
274 }
275 };
276
277 class ConstDecl : public Decl {
278 public:
ConstDecl(util::StringView name)279 explicit ConstDecl(util::StringView name) : Decl(name) {}
280
Type()281 DeclType Type() const override
282 {
283 return DeclType::CONST;
284 }
285 };
286
287 class ClassDecl : public Decl {
288 public:
ClassDecl(util::StringView name)289 explicit ClassDecl(util::StringView name) : Decl(name) {}
290
Type()291 DeclType Type() const override
292 {
293 return DeclType::CLASS;
294 }
295 };
296
297 class ParameterDecl : public Decl {
298 public:
ParameterDecl(util::StringView name)299 explicit ParameterDecl(util::StringView name) : Decl(name) {}
300
Type()301 DeclType Type() const override
302 {
303 return DeclType::PARAM;
304 }
305 };
306
307 class ImportEqualsDecl : public Decl {
308 public:
ImportEqualsDecl(util::StringView name)309 explicit ImportEqualsDecl(util::StringView name) : Decl(name) {}
310
Type()311 DeclType Type() const override
312 {
313 return DeclType::IMPORT_EQUALS;
314 }
315 };
316
317 } // namespace panda::es2panda::binder
318
319 #endif
320