• 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 "varbinder/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 ImportDeclaration;
28 class ETSImportDeclaration;
29 }  // namespace panda::es2panda::ir
30 
31 namespace panda::es2panda::varbinder {
32 class Scope;
33 class LocalScope;
34 
35 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
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     ir::AstNode *Node()
54     {
55         return node_;
56     }
57 
58     const ir::AstNode *Node() const
59     {
60         return node_;
61     }
62 
63 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
64 #define DECLARE_CHECKS_CASTS(declKind, className)         \
65     bool Is##className() const                            \
66     {                                                     \
67         return Type() == DeclType::declKind;              \
68     }                                                     \
69     className *As##className()                            \
70     {                                                     \
71         ASSERT(Is##className());                          \
72         return reinterpret_cast<className *>(this);       \
73     }                                                     \
74     const className *As##className() const                \
75     {                                                     \
76         ASSERT(Is##className());                          \
77         return reinterpret_cast<const className *>(this); \
78     }
79     DECLARATION_KINDS(DECLARE_CHECKS_CASTS)
80 #undef DECLARE_CHECKS_CASTS
81 
82     void BindNode(ir::AstNode *node)
83     {
84         node_ = node;
85     }
86 
87     bool IsLetOrConstDecl() const
88     {
89         return IsLetDecl() || IsConstDecl();
90     }
91 
92     bool PossibleTDZ() const
93     {
94         return IsLetOrConstDecl() || IsParameterDecl();
95     }
96 
97 protected:
98     explicit Decl(util::StringView name) : name_(name) {}
99     explicit Decl(util::StringView name, ir::AstNode *declNode) : name_(name), node_(declNode) {}
100 
101     // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
102     util::StringView name_;
103     ir::AstNode *node_ {};
104     // NOLINTEND(misc-non-private-member-variables-in-classes)
105 };
106 
107 template <typename T>
108 class MultiDecl : public Decl {
109 public:
MultiDecl(ArenaAllocator * allocator,util::StringView name)110     explicit MultiDecl(ArenaAllocator *allocator, util::StringView name)
111         : Decl(name), declarations_(allocator->Adapter())
112     {
113     }
114 
MultiDecl(ArenaAllocator * allocator,util::StringView name,ir::AstNode * declNode)115     explicit MultiDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode)
116         : Decl(name, declNode), declarations_(allocator->Adapter())
117     {
118     }
119 
Decls()120     const ArenaVector<T *> &Decls() const
121     {
122         return declarations_;
123     }
124 
Add(T * decl)125     void Add(T *decl)
126     {
127         declarations_.push_back(decl);
128     }
129 
130 private:
131     ArenaVector<T *> declarations_;
132 };
133 
134 class EnumLiteralDecl : public Decl {
135 public:
EnumLiteralDecl(util::StringView name,bool isConst)136     explicit EnumLiteralDecl(util::StringView name, bool isConst) : Decl(name), isConst_(isConst) {}
EnumLiteralDecl(util::StringView name,ir::AstNode * declNode,bool isConst)137     explicit EnumLiteralDecl(util::StringView name, ir::AstNode *declNode, bool isConst)
138         : Decl(name, declNode), isConst_(isConst)
139     {
140     }
141 
Type()142     DeclType Type() const override
143     {
144         return DeclType::ENUM_LITERAL;
145     }
146 
IsConst()147     bool IsConst() const
148     {
149         return isConst_;
150     }
151 
BindScope(LocalScope * scope)152     void BindScope(LocalScope *scope)
153     {
154         scope_ = scope;
155     }
156 
Scope()157     LocalScope *Scope()
158     {
159         return scope_;
160     }
161 
162 private:
163     LocalScope *scope_ {};
164     bool isConst_ {};
165 };
166 
167 class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> {
168 public:
InterfaceDecl(ArenaAllocator * allocator,util::StringView name)169     explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {}
InterfaceDecl(ArenaAllocator * allocator,util::StringView name,ir::AstNode * declNode)170     explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode)
171         : MultiDecl(allocator, name, declNode)
172     {
173     }
174 
Type()175     DeclType Type() const override
176     {
177         return DeclType::INTERFACE;
178     }
179 };
180 
181 class ClassDecl : public Decl {
182 public:
ClassDecl(util::StringView name)183     explicit ClassDecl(util::StringView name) : Decl(name) {}
ClassDecl(util::StringView name,ir::AstNode * node)184     explicit ClassDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {}
185 
Type()186     DeclType Type() const override
187     {
188         return DeclType::CLASS;
189     }
190 };
191 
192 class FunctionDecl : public MultiDecl<ir::ScriptFunction> {
193 public:
FunctionDecl(ArenaAllocator * allocator,util::StringView name,ir::AstNode * node)194     explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *node)
195         : MultiDecl(allocator, name)
196     {
197         node_ = node;
198     }
199 
Type()200     DeclType Type() const override
201     {
202         return DeclType::FUNC;
203     }
204 };
205 
206 class TypeParameterDecl : public Decl {
207 public:
TypeParameterDecl(util::StringView name)208     explicit TypeParameterDecl(util::StringView name) : Decl(name) {}
209 
Type()210     DeclType Type() const override
211     {
212         return DeclType::TYPE_PARAMETER;
213     }
214 };
215 
216 class PropertyDecl : public Decl {
217 public:
PropertyDecl(util::StringView name)218     explicit PropertyDecl(util::StringView name) : Decl(name) {}
219 
Type()220     DeclType Type() const override
221     {
222         return DeclType::PROPERTY;
223     }
224 };
225 
226 class MethodDecl : public Decl {
227 public:
MethodDecl(util::StringView name)228     explicit MethodDecl(util::StringView name) : Decl(name) {}
229 
Type()230     DeclType Type() const override
231     {
232         return DeclType::METHOD;
233     }
234 };
235 
236 class EnumDecl : public Decl {
237 public:
EnumDecl(util::StringView name)238     explicit EnumDecl(util::StringView name) : Decl(name) {}
239 
Type()240     DeclType Type() const override
241     {
242         return DeclType::ENUM;
243     }
244 };
245 
246 class TypeAliasDecl : public Decl {
247 public:
TypeAliasDecl(util::StringView name)248     explicit TypeAliasDecl(util::StringView name) : Decl(name) {}
TypeAliasDecl(util::StringView name,ir::AstNode * node)249     explicit TypeAliasDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {}
250 
Type()251     DeclType Type() const override
252     {
253         return DeclType::TYPE_ALIAS;
254     }
255 };
256 
257 class NameSpaceDecl : public Decl {
258 public:
NameSpaceDecl(util::StringView name)259     explicit NameSpaceDecl(util::StringView name) : Decl(name) {}
260 
Type()261     DeclType Type() const override
262     {
263         return DeclType::NAMESPACE;
264     }
265 };
266 
267 class VarDecl : public Decl {
268 public:
VarDecl(util::StringView name)269     explicit VarDecl(util::StringView name) : Decl(name) {}
270 
Type()271     DeclType Type() const override
272     {
273         return DeclType::VAR;
274     }
275 };
276 
277 class LetDecl : public Decl {
278 public:
LetDecl(util::StringView name)279     explicit LetDecl(util::StringView name) : Decl(name) {}
LetDecl(util::StringView name,ir::AstNode * declNode)280     explicit LetDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {}
281 
Type()282     DeclType Type() const override
283     {
284         return DeclType::LET;
285     }
286 };
287 
288 class ConstDecl : public Decl {
289 public:
ConstDecl(util::StringView name)290     explicit ConstDecl(util::StringView name) : Decl(name) {}
ConstDecl(util::StringView name,ir::AstNode * declNode)291     explicit ConstDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {}
292 
Type()293     DeclType Type() const override
294     {
295         return DeclType::CONST;
296     }
297 };
298 
299 class ParameterDecl : public Decl {
300 public:
ParameterDecl(util::StringView name)301     explicit ParameterDecl(util::StringView name) : Decl(name) {}
302 
Type()303     DeclType Type() const override
304     {
305         return DeclType::PARAM;
306     }
307 };
308 
309 class ImportDecl : public Decl {
310 public:
ImportDecl(util::StringView importName,util::StringView localName)311     explicit ImportDecl(util::StringView importName, util::StringView localName)
312         : Decl(localName), importName_(importName)
313     {
314     }
315 
ImportDecl(util::StringView importName,util::StringView localName,ir::AstNode * node)316     explicit ImportDecl(util::StringView importName, util::StringView localName, ir::AstNode *node)
317         : Decl(localName), importName_(importName)
318     {
319         BindNode(node);
320     }
321 
ImportName()322     const util::StringView &ImportName() const
323     {
324         return importName_;
325     }
326 
LocalName()327     const util::StringView &LocalName() const
328     {
329         return name_;
330     }
331 
Type()332     DeclType Type() const override
333     {
334         return DeclType::IMPORT;
335     }
336 
337 private:
338     util::StringView importName_;
339 };
340 
341 class ExportDecl : public Decl {
342 public:
ExportDecl(util::StringView exportName,util::StringView localName)343     explicit ExportDecl(util::StringView exportName, util::StringView localName)
344         : Decl(localName), exportName_(exportName)
345     {
346     }
347 
ExportDecl(util::StringView exportName,util::StringView localName,ir::AstNode * node)348     explicit ExportDecl(util::StringView exportName, util::StringView localName, ir::AstNode *node)
349         : Decl(localName), exportName_(exportName)
350     {
351         BindNode(node);
352     }
353 
ExportName()354     const util::StringView &ExportName() const
355     {
356         return exportName_;
357     }
358 
LocalName()359     const util::StringView &LocalName() const
360     {
361         return name_;
362     }
363 
Type()364     DeclType Type() const override
365     {
366         return DeclType::EXPORT;
367     }
368 
369 private:
370     util::StringView exportName_;
371 };
372 }  // namespace panda::es2panda::varbinder
373 
374 #endif
375