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