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;
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 
Name() const50     const util::StringView &Name() const
51     {
52         return name_;
53     }
54 
Node() const55     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 
BindNode(const ir::AstNode *node)78     void BindNode(const ir::AstNode *node)
79     {
80         node_ = node;
81     }
82 
IsLetOrConstOrClassDecl() const83     bool IsLetOrConstOrClassDecl() const
84     {
85         return IsLetDecl() || IsConstDecl() || IsClassDecl();
86     }
87 
Flags() const88     DeclarationFlags Flags() const
89     {
90         return flags_;
91     }
92 
AddFlag(DeclarationFlags flag)93     void AddFlag(DeclarationFlags flag)
94     {
95         flags_ |= flag;
96     }
97 
HasFlag(DeclarationFlags flag) const98     bool HasFlag(DeclarationFlags flag) const
99     {
100         return (flags_ & flag) != 0;
101     }
102 
IsImportDecl() const103     bool IsImportDecl() const
104     {
105         return HasFlag(DeclarationFlags::IMPORT);
106     }
107 
IsImportOrExportDecl() const108     bool IsImportOrExportDecl() const
109     {
110         return HasFlag(DeclarationFlags::IMPORT | DeclarationFlags::EXPORT);
111     }
112 
IsExportDeclInTsModule() const113     bool IsExportDeclInTsModule() const
114     {
115         return HasFlag(DeclarationFlags::EXPORT_IN_TSMODULE);
116     }
117 
SetDeclare(bool isDeclare)118     void SetDeclare(bool isDeclare)
119     {
120         isDeclare_ = isDeclare;
121     }
122 
IsDeclare() const123     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:
Decl(util::StringView name)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() const151     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 
170     DeclType Type() const override
171     {
172         return DeclType::ENUM_LITERAL;
173     }
174 
IsExport() const175     bool IsExport() const
176     {
177         return isExport_;
178     }
179 
IsConst() const180     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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
357     DeclType Type() const override
358     {
359         return DeclType::IMPORT_EQUALS;
360     }
361 };
362 
363 }  // namespace panda::es2panda::binder
364 
365 #endif
366