• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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