1 /*
2 * Copyright (c) 2021-2024 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 ark::es2panda::ir {
24 class AstNode;
25 class ScriptFunction;
26 class TSInterfaceDeclaration;
27 class ImportDeclaration;
28 class ETSImportDeclaration;
29 } // namespace ark::es2panda::ir
30
31 namespace ark::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 LabelDecl : public Decl {
300 public:
LabelDecl(util::StringView name)301 explicit LabelDecl(util::StringView name) : Decl(name) {}
LabelDecl(util::StringView name,ir::AstNode * declNode)302 explicit LabelDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {}
303
Type()304 DeclType Type() const override
305 {
306 return DeclType::LABEL;
307 }
308 };
309
310 class ReadonlyDecl : public Decl {
311 public:
ReadonlyDecl(util::StringView name)312 explicit ReadonlyDecl(util::StringView name) : Decl(name) {}
ReadonlyDecl(util::StringView name,ir::AstNode * declNode)313 explicit ReadonlyDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {}
314
Type()315 DeclType Type() const override
316 {
317 return DeclType::READONLY;
318 }
319 };
320
321 class ParameterDecl : public Decl {
322 public:
ParameterDecl(util::StringView name)323 explicit ParameterDecl(util::StringView name) : Decl(name) {}
324
Type()325 DeclType Type() const override
326 {
327 return DeclType::PARAM;
328 }
329 };
330
331 class ImportDecl : public Decl {
332 public:
ImportDecl(util::StringView importName,util::StringView localName)333 explicit ImportDecl(util::StringView importName, util::StringView localName)
334 : Decl(localName), importName_(importName)
335 {
336 }
337
ImportDecl(util::StringView importName,util::StringView localName,ir::AstNode * node)338 explicit ImportDecl(util::StringView importName, util::StringView localName, ir::AstNode *node)
339 : Decl(localName), importName_(importName)
340 {
341 BindNode(node);
342 }
343
ImportName()344 const util::StringView &ImportName() const
345 {
346 return importName_;
347 }
348
LocalName()349 const util::StringView &LocalName() const
350 {
351 return name_;
352 }
353
Type()354 DeclType Type() const override
355 {
356 return DeclType::IMPORT;
357 }
358
359 private:
360 util::StringView importName_;
361 };
362
363 class ExportDecl : public Decl {
364 public:
ExportDecl(util::StringView exportName,util::StringView localName)365 explicit ExportDecl(util::StringView exportName, util::StringView localName)
366 : Decl(localName), exportName_(exportName)
367 {
368 }
369
ExportDecl(util::StringView exportName,util::StringView localName,ir::AstNode * node)370 explicit ExportDecl(util::StringView exportName, util::StringView localName, ir::AstNode *node)
371 : Decl(localName), exportName_(exportName)
372 {
373 BindNode(node);
374 }
375
ExportName()376 const util::StringView &ExportName() const
377 {
378 return exportName_;
379 }
380
LocalName()381 const util::StringView &LocalName() const
382 {
383 return name_;
384 }
385
Type()386 DeclType Type() const override
387 {
388 return DeclType::EXPORT;
389 }
390
391 private:
392 util::StringView exportName_;
393 };
394 } // namespace ark::es2panda::varbinder
395
396 #endif
397