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