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 bool IsSendableClassDecl() const;
129
130 bool IsSendableFunctionDecl() const;
131
132 bool NeedSetInSendableEnv(Scope *scope) const;
133
134 protected:
135 explicit Decl(util::StringView name) : name_(name) {}
136
137 util::StringView name_;
138 DeclarationFlags flags_ {};
139 const ir::AstNode *node_ {};
140 bool isDeclare_ {false};
141 };
142
143 template <typename T>
144 class MultiDecl : public Decl {
145 public:
MultiDecl(ArenaAllocator * allocator,util::StringView name)146 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name)
147 : Decl(name), declarations_(allocator->Adapter())
148 {
149 }
150
Decls()151 const ArenaVector<T *> &Decls() const
152 {
153 return declarations_;
154 }
155
Add(T * decl)156 void Add(T *decl)
157 {
158 declarations_.push_back(decl);
159 }
160
161 private:
162 ArenaVector<T *> declarations_;
163 };
164
165 class EnumLiteralDecl : public MultiDecl<ir::TSEnumDeclaration> {
166 public:
EnumLiteralDecl(ArenaAllocator * allocator,util::StringView name,bool isExport,bool isConst)167 explicit EnumLiteralDecl(ArenaAllocator *allocator, util::StringView name, bool isExport, bool isConst)
168 : MultiDecl(allocator, name), isExport_(isExport), isConst_(isConst) {}
169
Type()170 DeclType Type() const override
171 {
172 return DeclType::ENUM_LITERAL;
173 }
174
IsExport()175 bool IsExport() const
176 {
177 return isExport_;
178 }
179
IsConst()180 bool IsConst() const
181 {
182 return isConst_;
183 }
184
BindScope(TSEnumScope * scope)185 void BindScope(TSEnumScope *scope)
186 {
187 scope_ = scope;
188 }
189
Scope()190 TSEnumScope *Scope()
191 {
192 return scope_;
193 }
194
195 private:
196 TSEnumScope *scope_ {nullptr};
197 bool isExport_ {};
198 bool isConst_ {};
199 };
200
201 class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> {
202 public:
InterfaceDecl(ArenaAllocator * allocator,util::StringView name)203 explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {}
204
Type()205 DeclType Type() const override
206 {
207 return DeclType::INTERFACE;
208 }
209 };
210
211 class TypeParameterDecl : public Decl {
212 public:
213 explicit TypeParameterDecl(util::StringView name, const ir::AstNode *node);
214
Type()215 DeclType Type() const override
216 {
217 return DeclType::TYPE_PARAMETER;
218 }
219 };
220
221 class PropertyDecl : public Decl {
222 public:
PropertyDecl(util::StringView name)223 explicit PropertyDecl(util::StringView name) : Decl(name) {}
224
Type()225 DeclType Type() const override
226 {
227 return DeclType::PROPERTY;
228 }
229 };
230
231 class MethodDecl : public Decl {
232 public:
MethodDecl(util::StringView name)233 explicit MethodDecl(util::StringView name) : Decl(name) {}
234
Type()235 DeclType Type() const override
236 {
237 return DeclType::METHOD;
238 }
239 };
240
241 class EnumDecl : public Decl {
242 public:
EnumDecl(util::StringView name)243 explicit EnumDecl(util::StringView name) : Decl(name) {}
244
Type()245 DeclType Type() const override
246 {
247 return DeclType::ENUM;
248 }
249 };
250
251 class TypeAliasDecl : public Decl {
252 public:
TypeAliasDecl(util::StringView name)253 explicit TypeAliasDecl(util::StringView name) : Decl(name) {}
254
Type()255 DeclType Type() const override
256 {
257 return DeclType::TYPE_ALIAS;
258 }
259 };
260
261 class NamespaceDecl : public MultiDecl<ir::TSModuleDeclaration> {
262 public:
NamespaceDecl(ArenaAllocator * allocator,util::StringView name)263 explicit NamespaceDecl(ArenaAllocator *allocator, util::StringView name)
264 : MultiDecl(allocator, name)
265 {
266 }
267
Type()268 DeclType Type() const override
269 {
270 return DeclType::NAMESPACE;
271 }
272
273 bool IsInstantiated() const;
274 };
275
276 class VarDecl : public Decl {
277 public:
VarDecl(util::StringView name)278 explicit VarDecl(util::StringView name) : Decl(name) {}
279
Type()280 DeclType Type() const override
281 {
282 return DeclType::VAR;
283 }
284 };
285
286 class LetDecl : public Decl {
287 public:
LetDecl(util::StringView name)288 explicit LetDecl(util::StringView name) : Decl(name) {}
289
Type()290 DeclType Type() const override
291 {
292 return DeclType::LET;
293 }
294 };
295
296 class ConstDecl : public Decl {
297 public:
ConstDecl(util::StringView name)298 explicit ConstDecl(util::StringView name) : Decl(name) {}
299
Type()300 DeclType Type() const override
301 {
302 return DeclType::CONST;
303 }
304 };
305
306 class ClassDecl : public Decl {
307 public:
ClassDecl(util::StringView name)308 explicit ClassDecl(util::StringView name) : Decl(name) {}
309
Type()310 DeclType Type() const override
311 {
312 return DeclType::CLASS;
313 }
314 };
315
316 class FunctionDecl : public MultiDecl<ir::ScriptFunction> {
317 public:
FunctionDecl(ArenaAllocator * allocator,util::StringView name,const ir::AstNode * node)318 explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, const ir::AstNode *node)
319 : MultiDecl(allocator, name)
320 {
321 node_ = node;
322 }
323
Type()324 DeclType Type() const override
325 {
326 return DeclType::FUNC;
327 }
328
SetDeclClass(ClassDecl * declClass)329 void SetDeclClass(ClassDecl *declClass)
330 {
331 declClass_ = declClass;
332 }
333
GetDeclClass()334 ClassDecl *GetDeclClass()
335 {
336 return declClass_;
337 }
338
339 private:
340 ClassDecl *declClass_ {nullptr};
341 };
342
343 class ParameterDecl : public Decl {
344 public:
ParameterDecl(util::StringView name)345 explicit ParameterDecl(util::StringView name) : Decl(name) {}
346
Type()347 DeclType Type() const override
348 {
349 return DeclType::PARAM;
350 }
351 };
352
353 class ImportEqualsDecl : public Decl {
354 public:
ImportEqualsDecl(util::StringView name)355 explicit ImportEqualsDecl(util::StringView name) : Decl(name) {}
356
Type()357 DeclType Type() const override
358 {
359 return DeclType::IMPORT_EQUALS;
360 }
361 };
362
363 } // namespace panda::es2panda::binder
364
365 #endif
366