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 // CC-OFFNXT(G.PRE.09) code gen
36 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
37 #define DECLARE_CLASSES(decl_kind, className) class className; // CC-OFF(G.PRE.02) name part
DECLARATION_KINDS(DECLARE_CLASSES)38 DECLARATION_KINDS(DECLARE_CLASSES)
39 #undef DECLARE_CLASSES
40
41 class Decl {
42 public:
43 virtual ~Decl() = default;
44 NO_COPY_SEMANTIC(Decl);
45 NO_MOVE_SEMANTIC(Decl);
46
47 virtual DeclType Type() const = 0;
48
49 const util::StringView &Name() const
50 {
51 return name_;
52 }
53
54 ir::AstNode *Node()
55 {
56 return node_;
57 }
58
59 const ir::AstNode *Node() const
60 {
61 return node_;
62 }
63
64 /* CC-OFFNXT(G.PRE.06) solid logic */
65 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
66 #define DECLARE_CHECKS_CASTS(declKind, className) \
67 bool Is##className() const \
68 { \
69 /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \
70 return Type() == DeclType::declKind; /* CC-OFF(G.PRE.02) name part */ \
71 } \
72 /* CC-OFFNXT(G.PRE.02) name part*/ \
73 className *As##className() \
74 { \
75 ASSERT(Is##className()); \
76 /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \
77 return reinterpret_cast<className *>(this); /* CC-OFF(G.PRE.02) name part */ \
78 } \
79 const className *As##className() const \
80 { \
81 ASSERT(Is##className()); \
82 /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \
83 return reinterpret_cast<const className *>(this); \
84 }
85 DECLARATION_KINDS(DECLARE_CHECKS_CASTS)
86 #undef DECLARE_CHECKS_CASTS
87
88 void BindNode(ir::AstNode *node)
89 {
90 node_ = node;
91 }
92
93 bool IsLetOrConstDecl() const
94 {
95 return IsLetDecl() || IsConstDecl();
96 }
97
98 bool PossibleTDZ() const
99 {
100 return IsLetOrConstDecl() || IsParameterDecl();
101 }
102
103 protected:
104 explicit Decl(util::StringView name) : name_(name) {}
105 explicit Decl(util::StringView name, ir::AstNode *declNode) : name_(name), node_(declNode) {}
106
107 // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
108 util::StringView name_;
109 ir::AstNode *node_ {};
110 // NOLINTEND(misc-non-private-member-variables-in-classes)
111 };
112
113 template <typename T>
114 class MultiDecl : public Decl {
115 public:
MultiDecl(ArenaAllocator * allocator,util::StringView name)116 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name)
117 : Decl(name), declarations_(allocator->Adapter())
118 {
119 }
120
MultiDecl(ArenaAllocator * allocator,util::StringView name,ir::AstNode * declNode)121 explicit MultiDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode)
122 : Decl(name, declNode), declarations_(allocator->Adapter())
123 {
124 }
125
Decls()126 const ArenaVector<T *> &Decls() const
127 {
128 return declarations_;
129 }
130
Add(T * decl)131 void Add(T *decl)
132 {
133 declarations_.push_back(decl);
134 }
135
136 private:
137 ArenaVector<T *> declarations_;
138 };
139
140 class EnumLiteralDecl : public Decl {
141 public:
EnumLiteralDecl(util::StringView name,bool isConst)142 explicit EnumLiteralDecl(util::StringView name, bool isConst) : Decl(name), isConst_(isConst) {}
EnumLiteralDecl(util::StringView name,ir::AstNode * declNode,bool isConst)143 explicit EnumLiteralDecl(util::StringView name, ir::AstNode *declNode, bool isConst)
144 : Decl(name, declNode), isConst_(isConst)
145 {
146 }
147
Type()148 DeclType Type() const override
149 {
150 return DeclType::ENUM_LITERAL;
151 }
152
IsConst()153 bool IsConst() const
154 {
155 return isConst_;
156 }
157
BindScope(LocalScope * scope)158 void BindScope(LocalScope *scope)
159 {
160 scope_ = scope;
161 }
162
Scope()163 LocalScope *Scope()
164 {
165 return scope_;
166 }
167
168 private:
169 LocalScope *scope_ {};
170 bool isConst_ {};
171 };
172
173 class InterfaceDecl : public MultiDecl<ir::TSInterfaceDeclaration> {
174 public:
InterfaceDecl(ArenaAllocator * allocator,util::StringView name)175 explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {}
InterfaceDecl(ArenaAllocator * allocator,util::StringView name,ir::AstNode * declNode)176 explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode)
177 : MultiDecl(allocator, name, declNode)
178 {
179 }
180
Type()181 DeclType Type() const override
182 {
183 return DeclType::INTERFACE;
184 }
185 };
186
187 class ClassDecl : public Decl {
188 public:
ClassDecl(util::StringView name)189 explicit ClassDecl(util::StringView name) : Decl(name) {}
ClassDecl(util::StringView name,ir::AstNode * node)190 explicit ClassDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {}
191
Type()192 DeclType Type() const override
193 {
194 return DeclType::CLASS;
195 }
196 };
197
198 class FunctionDecl : public MultiDecl<ir::ScriptFunction> {
199 public:
FunctionDecl(ArenaAllocator * allocator,util::StringView name,ir::AstNode * node)200 explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *node)
201 : MultiDecl(allocator, name)
202 {
203 node_ = node;
204 }
205
Type()206 DeclType Type() const override
207 {
208 return DeclType::FUNC;
209 }
210 };
211
212 class TypeParameterDecl : public Decl {
213 public:
TypeParameterDecl(util::StringView name)214 explicit TypeParameterDecl(util::StringView name) : Decl(name) {}
215
Type()216 DeclType Type() const override
217 {
218 return DeclType::TYPE_PARAMETER;
219 }
220 };
221
222 class PropertyDecl : public Decl {
223 public:
PropertyDecl(util::StringView name)224 explicit PropertyDecl(util::StringView name) : Decl(name) {}
225
Type()226 DeclType Type() const override
227 {
228 return DeclType::PROPERTY;
229 }
230 };
231
232 class MethodDecl : public Decl {
233 public:
MethodDecl(util::StringView name)234 explicit MethodDecl(util::StringView name) : Decl(name) {}
235
Type()236 DeclType Type() const override
237 {
238 return DeclType::METHOD;
239 }
240 };
241
242 class EnumDecl : public Decl {
243 public:
EnumDecl(util::StringView name)244 explicit EnumDecl(util::StringView name) : Decl(name) {}
245
Type()246 DeclType Type() const override
247 {
248 return DeclType::ENUM;
249 }
250 };
251
252 class TypeAliasDecl : public Decl {
253 public:
TypeAliasDecl(util::StringView name)254 explicit TypeAliasDecl(util::StringView name) : Decl(name) {}
TypeAliasDecl(util::StringView name,ir::AstNode * node)255 explicit TypeAliasDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {}
256
Type()257 DeclType Type() const override
258 {
259 return DeclType::TYPE_ALIAS;
260 }
261 };
262
263 class NameSpaceDecl : public Decl {
264 public:
NameSpaceDecl(util::StringView name)265 explicit NameSpaceDecl(util::StringView name) : Decl(name) {}
266
Type()267 DeclType Type() const override
268 {
269 return DeclType::NAMESPACE;
270 }
271 };
272
273 class VarDecl : public Decl {
274 public:
VarDecl(util::StringView name)275 explicit VarDecl(util::StringView name) : Decl(name) {}
276
Type()277 DeclType Type() const override
278 {
279 return DeclType::VAR;
280 }
281 };
282
283 class LetDecl : public Decl {
284 public:
LetDecl(util::StringView name)285 explicit LetDecl(util::StringView name) : Decl(name) {}
LetDecl(util::StringView name,ir::AstNode * declNode)286 explicit LetDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {}
287
Type()288 DeclType Type() const override
289 {
290 return DeclType::LET;
291 }
292 };
293
294 class ConstDecl : public Decl {
295 public:
ConstDecl(util::StringView name)296 explicit ConstDecl(util::StringView name) : Decl(name) {}
ConstDecl(util::StringView name,ir::AstNode * declNode)297 explicit ConstDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {}
298
Type()299 DeclType Type() const override
300 {
301 return DeclType::CONST;
302 }
303 };
304
305 class LabelDecl : public Decl {
306 public:
LabelDecl(util::StringView name)307 explicit LabelDecl(util::StringView name) : Decl(name) {}
LabelDecl(util::StringView name,ir::AstNode * declNode)308 explicit LabelDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {}
309
Type()310 DeclType Type() const override
311 {
312 return DeclType::LABEL;
313 }
314 };
315
316 class ReadonlyDecl : public Decl {
317 public:
ReadonlyDecl(util::StringView name)318 explicit ReadonlyDecl(util::StringView name) : Decl(name) {}
ReadonlyDecl(util::StringView name,ir::AstNode * declNode)319 explicit ReadonlyDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {}
320
Type()321 DeclType Type() const override
322 {
323 return DeclType::READONLY;
324 }
325 };
326
327 class ParameterDecl : public Decl {
328 public:
ParameterDecl(util::StringView name)329 explicit ParameterDecl(util::StringView name) : Decl(name) {}
330
Type()331 DeclType Type() const override
332 {
333 return DeclType::PARAM;
334 }
335 };
336
337 class AnnotationDecl : public Decl {
338 public:
AnnotationDecl(util::StringView name)339 explicit AnnotationDecl(util::StringView name) : Decl(name) {}
AnnotationDecl(util::StringView name,ir::AstNode * node)340 explicit AnnotationDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {}
341
Type()342 DeclType Type() const override
343 {
344 return DeclType::ANNOTATIONDECL;
345 }
346 };
347
348 class AnnotationUsage : public Decl {
349 public:
AnnotationUsage(util::StringView name)350 explicit AnnotationUsage(util::StringView name) : Decl(name) {}
AnnotationUsage(util::StringView name,ir::AstNode * node)351 explicit AnnotationUsage(util::StringView name, ir::AstNode *node) : Decl(name, node) {}
352
Type()353 DeclType Type() const override
354 {
355 return DeclType::ANNOTATIONUSAGE;
356 }
357 };
358
359 class ImportDecl : public Decl {
360 public:
ImportDecl(util::StringView importName,util::StringView localName)361 explicit ImportDecl(util::StringView importName, util::StringView localName)
362 : Decl(localName), importName_(importName)
363 {
364 }
365
ImportDecl(util::StringView importName,util::StringView localName,ir::AstNode * node)366 explicit ImportDecl(util::StringView importName, util::StringView localName, ir::AstNode *node)
367 : Decl(localName), importName_(importName)
368 {
369 BindNode(node);
370 }
371
ImportName()372 const util::StringView &ImportName() const
373 {
374 return importName_;
375 }
376
LocalName()377 const util::StringView &LocalName() const
378 {
379 return name_;
380 }
381
Type()382 DeclType Type() const override
383 {
384 return DeclType::IMPORT;
385 }
386
387 private:
388 util::StringView importName_;
389 };
390
391 class ExportDecl : public Decl {
392 public:
ExportDecl(util::StringView exportName,util::StringView localName)393 explicit ExportDecl(util::StringView exportName, util::StringView localName)
394 : Decl(localName), exportName_(exportName)
395 {
396 }
397
ExportDecl(util::StringView exportName,util::StringView localName,ir::AstNode * node)398 explicit ExportDecl(util::StringView exportName, util::StringView localName, ir::AstNode *node)
399 : Decl(localName), exportName_(exportName)
400 {
401 BindNode(node);
402 }
403
ExportName()404 const util::StringView &ExportName() const
405 {
406 return exportName_;
407 }
408
LocalName()409 const util::StringView &LocalName() const
410 {
411 return name_;
412 }
413
Type()414 DeclType Type() const override
415 {
416 return DeclType::EXPORT;
417 }
418
419 private:
420 util::StringView exportName_;
421 };
422 } // namespace ark::es2panda::varbinder
423
424 #endif
425