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